A Demo Project for the UnrealEngineSDK
Loading...
Searching...
No Matches
VRExpansionFunctionLibrary.cpp
Go to the documentation of this file.
1// Fill out your copyright notice in the Description page of Project Settings.
3#include "DrawDebugHelpers.h"
4#include "Engine/Engine.h"
5#include "IXRTrackingSystem.h"
6#include "IHeadMountedDisplay.h"
9
10#if WITH_CHAOS
11#include "Chaos/ParticleHandle.h"
12#include "Chaos/KinematicGeometryParticles.h"
13#include "Chaos/ParticleHandle.h"
14#include "PhysicsProxy/SingleParticlePhysicsProxy.h"
15#include "PBDRigidsSolver.h"
16#endif
17
18#if WITH_EDITOR
19#include "Editor/UnrealEd/Classes/Editor/EditorEngine.h"
20#endif
21
22//General Log
23DEFINE_LOG_CATEGORY(VRExpansionFunctionLibraryLog);
24
26{
27 if (WorldContextObject)
28 {
29 return WorldContextObject->GetWorld()->GetGameViewport();
30 }
31
32 return nullptr;
33}
34
35void UVRExpansionFunctionLibrary::SetActorsIgnoreAllCollision(UObject* WorldContextObject, AActor* Actor1, AActor* Actor2, bool bIgnoreCollision)
36{
37 TInlineComponentArray<UPrimitiveComponent*> PrimitiveComponents1;
38 Actor1->GetComponents<UPrimitiveComponent>(PrimitiveComponents1);
39
40 TInlineComponentArray<UPrimitiveComponent*> PrimitiveComponents2;
41 Actor2->GetComponents<UPrimitiveComponent>(PrimitiveComponents2);
42
43 UCollisionIgnoreSubsystem* CollisionIgnoreSubsystem = WorldContextObject->GetWorld()->GetSubsystem<UCollisionIgnoreSubsystem>();
44
45 if (CollisionIgnoreSubsystem)
46 {
47 // Just a temp flag to only check state on the first component pair
48 bool bIgnorefirst = true;
49 for (int i = 0; i < PrimitiveComponents1.Num(); ++i)
50 {
51 for (int j = 0; j < PrimitiveComponents2.Num(); ++j)
52 {
53 // Don't ignore collision if one is already invalid
54 if (!PrimitiveComponents1[i] || !PrimitiveComponents2[j])
55 {
56 continue;
57 }
58
59 // Don't ignore collision if no collision on at least one of the objects
60 if (PrimitiveComponents1[i]->GetCollisionEnabled() == ECollisionEnabled::NoCollision || PrimitiveComponents2[j]->GetCollisionEnabled() == ECollisionEnabled::NoCollision)
61 {
62 if (!bIgnoreCollision)
63 {
64 if (CollisionIgnoreSubsystem->AreComponentsIgnoringCollisions(PrimitiveComponents1[i], PrimitiveComponents2[j]))
65 {
66 UE_LOG(VRExpansionFunctionLibraryLog, Error, TEXT("Set Actors Ignore Collision called with at least one object set to no collision that are ignoring collision already!! %s, %s"), *PrimitiveComponents1[i]->GetName(), *PrimitiveComponents2[j]->GetName());
67 }
68 }
69 continue;
70 }
71
72 CollisionIgnoreSubsystem->SetComponentCollisionIgnoreState(true, true, PrimitiveComponents1[i], NAME_None, PrimitiveComponents2[j], NAME_None, bIgnoreCollision, bIgnorefirst);
73 bIgnorefirst = false;
74 }
75 }
76 }
77}
78
79void UVRExpansionFunctionLibrary::SetObjectsIgnoreCollision(UObject* WorldContextObject, UPrimitiveComponent* Prim1, FName OptionalBoneName1, bool bAddChildBones1, UPrimitiveComponent* Prim2, FName OptionalBoneName2, bool bAddChildBones2, bool bIgnoreCollision)
80{
81 UCollisionIgnoreSubsystem* CollisionIgnoreSubsystem = WorldContextObject->GetWorld()->GetSubsystem<UCollisionIgnoreSubsystem>();
82
83 if (CollisionIgnoreSubsystem)
84 {
85 CollisionIgnoreSubsystem->SetComponentCollisionIgnoreState(bAddChildBones1, bAddChildBones2, Prim1, OptionalBoneName1, Prim2, OptionalBoneName2, bIgnoreCollision, true);
86 }
87}
88
89
90bool UVRExpansionFunctionLibrary::IsComponentIgnoringCollision(UObject* WorldContextObject, UPrimitiveComponent* Prim1)
91{
92 UCollisionIgnoreSubsystem* CollisionIgnoreSubsystem = WorldContextObject->GetWorld()->GetSubsystem<UCollisionIgnoreSubsystem>();
93
94 if (CollisionIgnoreSubsystem)
95 {
96 return CollisionIgnoreSubsystem->IsComponentIgnoringCollision(Prim1);
97 }
98
99 return false;
100}
101
102bool UVRExpansionFunctionLibrary::AreComponentsIgnoringCollisions(UObject* WorldContextObject, UPrimitiveComponent* Prim1, UPrimitiveComponent* Prim2)
103{
104 UCollisionIgnoreSubsystem* CollisionIgnoreSubsystem = WorldContextObject->GetWorld()->GetSubsystem<UCollisionIgnoreSubsystem>();
105
106 if (CollisionIgnoreSubsystem && CollisionIgnoreSubsystem->CollisionTrackedPairs.Num() > 0)
107 {
108 return CollisionIgnoreSubsystem->AreComponentsIgnoringCollisions(Prim1, Prim2);
109 }
110
111 return false;
112}
113
114void UVRExpansionFunctionLibrary::RemoveObjectCollisionIgnore(UObject* WorldContextObject, UPrimitiveComponent* Prim1)
115{
116 UCollisionIgnoreSubsystem* CollisionIgnoreSubsystem = WorldContextObject->GetWorld()->GetSubsystem<UCollisionIgnoreSubsystem>();
117
118 if (CollisionIgnoreSubsystem)
119 {
120 CollisionIgnoreSubsystem->RemoveComponentCollisionIgnoreState(Prim1);
121 }
122}
123
125{
126 TInlineComponentArray<UPrimitiveComponent*> PrimitiveComponents1;
127 Actor1->GetComponents<UPrimitiveComponent>(PrimitiveComponents1);
128
129 UCollisionIgnoreSubsystem* CollisionIgnoreSubsystem = WorldContextObject->GetWorld()->GetSubsystem<UCollisionIgnoreSubsystem>();
130
131 if (CollisionIgnoreSubsystem)
132 {
133 for (int i = 0; i < PrimitiveComponents1.Num(); ++i)
134 {
135 CollisionIgnoreSubsystem->RemoveComponentCollisionIgnoreState(PrimitiveComponents1[i]);
136 }
137 }
138}
139
140void UVRExpansionFunctionLibrary::LowPassFilter_RollingAverage(FVector lastAverage, FVector newSample, FVector& newAverage, int32 numSamples)
141{
142 newAverage = lastAverage;
143 newAverage -= newAverage / numSamples;
144 newAverage += newSample / numSamples;
145}
146
147void UVRExpansionFunctionLibrary::LowPassFilter_Exponential(FVector lastAverage, FVector newSample, FVector& newAverage, float sampleFactor)
148{
149 newAverage = (newSample * sampleFactor) + ((1 - sampleFactor) * lastAverage);
150}
151
153{
154 if (!ActorToCheck)
155 return false;
156
157 if (USceneComponent* rootComp = ActorToCheck->GetRootComponent())
158 {
159 return rootComp->Mobility == EComponentMobility::Movable;
160 }
161
162 return false;
163}
164
165void UVRExpansionFunctionLibrary::GetGripSlotInRangeByTypeName(FName SlotType, AActor* Actor, FVector WorldLocation, float MaxRange, bool& bHadSlotInRange, FTransform& SlotWorldTransform, FName& SlotName, UGripMotionControllerComponent* QueryController)
166{
167 bHadSlotInRange = false;
168 SlotWorldTransform = FTransform::Identity;
169 SlotName = NAME_None;
170 UHandSocketComponent* TargetHandSocket = nullptr;
171
172 if (!Actor)
173 return;
174
175 if (USceneComponent* rootComp = Actor->GetRootComponent())
176 {
177 GetGripSlotInRangeByTypeName_Component(SlotType, rootComp, WorldLocation, MaxRange, bHadSlotInRange, SlotWorldTransform, SlotName, QueryController);
178 }
179}
180
181void UVRExpansionFunctionLibrary::GetGripSlotInRangeByTypeName_Component(FName SlotType, USceneComponent* Component, FVector WorldLocation, float MaxRange, bool& bHadSlotInRange, FTransform& SlotWorldTransform, FName& SlotName, UGripMotionControllerComponent* QueryController)
182{
183 bHadSlotInRange = false;
184 SlotWorldTransform = FTransform::Identity;
185 SlotName = NAME_None;
186 UHandSocketComponent* TargetHandSocket = nullptr;
187
188 if (!Component)
189 return;
190
191 FVector RelativeWorldLocation = Component->GetComponentTransform().InverseTransformPosition(WorldLocation);
192 MaxRange = FMath::Square(MaxRange);
193
194 float ClosestSlotDistance = -0.1f;
195
196 TArray<FName> SocketNames = Component->GetAllSocketNames();
197
198 FString GripIdentifier = SlotType.ToString();
199
200 int foundIndex = 0;
201
202 for (int i = 0; i < SocketNames.Num(); ++i)
203 {
204 if (SocketNames[i].ToString().Contains(GripIdentifier, ESearchCase::IgnoreCase, ESearchDir::FromStart))
205 {
206 float vecLen = FVector::DistSquared(RelativeWorldLocation, Component->GetSocketTransform(SocketNames[i], ERelativeTransformSpace::RTS_Component).GetLocation());
207
208 if (MaxRange >= vecLen && (ClosestSlotDistance < 0.0f || vecLen < ClosestSlotDistance))
209 {
210 ClosestSlotDistance = vecLen;
211 bHadSlotInRange = true;
212 foundIndex = i;
213 }
214 }
215 }
216
217 TArray<USceneComponent*> AttachChildren = Component->GetAttachChildren();
218
219 TArray<UHandSocketComponent*> RotationallyMatchingHandSockets;
220 for (USceneComponent* AttachChild : AttachChildren)
221 {
222 if (AttachChild && AttachChild->IsA<UHandSocketComponent>())
223 {
224 if (UHandSocketComponent* SocketComp = Cast<UHandSocketComponent>(AttachChild))
225 {
226 if (SocketComp->bDisabled)
227 continue;
228
229 FName BoneName = SocketComp->GetAttachSocketName();
230 FString SlotPrefix = BoneName != NAME_None ? BoneName.ToString() + SocketComp->SlotPrefix.ToString() : SocketComp->SlotPrefix.ToString();
231
232 if (SlotPrefix.Contains(GripIdentifier, ESearchCase::IgnoreCase, ESearchDir::FromStart))
233 {
234 FVector SocketRelativeLocation = Component->GetComponentTransform().InverseTransformPosition(SocketComp->GetHandSocketTransform(QueryController, true).GetLocation());
235 float vecLen = FVector::DistSquared(RelativeWorldLocation, SocketRelativeLocation);
236 //float vecLen = FVector::DistSquared(RelativeWorldLocation, SocketComp->GetRelativeLocation());
237 if (SocketComp->bAlwaysInRange)
238 {
239 if (SocketComp->bMatchRotation)
240 {
241 RotationallyMatchingHandSockets.Add(SocketComp);
242 }
243 else
244 {
245 TargetHandSocket = SocketComp;
246 ClosestSlotDistance = vecLen;
247 bHadSlotInRange = true;
248 }
249 }
250 else
251 {
252 float RangeVal = (SocketComp->OverrideDistance > 0.0f ? FMath::Square(SocketComp->OverrideDistance) : MaxRange);
253 if (RangeVal >= vecLen && (ClosestSlotDistance < 0.0f || vecLen < ClosestSlotDistance))
254 {
255 if (SocketComp->bMatchRotation)
256 {
257 RotationallyMatchingHandSockets.Add(SocketComp);
258 }
259 else
260 {
261 TargetHandSocket = SocketComp;
262 ClosestSlotDistance = vecLen;
263 bHadSlotInRange = true;
264 }
265 }
266 }
267 }
268 }
269 }
270 }
271
272 // Try and sort through any hand sockets flagged as rotationally matched
273 if (RotationallyMatchingHandSockets.Num() > 0)
274 {
275 FQuat ControllerRot = QueryController->GetPivotTransform().GetRotation();
276 //FQuat ClosestQuat = RotationallyMatchingHandSockets[0]->GetComponentTransform().GetRotation();
277 FQuat ClosestQuat = RotationallyMatchingHandSockets[0]->GetHandSocketTransform(QueryController, true).GetRotation();
278
279 TargetHandSocket = RotationallyMatchingHandSockets[0];
280 bHadSlotInRange = true;
281 ClosestSlotDistance = ControllerRot.AngularDistance(ClosestQuat);
282 for (int i = 1; i < RotationallyMatchingHandSockets.Num(); i++)
283 {
284 //float CheckDistance = ControllerRot.AngularDistance(RotationallyMatchingHandSockets[i]->GetComponentTransform().GetRotation());
285 float CheckDistance = ControllerRot.AngularDistance(RotationallyMatchingHandSockets[i]->GetHandSocketTransform(QueryController, true).GetRotation());
286 if (CheckDistance < ClosestSlotDistance)
287 {
288 TargetHandSocket = RotationallyMatchingHandSockets[i];
289 ClosestSlotDistance = CheckDistance;
290 }
291 }
292 }
293
294 if (bHadSlotInRange)
295 {
296 if (TargetHandSocket)
297 {
298 SlotWorldTransform = TargetHandSocket->GetHandSocketTransform(QueryController);
299 SlotName = TargetHandSocket->GetFName();
300 SlotWorldTransform.SetScale3D(FVector(1.0f));
301 }
302 else
303 {
304 SlotWorldTransform = Component->GetSocketTransform(SocketNames[foundIndex]);
305 SlotName = SocketNames[foundIndex];
306 SlotWorldTransform.SetScale3D(FVector(1.0f));
307 }
308 }
309}
310
311FRotator UVRExpansionFunctionLibrary::GetHMDPureYaw(FRotator HMDRotation)
312{
313 return GetHMDPureYaw_I(HMDRotation);
314}
315
317{
318
319 if (GEngine->XRSystem.IsValid() && GEngine->XRSystem->GetHMDDevice())
320 {
321 return (EBPHMDWornState)GEngine->XRSystem->GetHMDDevice()->GetHMDWornState();
322 }
323
325}
326
328{
329 return GEngine->XRSystem.IsValid() && GEngine->XRSystem->GetHMDDevice() && GEngine->XRSystem->GetHMDDevice()->IsHMDConnected();
330}
331
333{
334 if (GEngine && GEngine->XRSystem.IsValid())
335 {
336 /*
337 if (GEngine && GEngine->XRSystem.IsValid())
338 {
339 Ar.Logf(*GEngine->XRSystem->GetVersionString());
340 }
341 */
342
343 // #TODO 4.19: Figure out a way to replace this...its broken now
344 /*IHeadMountedDisplay* HMDDevice = GEngine->XRSystem->GetHMDDevice();
345 if (HMDDevice)
346 {
347 EHMDDeviceType::Type HMDDeviceType = HMDDevice->GetHMDDeviceType();
348
349 switch (HMDDeviceType)
350 {
351 case EHMDDeviceType::DT_ES2GenericStereoMesh: return EBPHMDDeviceType::DT_ES2GenericStereoMesh; break;
352 case EHMDDeviceType::DT_GearVR: return EBPHMDDeviceType::DT_GearVR; break;
353 case EHMDDeviceType::DT_Morpheus: return EBPHMDDeviceType::DT_Morpheus; break;
354 case EHMDDeviceType::DT_OculusRift: return EBPHMDDeviceType::DT_OculusRift; break;
355 case EHMDDeviceType::DT_SteamVR: return EBPHMDDeviceType::DT_SteamVR; break;
356 case EHMDDeviceType::DT_GoogleVR: return EBPHMDDeviceType::DT_GoogleVR; break;
357 }
358
359 }*/
360
361 // There are no device type entries for these now....
362 // Does the device type go away soon leaving only FNames?
363 // #TODO: 4.19?
364 // GearVR doesn't even return anything gut OculusHMD in FName currently.
365
366 static const FName SteamVRSystemName(TEXT("SteamVR"));
367 static const FName OculusSystemName(TEXT("OculusHMD"));
368 static const FName PSVRSystemName(TEXT("PSVR"));
369 static const FName OSVRSystemName(TEXT("OSVR"));
370 static const FName GoogleARCoreSystemName(TEXT("FGoogleARCoreHMD"));
371 static const FName AppleARKitSystemName(TEXT("AppleARKit"));
372 static const FName GoogleVRHMDSystemName(TEXT("FGoogleVRHMD"));
373
374 FName DeviceName(NAME_None);
375 DeviceName = GEngine->XRSystem->GetSystemName();
376
377
378 if (DeviceName == FName(TEXT("SimpleHMD")))
380 else if (DeviceName == SteamVRSystemName)
382 else if (DeviceName == OculusSystemName)
384 else if (DeviceName == PSVRSystemName)
386 else if (DeviceName == OSVRSystemName)
388 else if (DeviceName == GoogleARCoreSystemName)
390 else if (DeviceName == AppleARKitSystemName)
392 else if (DeviceName == GoogleVRHMDSystemName)
394 }
395
396 // Default to unknown
398}
399
400
402{
403#if WITH_EDITOR
404 if (GIsEditor)
405 {
406 if (UEditorEngine* EdEngine = Cast<UEditorEngine>(GEngine))
407 {
408 TOptional<FPlayInEditorSessionInfo> PlayInfo = EdEngine->GetPlayInEditorSessionInfo();
409 if (PlayInfo.IsSet())
410 {
411 return PlayInfo->OriginalRequestParams.SessionPreviewTypeOverride == EPlaySessionPreviewType::VRPreview;
412 }
413 else
414 {
415 return false;
416 }
417 }
418 }
419#endif
420
421 // Is not an editor build, default to true here
422 return true;
423}
424
426{
427#if WITH_EDITOR
428 if (GIsEditor)
429 {
430 if (UEditorEngine* EdEngine = Cast<UEditorEngine>(GEngine))
431 {
432 TOptional<FPlayInEditorSessionInfo> PlayInfo = EdEngine->GetPlayInEditorSessionInfo();
433 if (PlayInfo.IsSet())
434 {
435 return PlayInfo->OriginalRequestParams.SessionPreviewTypeOverride == EPlaySessionPreviewType::VRPreview;
436 }
437 else
438 {
439 return false;
440 }
441 }
442 }
443#endif
444
445 // Is not an editor build, default to false here
446 return false;
447}
448
449void UVRExpansionFunctionLibrary::NonAuthorityMinimumAreaRectangle(class UObject* WorldContextObject, const TArray<FVector>& InVerts, const FVector& SampleSurfaceNormal, FVector& OutRectCenter, FRotator& OutRectRotation, float& OutSideLengthX, float& OutSideLengthY, bool bDebugDraw)
450{
451 float MinArea = -1.f;
452 float CurrentArea = -1.f;
453 FVector SupportVectorA, SupportVectorB;
454 FVector RectSideA, RectSideB;
455 float MinDotResultA, MinDotResultB, MaxDotResultA, MaxDotResultB;
456 FVector TestEdge;
457 float TestEdgeDot = 0.f;
458 FVector PolyNormal(0.f, 0.f, 1.f);
459 TArray<int32> PolyVertIndices;
460
461 // Bail if we receive an empty InVerts array
462 if (InVerts.Num() == 0)
463 {
464 return;
465 }
466
467 // Compute the approximate normal of the poly, using the direction of SampleSurfaceNormal for guidance
468 PolyNormal = (InVerts[InVerts.Num() / 3] - InVerts[0]) ^ (InVerts[InVerts.Num() * 2 / 3] - InVerts[InVerts.Num() / 3]);
469 if ((PolyNormal | SampleSurfaceNormal) < 0.f)
470 {
471 PolyNormal = -PolyNormal;
472 }
473
474 // Transform the sample points to 2D
475 FMatrix SurfaceNormalMatrix = FRotationMatrix::MakeFromZX(PolyNormal, FVector(1.f, 0.f, 0.f));
476 TArray<FVector> TransformedVerts;
477 OutRectCenter = FVector(0.f);
478 for (int32 Idx = 0; Idx < InVerts.Num(); ++Idx)
479 {
480 OutRectCenter += InVerts[Idx];
481 TransformedVerts.Add(SurfaceNormalMatrix.InverseTransformVector(InVerts[Idx]));
482 }
483 OutRectCenter /= InVerts.Num();
484
485 // Compute the convex hull of the sample points
486 ConvexHull2D::ComputeConvexHull(TransformedVerts, PolyVertIndices);
487
488 // Minimum area rectangle as computed by http://www.geometrictools.com/Documentation/MinimumAreaRectangle.pdf
489 for (int32 Idx = 1; Idx < PolyVertIndices.Num() - 1; ++Idx)
490 {
491 SupportVectorA = (TransformedVerts[PolyVertIndices[Idx]] - TransformedVerts[PolyVertIndices[Idx - 1]]).GetSafeNormal();
492 SupportVectorA.Z = 0.f;
493 SupportVectorB.X = -SupportVectorA.Y;
494 SupportVectorB.Y = SupportVectorA.X;
495 SupportVectorB.Z = 0.f;
496 MinDotResultA = MinDotResultB = MaxDotResultA = MaxDotResultB = 0.f;
497
498 for (int TestVertIdx = 1; TestVertIdx < PolyVertIndices.Num(); ++TestVertIdx)
499 {
500 TestEdge = TransformedVerts[PolyVertIndices[TestVertIdx]] - TransformedVerts[PolyVertIndices[0]];
501 TestEdgeDot = SupportVectorA | TestEdge;
502 if (TestEdgeDot < MinDotResultA)
503 {
504 MinDotResultA = TestEdgeDot;
505 }
506 else if (TestEdgeDot > MaxDotResultA)
507 {
508 MaxDotResultA = TestEdgeDot;
509 }
510
511 TestEdgeDot = SupportVectorB | TestEdge;
512 if (TestEdgeDot < MinDotResultB)
513 {
514 MinDotResultB = TestEdgeDot;
515 }
516 else if (TestEdgeDot > MaxDotResultB)
517 {
518 MaxDotResultB = TestEdgeDot;
519 }
520 }
521
522 CurrentArea = (MaxDotResultA - MinDotResultA) * (MaxDotResultB - MinDotResultB);
523 if (MinArea < 0.f || CurrentArea < MinArea)
524 {
525 MinArea = CurrentArea;
526 RectSideA = SupportVectorA * (MaxDotResultA - MinDotResultA);
527 RectSideB = SupportVectorB * (MaxDotResultB - MinDotResultB);
528 }
529 }
530
531 RectSideA = SurfaceNormalMatrix.TransformVector(RectSideA);
532 RectSideB = SurfaceNormalMatrix.TransformVector(RectSideB);
533 OutRectRotation = FRotationMatrix::MakeFromZX(PolyNormal, RectSideA).Rotator();
534 OutSideLengthX = RectSideA.Size();
535 OutSideLengthY = RectSideB.Size();
536
537#if ENABLE_DRAW_DEBUG
538 if (bDebugDraw)
539 {
540 UWorld* World = (WorldContextObject) ? GEngine->GetWorldFromContextObject(WorldContextObject, EGetWorldErrorMode::LogAndReturnNull) : nullptr;
541 if (World != nullptr)
542 {
543 DrawDebugSphere(World, OutRectCenter, 10.f, 12, FColor::Yellow, true);
544 DrawDebugCoordinateSystem(World, OutRectCenter, SurfaceNormalMatrix.Rotator(), 100.f, true);
545 DrawDebugLine(World, OutRectCenter - RectSideA * 0.5f + FVector(0, 0, 10.f), OutRectCenter + RectSideA * 0.5f + FVector(0, 0, 10.f), FColor::Green, true, -1, 0, 5.f);
546 DrawDebugLine(World, OutRectCenter - RectSideB * 0.5f + FVector(0, 0, 10.f), OutRectCenter + RectSideB * 0.5f + FVector(0, 0, 10.f), FColor::Blue, true, -1, 0, 5.f);
547 }
548 else
549 {
550 FFrame::KismetExecutionMessage(TEXT("WorldContext required for MinimumAreaRectangle to draw a debug visualization."), ELogVerbosity::Warning);
551 }
552 }
553#endif
554}
555
560
562{
563 return Grip.IsValid() && !Grip.bIsPaused;
564}
565
566
567FTransform_NetQuantize UVRExpansionFunctionLibrary::MakeTransform_NetQuantize(FVector Translation, FRotator Rotation, FVector Scale)
568{
569 return FTransform_NetQuantize(Rotation, Translation, Scale);
570}
571
572void UVRExpansionFunctionLibrary::BreakTransform_NetQuantize(const FTransform_NetQuantize& InTransform, FVector& Translation, FRotator& Rotation, FVector& Scale)
573{
574 Translation = InTransform.GetLocation();
575 Rotation = InTransform.Rotator();
576 Scale = InTransform.GetScale3D();
577}
578
583
588
590{
591 return GripPair.GripID;
592}
593
594FVector_NetQuantize UVRExpansionFunctionLibrary::Conv_FVectorToFVectorNetQuantize(const FVector& InVector)
595{
596 return FVector_NetQuantize(InVector);
597}
598
599FVector_NetQuantize UVRExpansionFunctionLibrary::MakeVector_NetQuantize(FVector InVector)
600{
601 return FVector_NetQuantize(InVector);
602}
603
604FVector_NetQuantize10 UVRExpansionFunctionLibrary::Conv_FVectorToFVectorNetQuantize10(const FVector& InVector)
605{
606 return FVector_NetQuantize10(InVector);
607}
608
609FVector_NetQuantize10 UVRExpansionFunctionLibrary::MakeVector_NetQuantize10(FVector InVector)
610{
611 return FVector_NetQuantize10(InVector);
612}
613
614FVector_NetQuantize100 UVRExpansionFunctionLibrary::Conv_FVectorToFVectorNetQuantize100(const FVector& InVector)
615{
616 return FVector_NetQuantize100(InVector);
617}
618
619FVector_NetQuantize100 UVRExpansionFunctionLibrary::MakeVector_NetQuantize100(FVector InVector)
620{
621 return FVector_NetQuantize100(InVector);
622}
623
624USceneComponent* UVRExpansionFunctionLibrary::AddSceneComponentByClass(UObject* Outer, TSubclassOf<USceneComponent> Class, const FTransform& ComponentRelativeTransform)
625{
626 if (Class != nullptr && Outer != nullptr)
627 {
628 USceneComponent* Component = NewObject<USceneComponent>(Outer, *Class);
629 if (Component != nullptr)
630 {
631 if (USceneComponent* ParentComp = Cast<USceneComponent>(Outer))
632 Component->SetupAttachment(ParentComp);
633
634 Component->RegisterComponent();
635 Component->SetRelativeTransform(ComponentRelativeTransform);
636
637 return Component;
638 }
639 else
640 {
641 return nullptr;
642 }
643 }
644
645 return nullptr;
646}
static FName SteamVRSystemName(TEXT("SteamVR"))
EBPHMDDeviceType
UENUM(Blueprintable)
DEFINE_LOG_CATEGORY(VRExpansionFunctionLibraryLog)
EBPHMDWornState
UENUM(BlueprintType)
bool IsComponentIgnoringCollision(UPrimitiveComponent *Prim1)
bool AreComponentsIgnoringCollisions(UPrimitiveComponent *Prim1, UPrimitiveComponent *Prim2)
void SetComponentCollisionIgnoreState(bool bIterateChildren1, bool bIterateChildren2, UPrimitiveComponent *Prim1, FName OptionalBoneName1, UPrimitiveComponent *Prim2, FName OptionalBoneName2, bool bIgnoreCollision, bool bCheckFilters=false)
TMap< FCollisionPrimPair, FCollisionIgnorePairArray > CollisionTrackedPairs
UPROPERTY()
void RemoveComponentCollisionIgnoreState(UPrimitiveComponent *Prim1)
UCLASS(Blueprintable, meta = (BlueprintSpawnableComponent), ClassGroup = MotionController)
UCLASS(Blueprintable, ClassGroup = (VRExpansionPlugin), hideCategories = ("Component Tick",...
virtual FTransform GetHandSocketTransform(UGripMotionControllerComponent *QueryController, bool bIgnoreOnlySnapMesh=false)
static FVector_NetQuantize10 Conv_FVectorToFVectorNetQuantize10(const FVector &InVector)
UFUNCTION(BlueprintPure, meta = (DisplayName = "ToVector_NetQuantize10 (Vector)", CompactNodeTitle = ...
static bool IsInVREditorPreviewOrGame()
UFUNCTION(BlueprintPure, Category = "VRExpansionFunctions", meta = (bIgnoreSelf = "true",...
static USceneComponent * AddSceneComponentByClass(UObject *Outer, TSubclassOf< USceneComponent > Class, const FTransform &ComponentRelativeTransform)
UFUNCTION(BlueprintCallable, meta = (DisplayName = "Add Scene Component By Class"),...
static FVector_NetQuantize10 MakeVector_NetQuantize10(FVector InVector)
UFUNCTION(BlueprintPure, meta = (Scale = "1,1,1", Keywords = "construct build", NativeMakeFunc),...
static void SetObjectsIgnoreCollision(UObject *WorldContextObject, UPrimitiveComponent *Prim1=nullptr, FName OptionalBoneName1=NAME_None, bool bAddChildBones1=false, UPrimitiveComponent *Prim2=nullptr, FName OptionalBoneName2=NAME_None, bool bAddChildBones2=false, bool bIgnoreCollision=true)
UFUNCTION(BlueprintCallable, Category = "VRExpansionFunctions|Collision", meta = (bIgnoreSelf = "true...
static bool IsInVREditorPreview()
UFUNCTION(BlueprintPure, Category = "VRExpansionFunctions", meta = (bIgnoreSelf = "true",...
static uint8 Conv_GripPairToGripID(const FBPGripPair &GripPair)
UFUNCTION(BlueprintPure, meta = (DisplayName = "ToGripID (FBPGripPair)", CompactNodeTitle = "->",...
static void RemoveObjectCollisionIgnore(UObject *WorldContextObject, UPrimitiveComponent *Prim1)
UFUNCTION(BlueprintCallable, Category = "VRExpansionFunctions|Collision", meta = (bIgnoreSelf = "true...
static void GetGripSlotInRangeByTypeName_Component(FName SlotType, USceneComponent *Component, FVector WorldLocation, float MaxRange, bool &bHadSlotInRange, FTransform &SlotWorldTransform, FName &SlotName, UGripMotionControllerComponent *QueryController=nullptr)
UFUNCTION(BlueprintPure, Category = "VRGrip", meta = (bIgnoreSelf = "true", DisplayName = "GetGripSlo...
static FVector_NetQuantize Conv_FVectorToFVectorNetQuantize(const FVector &InVector)
UFUNCTION(BlueprintPure, meta = (DisplayName = "ToVector_NetQuantize (Vector)", CompactNodeTitle = "-...
static EBPHMDWornState GetIsHMDWorn()
UFUNCTION(BlueprintPure, Category = "VRExpansionFunctions", meta = (bIgnoreSelf = "true",...
static FVector_NetQuantize100 MakeVector_NetQuantize100(FVector InVector)
UFUNCTION(BlueprintPure, meta = (Scale = "1,1,1", Keywords = "construct build", NativeMakeFunc),...
static bool EqualEqual_FBPActorGripInformation(const FBPActorGripInformation &A, const FBPActorGripInformation &B)
UFUNCTION(BlueprintPure, meta = (DisplayName = "Equal VR Grip", CompactNodeTitle = "==",...
static FTransform_NetQuantize MakeTransform_NetQuantize(FVector Location, FRotator Rotation, FVector Scale)
UFUNCTION(BlueprintPure, meta = (Scale = "1,1,1", Keywords = "construct build", NativeMakeFunc),...
static void RemoveActorCollisionIgnore(UObject *WorldContextObject, AActor *Actor1)
UFUNCTION(BlueprintCallable, Category = "VRExpansionFunctions|Collision", meta = (bIgnoreSelf = "true...
static void LowPassFilter_RollingAverage(FVector lastAverage, FVector newSample, FVector &newAverage, int32 numSamples=10)
UFUNCTION(BlueprintPure, Category = "VRExpansionFunctions", meta = (bIgnoreSelf = "true",...
static void LowPassFilter_Exponential(FVector lastAverage, FVector newSample, FVector &newAverage, float sampleFactor=0.25f)
UFUNCTION(BlueprintPure, Category = "VRExpansionFunctions", meta = (bIgnoreSelf = "true",...
static FRotator GetHMDPureYaw(FRotator HMDRotation)
UFUNCTION(BlueprintPure, Category = "VRExpansionFunctions", meta = (bIgnoreSelf = "true",...
static EBPHMDDeviceType GetHMDType()
UFUNCTION(BlueprintPure, Category = "VRExpansionFunctions", meta = (bIgnoreSelf = "true",...
static FVector_NetQuantize100 Conv_FVectorToFVectorNetQuantize100(const FVector &InVector)
UFUNCTION(BlueprintPure, meta = (DisplayName = "ToVector_NetQuantize100 (Vector)",...
static UGameViewportClient * GetGameViewportClient(UObject *WorldContextObject)
UFUNCTION(BlueprintPure, Category = "VRExpansionFunctions", meta = (WorldContext = "WorldContextObjec...
static FVector_NetQuantize MakeVector_NetQuantize(FVector InVector)
UFUNCTION(BlueprintPure, meta = (Scale = "1,1,1", Keywords = "construct build", NativeMakeFunc),...
static void NonAuthorityMinimumAreaRectangle(UObject *WorldContextObject, const TArray< FVector > &InVerts, const FVector &SampleSurfaceNormal, FVector &OutRectCenter, FRotator &OutRectRotation, float &OutSideLengthX, float &OutSideLengthY, bool bDebugDraw=false)
UFUNCTION(BlueprintCallable, Category = "VRExpansionFunctions", meta = (WorldContext = "WorldContextO...
static bool IsActiveGrip(const FBPActorGripInformation &Grip)
UFUNCTION(BlueprintPure, Category = "VRExpansionFunctions")
static void BreakTransform_NetQuantize(const FTransform_NetQuantize &InTransform, FVector &Location, FRotator &Rotation, FVector &Scale)
UFUNCTION(BlueprintPure, Category = "VRExpansionLibrary|TransformNetQuantize", meta = (NativeBreakFun...
static bool GetIsActorMovable(AActor *ActorToCheck)
UFUNCTION(BlueprintPure, Category = "VRExpansionFunctions", meta = (bIgnoreSelf = "true",...
static bool AreComponentsIgnoringCollisions(UObject *WorldContextObject, UPrimitiveComponent *Prim1, UPrimitiveComponent *Prim2)
UFUNCTION(BlueprintCallable, Category = "VRExpansionFunctions|Collision", meta = (bIgnoreSelf = "true...
static void GetGripSlotInRangeByTypeName(FName SlotType, AActor *Actor, FVector WorldLocation, float MaxRange, bool &bHadSlotInRange, FTransform &SlotWorldTransform, FName &SlotName, UGripMotionControllerComponent *QueryController=nullptr)
UFUNCTION(BlueprintPure, Category = "VRGrip", meta = (bIgnoreSelf = "true", DisplayName = "GetGripSlo...
static UGripMotionControllerComponent * Conv_GripPairToMotionController(const FBPGripPair &GripPair)
UFUNCTION(BlueprintPure, meta = (DisplayName = "ToController (FBPGripPair)", CompactNodeTitle = "->",...
static bool GetIsHMDConnected()
UFUNCTION(BlueprintPure, Category = "VRExpansionFunctions", meta = (bIgnoreSelf = "true",...
static FTransform_NetQuantize Conv_TransformToTransformNetQuantize(const FTransform &InTransform)
UFUNCTION(BlueprintPure, meta = (DisplayName = "ToTransform_NetQuantize (Transform)",...
static bool IsComponentIgnoringCollision(UObject *WorldContextObject, UPrimitiveComponent *Prim1)
UFUNCTION(BlueprintCallable, Category = "VRExpansionFunctions|Collision", meta = (bIgnoreSelf = "true...
static FRotator GetHMDPureYaw_I(FRotator HMDRotation)
static void SetActorsIgnoreAllCollision(UObject *WorldContextObject, AActor *Actor1=nullptr, AActor *Actor2=nullptr, bool bIgnoreCollision=true)
UFUNCTION(BlueprintCallable, Category = "VRExpansionFunctions|Collision", meta = (bIgnoreSelf = "true...
USTRUCT(BlueprintType, Category = "VRExpansionLibrary")
bool bIsPaused
UPROPERTY(BlueprintReadWrite, NotReplicated, Category = "Settings")
USTRUCT(BlueprintType, Category = "VRExpansionLibrary")
UGripMotionControllerComponent * HoldingController
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "GripPair")
uint8 GripID
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "GripPair")
USTRUCT(BlueprintType, Category = "VRExpansionLibrary|TransformNetQuantize", meta = (HasNativeMake = ...