A Demo Project for the UnrealEngineSDK
Loading...
Searching...
No Matches
OptionalRepSkeletalMeshActor.cpp
Go to the documentation of this file.
1// Copyright 1998-2016 Epic Games, Inc. All Rights Reserved.
2
4#include "TimerManager.h"
5#include "Net/UnrealNetwork.h"
6#include "PhysicsReplication.h"
7#if WITH_PUSH_MODEL
8#include "Net/Core/PushModel/PushModel.h"
9#endif
10
11UNoRepSphereComponent::UNoRepSphereComponent(const FObjectInitializer& ObjectInitializer)
12 : Super(ObjectInitializer)
13{
14 this->SetIsReplicatedByDefault(true);
15 this->PrimaryComponentTick.bCanEverTick = false;
16 SphereRadius = 4.0f;
17 SetCollisionEnabled(ECollisionEnabled::PhysicsOnly);
18 SetCollisionResponseToAllChannels(ECR_Ignore);
19 //SetAllMassScale(0.0f); Engine hates calling this in constructor
20
21
22 BodyInstance.bOverrideMass = true;
23 BodyInstance.SetMassOverride(0.f);
24}
25
26void UNoRepSphereComponent::GetLifetimeReplicatedProps(TArray< class FLifetimeProperty >& OutLifetimeProps) const
27{
28 Super::GetLifetimeReplicatedProps(OutLifetimeProps);
29
31
32 RESET_REPLIFETIME_CONDITION_PRIVATE_PROPERTY(USceneComponent, AttachParent, COND_InitialOnly);
33 RESET_REPLIFETIME_CONDITION_PRIVATE_PROPERTY(USceneComponent, AttachSocketName, COND_InitialOnly);
34 RESET_REPLIFETIME_CONDITION_PRIVATE_PROPERTY(USceneComponent, AttachChildren, COND_InitialOnly);
35 RESET_REPLIFETIME_CONDITION_PRIVATE_PROPERTY(USceneComponent, RelativeLocation, COND_InitialOnly);
36 RESET_REPLIFETIME_CONDITION_PRIVATE_PROPERTY(USceneComponent, RelativeRotation, COND_InitialOnly);
37 RESET_REPLIFETIME_CONDITION_PRIVATE_PROPERTY(USceneComponent, RelativeScale3D, COND_InitialOnly);
38 //DISABLE_REPLICATED_PRIVATE_PROPERTY(AActor, AttachmentReplication);
39}
40
41void UNoRepSphereComponent::PreReplication(IRepChangedPropertyTracker& ChangedPropertyTracker)
42{
43 Super::PreReplication(ChangedPropertyTracker);
44
45}
46
47void FSkeletalMeshComponentEndPhysicsTickFunctionVR::ExecuteTick(float DeltaTime, enum ELevelTick TickType, ENamedThreads::Type CurrentThread, const FGraphEventRef& MyCompletionGraphEvent)
48{
49 //QUICK_SCOPE_CYCLE_COUNTER(FSkeletalMeshComponentEndPhysicsTickFunction_ExecuteTick);
50 //CSV_SCOPED_TIMING_STAT_EXCLUSIVE(Physics);
51
52 FActorComponentTickFunction::ExecuteTickHelper(TargetVR, /*bTickInEditor=*/ false, DeltaTime, TickType, [this](float DilatedTime)
53 {
55 });
56}
57
59{
60 if (TargetVR)
61 {
62 return TargetVR->GetFullName() + TEXT("[EndPhysicsTickVR]");
63 }
64 return TEXT("<NULL>[EndPhysicsTick]");
65}
66
68{
69 return FName(TEXT("SkeletalMeshComponentEndPhysicsTickVR"));
70}
71
72
74 : Super(ObjectInitializer)
75{
76 bReplicateMovement = true;
77 this->EndPhysicsTickFunction.bCanEverTick = false;
78 bReplicatePhysicsToAutonomousProxy = false;
79
80 EndPhysicsTickFunctionVR.TickGroup = TG_EndPhysics;
81 EndPhysicsTickFunctionVR.bCanEverTick = true;
82 EndPhysicsTickFunctionVR.bStartWithTickEnabled = true;
83}
84
85void UInversePhysicsSkeletalMeshComponent::PreReplication(IRepChangedPropertyTracker& ChangedPropertyTracker)
86{
87 Super::PreReplication(ChangedPropertyTracker);
88
89 // Don't replicate if set to not do it
90 DOREPLIFETIME_ACTIVE_OVERRIDE_PRIVATE_PROPERTY(USceneComponent, RelativeLocation, bReplicateMovement);
91 DOREPLIFETIME_ACTIVE_OVERRIDE_PRIVATE_PROPERTY(USceneComponent, RelativeRotation, bReplicateMovement);
92 DOREPLIFETIME_ACTIVE_OVERRIDE_PRIVATE_PROPERTY(USceneComponent, RelativeScale3D, bReplicateMovement);
93}
94
96{
97 //IMPORTANT!
98 //
99 // The decision on whether to use EndPhysicsTickComponent or not is made by ShouldRunEndPhysicsTick()
100 // Any changes that are made to EndPhysicsTickComponent that affect whether it should be run or not
101 // have to be reflected in ShouldRunEndPhysicsTick() as well
102
103 // if physics is disabled on dedicated server, no reason to be here.
104 if (!bEnablePhysicsOnDedicatedServer && IsRunningDedicatedServer())
105 {
106 FinalizeBoneTransform();
107 return;
108 }
109
110 if (IsRegistered() && IsSimulatingPhysics() && RigidBodyIsAwake())
111 {
112 if (bNotifySyncComponentToRBPhysics)
113 {
114 OnSyncComponentToRBPhysics();
115 }
116
117 SyncComponentToRBPhysics();
118 }
119
120 // this used to not run if not rendered, but that causes issues such as bounds not updated
121 // causing it to not rendered, at the end, I think we should blend body positions
122 // for example if you're only simulating, this has to happen all the time
123 // whether looking at it or not, otherwise
124 // @todo better solution is to check if it has moved by changing SyncComponentToRBPhysics to return true if anything modified
125 // and run this if that is true or rendered
126 // that will at least reduce the chance of mismatch
127 // generally if you move your actor position, this has to happen to approximately match their bounds
128 if (ShouldBlendPhysicsBones())
129 {
130 if (IsRegistered())
131 {
132 BlendInPhysicsInternalVR(ThisTickFunction);
133 }
134 }
135}
136
138{
139 check(IsInGameThread());
140
141 // Can't do anything without a SkeletalMesh
142 if (!SkeletalMesh)
143 {
144 return;
145 }
146
147 // We now have all the animations blended together and final relative transforms for each bone.
148 // If we don't have or want any physics, we do nothing.
149 if (Bodies.Num() > 0 && CollisionEnabledHasPhysics(GetCollisionEnabled()))
150 {
151 //HandleExistingParallelEvaluationTask(/*bBlockOnTask = */ true, /*bPerformPostAnimEvaluation =*/ true);
152 // start parallel work
153 //check(!IsValidRef(ParallelAnimationEvaluationTask));
154
155 const bool bParallelBlend = false;// !!CVarUseParallelBlendPhysics.GetValueOnGameThread() && FApp::ShouldUseThreadingForPerformance();
156 if (bParallelBlend)
157 {
158 /*SwapEvaluationContextBuffers();
159
160 ParallelAnimationEvaluationTask = TGraphTask<FParallelBlendPhysicsTask>::CreateTask().ConstructAndDispatchWhenReady(this);
161
162 // set up a task to run on the game thread to accept the results
163 FGraphEventArray Prerequistes;
164 Prerequistes.Add(ParallelAnimationEvaluationTask);
165
166 check(!IsValidRef(ParallelBlendPhysicsCompletionTask));
167 ParallelBlendPhysicsCompletionTask = TGraphTask<FParallelBlendPhysicsCompletionTask>::CreateTask(&Prerequistes).ConstructAndDispatchWhenReady(this);
168
169 ThisTickFunction.GetCompletionHandle()->DontCompleteUntil(ParallelBlendPhysicsCompletionTask);*/
170 }
171 else
172 {
173 PRAGMA_DISABLE_DEPRECATION_WARNINGS
174 PerformBlendPhysicsBonesVR(RequiredBones, BoneSpaceTransforms);
175 PRAGMA_ENABLE_DEPRECATION_WARNINGS
177 }
178 }
179}
180
182{
183 //SCOPE_CYCLE_COUNTER(STAT_FinalizeAnimationUpdate);
184
185 // Flip bone buffer and send 'post anim' notification
186 FinalizeBoneTransform();
187
188 if (!bSimulationUpdatesChildTransforms || !IsSimulatingPhysics()) //If we simulate physics the call to MoveComponent already updates the children transforms. If we are confident that animation will not be needed this can be skipped. TODO: this should be handled at the scene component layer
189 {
190 //SCOPE_CYCLE_COUNTER(STAT_FinalizeAnimationUpdate_UpdateChildTransforms);
191
192 // Update Child Transform - The above function changes bone transform, so will need to update child transform
193 // But only children attached to us via a socket.
194 UpdateChildTransforms(EUpdateTransformFlags::OnlyUpdateIfUsingSocket);
195 }
196
197 if (bUpdateOverlapsOnAnimationFinalize)
198 {
199 //SCOPE_CYCLE_COUNTER(STAT_FinalizeAnimationUpdate_UpdateOverlaps);
200
201 // animation often change overlap.
202 UpdateOverlaps();
203 }
204
205 // update bounds
206 // *NOTE* This is a private var, I have to remove it for this temp fix
207 /*if (bSkipBoundsUpdateWhenInterpolating)
208 {
209 if (AnimEvaluationContext.bDoEvaluation)
210 {
211 //SCOPE_CYCLE_COUNTER(STAT_FinalizeAnimationUpdate_UpdateBounds);
212 // Cached local bounds are now out of date
213 InvalidateCachedBounds();
214
215 UpdateBounds();
216 }
217 }
218 else*/
219 {
220 //SCOPE_CYCLE_COUNTER(STAT_FinalizeAnimationUpdate_UpdateBounds);
221 // Cached local bounds are now out of date
222 InvalidateCachedBounds();
223
224 UpdateBounds();
225 }
226
227 // Need to send new bounds to
228 MarkRenderTransformDirty();
229
230 // New bone positions need to be sent to render thread
231 MarkRenderDynamicDataDirty();
232
233 // If we have any Slave Components, they need to be refreshed as well.
234 RefreshSlaveComponents();
235}
236
238{
239 FTransform TM; // Should never contain scaling.
240 bool bUpToDate; // If this equals PhysAssetUpdateNum, then the matrix is up to date.
241};
242
243typedef TArray<FAssetWorldBoneTM, TMemStackAllocator<alignof(FAssetWorldBoneTM)>> TAssetWorldBoneTMArray;
244
245void UpdateWorldBoneTMVR(TAssetWorldBoneTMArray& WorldBoneTMs, const TArray<FTransform>& InBoneSpaceTransforms, int32 BoneIndex, USkeletalMeshComponent* SkelComp, const FTransform& LocalToWorldTM, const FVector& Scale3D)
246{
247 // If its already up to date - do nothing
248 if (WorldBoneTMs[BoneIndex].bUpToDate)
249 {
250 return;
251 }
252
253 FTransform ParentTM, RelTM;
254 if (BoneIndex == 0)
255 {
256 // If this is the root bone, we use the mesh component LocalToWorld as the parent transform.
257 ParentTM = LocalToWorldTM;
258 }
259 else
260 {
261 // If not root, use our cached world-space bone transforms.
262 int32 ParentIndex = SkelComp->SkeletalMesh->GetRefSkeleton().GetParentIndex(BoneIndex);
263 UpdateWorldBoneTMVR(WorldBoneTMs, InBoneSpaceTransforms, ParentIndex, SkelComp, LocalToWorldTM, Scale3D);
264 ParentTM = WorldBoneTMs[ParentIndex].TM;
265 }
266
267 if (InBoneSpaceTransforms.IsValidIndex(BoneIndex))
268 {
269 RelTM = InBoneSpaceTransforms[BoneIndex];
270 RelTM.ScaleTranslation(Scale3D);
271
272 WorldBoneTMs[BoneIndex].TM = RelTM * ParentTM;
273 WorldBoneTMs[BoneIndex].bUpToDate = true;
274 }
275}
276
277void UInversePhysicsSkeletalMeshComponent::PerformBlendPhysicsBonesVR(const TArray<FBoneIndexType>& InRequiredBones, TArray<FTransform>& InBoneSpaceTransforms)
278{
279 //SCOPE_CYCLE_COUNTER(STAT_BlendInPhysics);
280 // Get drawscale from Owner (if there is one)
281 FVector TotalScale3D = GetComponentTransform().GetScale3D();
282 FVector RecipScale3D = TotalScale3D.Reciprocal();
283
284 UPhysicsAsset* const PhysicsAsset = GetPhysicsAsset();
285 check(PhysicsAsset);
286
287 if (GetNumComponentSpaceTransforms() == 0)
288 {
289 return;
290 }
291
292 // Get the scene, and do nothing if we can't get one.
293 FPhysScene* PhysScene = nullptr;
294 if (GetWorld() != nullptr)
295 {
296 PhysScene = GetWorld()->GetPhysicsScene();
297 }
298
299 if (PhysScene == nullptr)
300 {
301 return;
302 }
303
304 FMemMark Mark(FMemStack::Get());
305 // Make sure scratch space is big enough.
306 TAssetWorldBoneTMArray WorldBoneTMs;
307 WorldBoneTMs.AddZeroed(GetNumComponentSpaceTransforms());
308
309 FTransform LocalToWorldTM = GetComponentTransform();
310
311 // This fixes the simulated inversed scaled skeletal mesh bug
312 LocalToWorldTM.SetScale3D(LocalToWorldTM.GetScale3D().GetSignVector());
313 LocalToWorldTM.NormalizeRotation();
314 //LocalToWorldTM.RemoveScaling();
315
316 TArray<FTransform>& EditableComponentSpaceTransforms = GetEditableComponentSpaceTransforms();
317
318 struct FBodyTMPair
319 {
320 FBodyInstance* BI;
321 FTransform TM;
322 };
323
324 FPhysicsCommand::ExecuteRead(this, [&]()
325 {
326 bool bSetParentScale = false;
327 const bool bSimulatedRootBody = Bodies.IsValidIndex(RootBodyData.BodyIndex) && Bodies[RootBodyData.BodyIndex]->IsInstanceSimulatingPhysics();
328 const FTransform NewComponentToWorld = bSimulatedRootBody ? GetComponentTransformFromBodyInstance(Bodies[RootBodyData.BodyIndex]) : FTransform::Identity;
329
330 // For each bone - see if we need to provide some data for it.
331 for (int32 i = 0; i < InRequiredBones.Num(); i++)
332 {
333 int32 BoneIndex = InRequiredBones[i];
334
335 // See if this is a physics bone..
336 int32 BodyIndex = PhysicsAsset->FindBodyIndex(SkeletalMesh->GetRefSkeleton().GetBoneName(BoneIndex));
337 // need to update back to physX so that physX knows where it was after blending
338 FBodyInstance* PhysicsAssetBodyInstance = nullptr;
339
340 // If so - get its world space matrix and its parents world space matrix and calc relative atom.
341 if (BodyIndex != INDEX_NONE)
342 {
343 PhysicsAssetBodyInstance = Bodies[BodyIndex];
344
345 //if simulated body copy back and blend with animation
346 if (PhysicsAssetBodyInstance->IsInstanceSimulatingPhysics())
347 {
348 FTransform PhysTM = PhysicsAssetBodyInstance->GetUnrealWorldTransform_AssumesLocked();
349
350 // Store this world-space transform in cache.
351 WorldBoneTMs[BoneIndex].TM = PhysTM;
352 WorldBoneTMs[BoneIndex].bUpToDate = true;
353
354 float UsePhysWeight = (bBlendPhysics) ? 1.f : PhysicsAssetBodyInstance->PhysicsBlendWeight;
355
356 // Find this bones parent matrix.
357 FTransform ParentWorldTM;
358
359 // if we wan't 'full weight' we just find
360 if (UsePhysWeight > 0.f)
361 {
362 if (!(ensure(InBoneSpaceTransforms.Num())))
363 {
364 continue;
365 }
366
367 if (BoneIndex == 0)
368 {
369 ParentWorldTM = LocalToWorldTM;
370 }
371 else
372 {
373 // If not root, get parent TM from cache (making sure its up-to-date).
374 int32 ParentIndex = SkeletalMesh->GetRefSkeleton().GetParentIndex(BoneIndex);
375 UpdateWorldBoneTMVR(WorldBoneTMs, InBoneSpaceTransforms, ParentIndex, this, LocalToWorldTM, TotalScale3D);
376 ParentWorldTM = WorldBoneTMs[ParentIndex].TM;
377 }
378
379
380 // Then calc rel TM and convert to atom.
381 FTransform RelTM = PhysTM.GetRelativeTransform(ParentWorldTM);
382 RelTM.RemoveScaling();
383 FQuat RelRot(RelTM.GetRotation());
384 FVector RelPos = RecipScale3D * RelTM.GetLocation();
385 FTransform PhysAtom = FTransform(RelRot, RelPos, InBoneSpaceTransforms[BoneIndex].GetScale3D());
386
387 // Now blend in this atom. See if we are forcing this bone to always be blended in
388 InBoneSpaceTransforms[BoneIndex].Blend(InBoneSpaceTransforms[BoneIndex], PhysAtom, UsePhysWeight);
389
390 if (!bSetParentScale)
391 {
392 //We must update RecipScale3D based on the atom scale of the root
393 TotalScale3D *= InBoneSpaceTransforms[0].GetScale3D();
394 RecipScale3D = TotalScale3D.Reciprocal();
395 bSetParentScale = true;
396 }
397
398 }
399 }
400 }
401
402 if (!(ensure(BoneIndex < EditableComponentSpaceTransforms.Num())))
403 {
404 continue;
405 }
406
407 // Update SpaceBases entry for this bone now
408 if (BoneIndex == 0)
409 {
410 if (!(ensure(InBoneSpaceTransforms.Num())))
411 {
412 continue;
413 }
414 EditableComponentSpaceTransforms[0] = InBoneSpaceTransforms[0];
415 }
416 else
417 {
418 if (bLocalSpaceKinematics || BodyIndex == INDEX_NONE || Bodies[BodyIndex]->IsInstanceSimulatingPhysics())
419 {
420 if (!(ensure(BoneIndex < InBoneSpaceTransforms.Num())))
421 {
422 continue;
423 }
424 const int32 ParentIndex = SkeletalMesh->GetRefSkeleton().GetParentIndex(BoneIndex);
425 EditableComponentSpaceTransforms[BoneIndex] = InBoneSpaceTransforms[BoneIndex] * EditableComponentSpaceTransforms[ParentIndex];
426
434 EditableComponentSpaceTransforms[BoneIndex].NormalizeRotation();
435 }
436 else if (bSimulatedRootBody)
437 {
438 EditableComponentSpaceTransforms[BoneIndex] = Bodies[BodyIndex]->GetUnrealWorldTransform_AssumesLocked().GetRelativeTransform(NewComponentToWorld);
439 }
440 }
441 }
442 }); //end scope for read lock
443
444}
445
447{
448 if (bRegister != EndPhysicsTickFunctionVR.IsTickFunctionRegistered())
449 {
450 if (bRegister)
451 {
452 if (SetupActorComponentTickFunction(&EndPhysicsTickFunctionVR))
453 {
455 // Make sure our EndPhysicsTick gets called after physics simulation is finished
456 UWorld* World = GetWorld();
457 if (World != nullptr)
458 {
459 EndPhysicsTickFunctionVR.AddPrerequisite(World, World->EndPhysicsTickFunction);
460 }
461 }
462 }
463 else
464 {
465 EndPhysicsTickFunctionVR.UnRegisterTickFunction();
466 }
467 }
468}
469
470void UInversePhysicsSkeletalMeshComponent::TickComponent(float DeltaTime, enum ELevelTick TickType, FActorComponentTickFunction* ThisTickFunction)
471{
472 //CSV_SCOPED_TIMING_STAT_EXCLUSIVE(Animation);
473
474 bool bShouldRunPhysTick = (bEnablePhysicsOnDedicatedServer || !IsNetMode(NM_DedicatedServer)) && // Early out if we are on a dedicated server and not running physics.
475 ((IsSimulatingPhysics() && RigidBodyIsAwake()) || ShouldBlendPhysicsBones());
476
477 RegisterEndPhysicsTick(PrimaryComponentTick.IsTickFunctionRegistered() && bShouldRunPhysTick);
478 //UpdateEndPhysicsTickRegisteredState();
479 RegisterClothTick(PrimaryComponentTick.IsTickFunctionRegistered() && ShouldRunClothTick());
480 //UpdateClothTickRegisteredState();
481
482
483 // If we are suspended, we will not simulate clothing, but as clothing is simulated in local space
484 // relative to a root bone we need to extract simulation positions as this bone could be animated.
485 /*if (bClothingSimulationSuspended && this->GetClothingSimulation() && this->GetClothingSimulation()->ShouldSimulate())
486 {
487 //CSV_SCOPED_TIMING_STAT(Animation, Cloth);
488
489 this->GetClothingSimulation()->GetSimulationData(CurrentSimulationData, this, Cast<USkeletalMeshComponent>(MasterPoseComponent.Get()));
490 }*/
491
492 Super::Super::TickComponent(DeltaTime, TickType, ThisTickFunction);
493
494 PendingRadialForces.Reset();
495
496 // Update bOldForceRefPose
497 bOldForceRefPose = bForceRefpose;
498
499
500 static const auto CVarAnimationDelaysEndGroup = IConsoleManager::Get().FindTConsoleVariableDataInt(TEXT("tick.AnimationDelaysEndGroup"));
502 const bool bDoLateEnd = CVarAnimationDelaysEndGroup->GetValueOnGameThread() > 0;
503 const bool bRequiresPhysics = EndPhysicsTickFunctionVR.IsTickFunctionRegistered();
504 const ETickingGroup EndTickGroup = bDoLateEnd && !bRequiresPhysics ? TG_PostPhysics : TG_PrePhysics;
505 if (ThisTickFunction)
506 {
507 ThisTickFunction->EndTickGroup = TG_PostPhysics;// EndTickGroup;
508
509 // Note that if animation is so long that we are blocked in EndPhysics we may want to reduce the priority. However, there is a risk that this function will not go wide early enough.
510 // This requires profiling and is very game dependent so cvar for now makes sense
511
512 static const auto CVarHiPriSkinnedMeshesTicks = IConsoleManager::Get().FindTConsoleVariableDataInt(TEXT("tick.HiPriSkinnedMeshes"));
513 bool bDoHiPri = CVarHiPriSkinnedMeshesTicks->GetValueOnGameThread() > 0;
514 if (ThisTickFunction->bHighPriority != bDoHiPri)
515 {
516 ThisTickFunction->SetPriorityIncludingPrerequisites(bDoHiPri);
517 }
518 }
519
520 // If we are waiting for ParallelEval to complete or if we require Physics,
521 // then FinalizeBoneTransform will be called and Anim events will be dispatched there.
522 // We prefer doing it there so these events are triggered once we have a new updated pose.
523 // Note that it's possible that FinalizeBoneTransform has already been called here if not using ParallelUpdate.
524 // or it's possible that it hasn't been called at all if we're skipping Evaluate due to not being visible.
525 // ConditionallyDispatchQueuedAnimEvents will catch that and only Dispatch events if not already done.
526 if (!IsRunningParallelEvaluation() && !bRequiresPhysics)
527 {
529 // Notify / Event Handling!
530 // This can do anything to our component (including destroy it)
531 // Any code added after this point needs to take that into account
533
534 ConditionallyDispatchQueuedAnimEvents();
535 }
536}
537
538void UInversePhysicsSkeletalMeshComponent::GetLifetimeReplicatedProps(TArray< class FLifetimeProperty > & OutLifetimeProps) const
539{
540 Super::GetLifetimeReplicatedProps(OutLifetimeProps);
541
543}
544
546 Super(ObjectInitializer.SetDefaultSubobjectClass<UInversePhysicsSkeletalMeshComponent>(TEXT("SkeletalMeshComponent0")))
547{
550}
551
552void AOptionalRepGrippableSkeletalMeshActor::GetLifetimeReplicatedProps(TArray< class FLifetimeProperty >& OutLifetimeProps) const
553{
554 Super::GetLifetimeReplicatedProps(OutLifetimeProps);
555
558
560 {
561 RESET_REPLIFETIME_CONDITION_PRIVATE_PROPERTY(AActor, AttachmentReplication, COND_InitialOnly);
562 }
563 //DISABLE_REPLICATED_PRIVATE_PROPERTY(AActor, AttachmentReplication);
564}
565
567{
569 {
570 return;
571 }
572
573 Super::OnRep_ReplicateMovement();
574}
575
577{
579 {
580 return;
581 }
582
583 Super::PostNetReceivePhysicState();
584}
void UpdateWorldBoneTMVR(TAssetWorldBoneTMArray &WorldBoneTMs, const TArray< FTransform > &InBoneSpaceTransforms, int32 BoneIndex, USkeletalMeshComponent *SkelComp, const FTransform &LocalToWorldTM, const FVector &Scale3D)
TArray< FAssetWorldBoneTM, TMemStackAllocator< alignof(FAssetWorldBoneTM)> > TAssetWorldBoneTMArray
UCLASS(Blueprintable, meta = (BlueprintSpawnableComponent, ChildCanTick), ClassGroup = (VRExpansionPl...
bool bIgnoreAttachmentReplication
UPROPERTY(EditAnywhere, Replicated, BlueprintReadWrite, Category = "Replication")
AOptionalRepGrippableSkeletalMeshActor(const FObjectInitializer &ObjectInitializer)
bool bIgnorePhysicsReplication
UPROPERTY(EditAnywhere, Replicated, BlueprintReadWrite, Category = "Replication")
UCLASS(Blueprintable, meta = (ChildCanTick, BlueprintSpawnableComponent), ClassGroup = (VRExpansionPl...
UInversePhysicsSkeletalMeshComponent(const FObjectInitializer &ObjectInitializer)
void PerformBlendPhysicsBonesVR(const TArray< FBoneIndexType > &InRequiredBones, TArray< FTransform > &InBoneSpaceTransforms)
virtual void TickComponent(float DeltaTime, enum ELevelTick TickType, FActorComponentTickFunction *ThisTickFunction) override
void BlendInPhysicsInternalVR(FTickFunction &ThisTickFunction)
FSkeletalMeshComponentEndPhysicsTickFunctionVR EndPhysicsTickFunctionVR
void EndPhysicsTickComponentVR(FSkeletalMeshComponentEndPhysicsTickFunctionVR &ThisTickFunction)
bool bReplicateMovement
UPROPERTY(EditAnywhere, Replicated, BlueprintReadWrite, Category = "Component Replication")
virtual void RegisterEndPhysicsTick(bool bRegister) override
virtual void PreReplication(IRepChangedPropertyTracker &ChangedPropertyTracker) override
UCLASS(Blueprintable, meta = (BlueprintSpawnableComponent, ChildCanTick), ClassGroup = (VRExpansionPl...
bool bReplicateMovement
UPROPERTY(EditAnywhere, Replicated, BlueprintReadWrite, Category = "Component Replication")
virtual void PreReplication(IRepChangedPropertyTracker &ChangedPropertyTracker) override
UNoRepSphereComponent(const FObjectInitializer &ObjectInitializer)
virtual void ExecuteTick(float DeltaTime, enum ELevelTick TickType, ENamedThreads::Type CurrentThread, const FGraphEventRef &MyCompletionGraphEvent) override
virtual FName DiagnosticContext(bool bDetailed) override