UDocumentation UE5.7 10.02.2026 (Source)
API documentation for Unreal Engine 5.7
FieldSystemProxyHelper.h
Go to the documentation of this file.
1// Copyright Epic Games, Inc. All Rights Reserved.
2
3#pragma once
4
5#include "Field/FieldSystem.h"
6#include "Chaos/Array.h"
9#include "Chaos/Defines.h"
11#include "Chaos/Particles.h"
12#include <limits>
13
15
16namespace Chaos
17{
29 template <typename PhysicsProxy>
30 static bool BuildFieldSamplePoints(
31 PhysicsProxy* LocalProxy,
34 FFieldExecutionDatas& ExecutionDatas,
39 {
40 if(!LocalProxy || !RigidSolver)
41 {
42 return false;
43 }
49
50 EFieldFilterType FilterType = EFieldFilterType::Field_Filter_Max;
51 EFieldObjectType ObjectType = EFieldObjectType::Field_Object_Max;
52 EFieldPositionType PositionType = EFieldPositionType::Field_Position_Max;
53
55 {
57 FilterType = MetaDataFilter->FilterType;
58 ObjectType = MetaDataFilter->ObjectType;
59 PositionType = MetaDataFilter->PositionType;
60 }
61
64
65 //if (LocalProxy && ( (PrevResolutionType != ResolutionType) || (PrevFilterType != FilterType) || (PrevObjectType != ObjectType) || (PrevPositionType != PositionType) || FilteredHandles.Num() == 0))
66 {
67 if (FilterType != EFieldFilterType::Field_Filter_Max)
68 {
69 LocalProxy->GetFilteredParticleHandles(FilteredHandles, RigidSolver, FilterType, ObjectType);
70 }
71 else
72 {
73 LocalProxy->GetRelevantParticleHandles(FilteredHandles, RigidSolver, ResolutionType);
74 }
75
77 PrevFilterType = FilterType;
78 PrevObjectType = ObjectType;
79 PrevPositionType = PositionType;
80
84
85 auto FillExecutionDatas = [&ExecutionDatas,&FieldCommand,&InsideHandles](FVec3 SamplePosition, Chaos::FGeometryParticleHandle* ParticleHandle, int32& HandleIndex)
86 {
87 if (FPBDRigidClusteredParticleHandle* ClusterHandle = ParticleHandle->CastToClustered())
88 {
89 // Disabled clustered particles that are driven by a parent, contain particle
90 // positions in local space. The field system requires the transformation of
91 // the disabled child particles into world space.
92 if (ClusterHandle->Disabled() == true)
93 {
95
96 // go up the chain until no parent or a non-disabled parent ( should normally stop at a non disabled one )
98 while (ParentHandle && ParentHandle->Disabled())
99 {
100 RelativeFrame = RelativeFrame * ParentHandle->ChildToParent();
101 ParentHandle = ParentHandle->Parent();
102 }
103
104 if (ParentHandle && ParentHandle->Disabled() == false)
105 {
108 SamplePosition = ChildFrame.GetTranslation();
109 }
110 }
111 }
112
113
114 if (FieldCommand.BoundingBox.IsInside(SamplePosition))
115 {
116 ExecutionDatas.SamplePositions[HandleIndex] = SamplePosition;
117 ExecutionDatas.SampleIndices[HandleIndex] = FFieldContextIndex(HandleIndex, HandleIndex);
118 InsideHandles[HandleIndex] = ParticleHandle;
119 ++HandleIndex;
120 }
121 };
122
123 int32 HandleIndex = 0;
124 if (PositionType == EFieldPositionType::Field_Position_CenterOfMass)
125 {
126 for (int32 Idx = 0; Idx < FilteredHandles.Num(); ++Idx)
127 {
128 if (Chaos::FPBDRigidParticleHandle* RigidHandle = FilteredHandles[Idx]->CastToRigidParticle())
129 {
132 }
133 }
134 }
135 else
136 {
137 for (int32 Idx = 0; Idx < FilteredHandles.Num(); ++Idx)
138 {
140 {
141 const FVec3& SamplePosition = FilteredHandle->GetX();
143 }
144 }
145 }
146 ExecutionDatas.SamplePositions.SetNum(HandleIndex, EAllowShrinking::No);
147 ExecutionDatas.SampleIndices.SetNum(HandleIndex, EAllowShrinking::No);
148 InsideHandles.SetNum(HandleIndex, EAllowShrinking::No);
149 }
150 return InsideHandles.Num() > 0;
151 }
152
159 static void InitDynamicStateResults(const TArray<Chaos::FGeometryParticleHandle*>& ParticleHandles, FFieldContext& FieldContext, TArray<int32>& LocalResults)
160 {
161 for (const FFieldContextIndex& Index : FieldContext.GetEvaluatedSamples())
162 {
163 const Chaos::EObjectStateType InitState = (ParticleHandles[Index.Sample]->ObjectState() != Chaos::EObjectStateType::Uninitialized) ?
164 ParticleHandles[Index.Sample]->ObjectState() : Chaos::EObjectStateType::Dynamic;
165 LocalResults[Index.Result] = static_cast<int32>(InitState);
166 }
167 }
168
175 static void InitActivateDisabledResults(const TArray<Chaos::FGeometryParticleHandle*>& ParticleHandles, FFieldContext& FieldContext, TArray<int32>& LocalResults)
176 {
177 for (const FFieldContextIndex& Index : FieldContext.GetEvaluatedSamples())
178 {
179 Chaos::FPBDRigidParticleHandle* RigidHandle = ParticleHandles[Index.Sample]->CastToRigidParticle();
180 if (RigidHandle)
181 {
182 LocalResults[Index.Result] = RigidHandle->Disabled();
183 }
184 }
185 }
186
193 static void SetParticleDynamicState(Chaos::FPBDRigidsSolver* RigidSolver,
195 {
196 const bool bIsGC = (RigidHandle->GetParticleType() == Chaos::EParticleType::GeometryCollection) ||
197 (RigidHandle->GetParticleType() == Chaos::EParticleType::Clustered && !RigidHandle->CastToClustered()->InternalCluster());
198
199 if (!bIsGC)
200 {
201 RigidSolver->GetEvolution()->SetParticleObjectState(RigidHandle, FieldState);
202 }
203 else
204 {
205 // @todo(chaos): this should also call Evolution.SetParticleObjectState, but to do that
206 // we need to change how the ActiveParticlesArray is handled in RigidParticleSOAs.
207 // Instead we manually do the parts of SetParticleObjectState that are still required
208 // while avoiding the SOA management.
209 RigidHandle->SetObjectStateLowLevel(FieldState);
210 if (!RigidHandle->Disabled())
211 {
212 RigidSolver->GetEvolution()->GetIslandManager().AddParticle(RigidHandle);
213
214 // This is mainly just to refresh the views. Note that we do not want to enable disabled particles.
215 RigidSolver->GetEvolution()->GetParticles().EnableParticle(RigidHandle);
216 }
217 }
218 }
219
230 static bool ReportDynamicStateResult(Chaos::FPBDRigidsSolver* RigidSolver,
232 const bool HasInitialLinearVelocity, const Chaos::FVec3& InitialLinearVelocity,
233 const bool HasInitialAngularVelocity, const Chaos::FVec3& InitialAngularVelocity)
234 {
235 const Chaos::EObjectStateType HandleState = RigidHandle->ObjectState();
236
237 // Do we need to be sure the mass > 0 only for the dynamic state
240
242 {
243 SetParticleDynamicState(RigidSolver, FieldState, RigidHandle);
244
246 {
247 RigidHandle->SetVf(Chaos::FVec3f(0));
248 RigidHandle->SetWf(Chaos::FVec3f(0));
249 }
251 {
253 {
254 RigidHandle->SetV(InitialLinearVelocity);
255 }
257 {
258 RigidHandle->SetW(InitialAngularVelocity);
259 }
260 }
261 }
262 return bHasStateChanged;
263 }
264
271 {
272 if (UpdatedParticleIndices.Num() > 0)
273 {
275 for (const FFieldContextIndex& ParticleIndex: UpdatedParticleIndices)
276 {
277 if (FPBDRigidClusteredParticleHandle* ClusteredHandle = Particles[ParticleIndex.Sample]->CastToClustered())
278 {
281 {
283 }
285 }
286 }
287
288 const FRigidClustering& Clustering = RigidSolver->GetEvolution()->GetRigidClustering();
290 {
292 {
293 if (TopParentClusteredHandle->ClusterIds().NumChildren)
294 {
295 UpdateKinematicProperties(TopParentClusteredHandle, Clustering.GetChildrenMap(), *RigidSolver->GetEvolution());
296 }
297 else
298 {
299 // if the cluster is dynamic let's make sure we clear kinematic target to avoid animated ones to have their velocity reset by the kinematic target update
300 // for particles with children this is taken care in UpdateKinematicProperties
302 {
303 RigidSolver->GetEvolution()->SetParticleKinematicTarget(TopParentClusteredHandle, FKinematicTarget());
304 }
305 }
306 }
307 }
308 }
309 }
310
318 {
319 // if no per particle physics material is set, make one
320 if (!RigidSolver->GetEvolution()->GetPerParticlePhysicsMaterial(RigidHandle).IsValid())
321 {
323 NewMaterial->SleepingLinearThreshold = ResultThreshold;
324 NewMaterial->SleepingAngularThreshold = ResultThreshold;
325
326 RigidSolver->GetEvolution()->SetPhysicsMaterial(RigidHandle, MakeSerializable(NewMaterial));
327 RigidSolver->GetEvolution()->SetPerParticlePhysicsMaterial(RigidHandle, NewMaterial);
328 }
329 else
330 {
331 const TUniquePtr<Chaos::FChaosPhysicsMaterial>& InstanceMaterial = RigidSolver->GetEvolution()->GetPerParticlePhysicsMaterial(RigidHandle);
332
333 if (ResultThreshold != InstanceMaterial->DisabledLinearThreshold)
334 {
335 InstanceMaterial->SleepingLinearThreshold = ResultThreshold;
336 InstanceMaterial->SleepingAngularThreshold = ResultThreshold;
337 }
338 }
339 }
340
348 {
349 // if no per particle physics material is set, make one
350 if (!RigidSolver->GetEvolution()->GetPerParticlePhysicsMaterial(RigidHandle).IsValid())
351 {
353 NewMaterial->DisabledLinearThreshold = ResultThreshold;
354 NewMaterial->DisabledAngularThreshold = ResultThreshold;
355
356 RigidSolver->GetEvolution()->SetPhysicsMaterial(RigidHandle, MakeSerializable(NewMaterial));
357 RigidSolver->GetEvolution()->SetPerParticlePhysicsMaterial(RigidHandle, NewMaterial);
358 }
359 else
360 {
361 const TUniquePtr<Chaos::FChaosPhysicsMaterial>& InstanceMaterial = RigidSolver->GetEvolution()->GetPerParticlePhysicsMaterial(RigidHandle);
362
363 if (ResultThreshold != InstanceMaterial->DisabledLinearThreshold)
364 {
365 InstanceMaterial->DisabledLinearThreshold = ResultThreshold;
366 InstanceMaterial->DisabledAngularThreshold = ResultThreshold;
367 }
368 }
369 }
370
381 static void FieldIntegerParameterUpdate(Chaos::FPBDRigidsSolver* RigidSolver, const FFieldSystemCommand& FieldCommand,
383 Chaos::FPBDPositionConstraints& PositionTarget,
385 {
387
388 if (FieldCommand.PhysicsType == EFieldPhysicsType::Field_DynamicState)
389 {
391 {
392 InitDynamicStateResults(ParticleHandles, FieldContext, FinalResults);
393
394 static_cast<const FFieldNode<int32>*>(FieldCommand.RootNode.Get())->Evaluate(FieldContext, ResultsView);
395
396 bool bHasStateChanged = false;
397
400 {
401 Chaos::FPBDRigidParticleHandle* RigidHandle = ParticleHandles[Index.Sample]->CastToRigidParticle();
402 if (RigidHandle)
403 {
404 const int32 CurrResult = ResultsView[Index.Result];
405 check(CurrResult < std::numeric_limits<int8>::max());
406
407 const int8 ResultState = static_cast<int8>(CurrResult);
408 bHasStateChanged |= ReportDynamicStateResult(RigidSolver, static_cast<Chaos::EObjectStateType>(ResultState), RigidHandle,
409 false, Chaos::FVec3(0), false, Chaos::FVec3(0));
410 }
411 }
413 {
414 UpdateSolverParticlesState(RigidSolver, EvaluatedSamples, ParticleHandles);
415 }
416 }
417 }
418 else if (FieldCommand.PhysicsType == EFieldPhysicsType::Field_ActivateDisabled)
419 {
421 {
422 InitActivateDisabledResults(ParticleHandles, FieldContext, FinalResults);
423
424 static_cast<const FFieldNode<int32>*>(FieldCommand.RootNode.Get())->Evaluate(FieldContext, ResultsView);
425 for (const FFieldContextIndex& Index : FieldContext.GetEvaluatedSamples())
426 {
427 Chaos::FPBDRigidParticleHandle* RigidHandle = ParticleHandles[Index.Sample]->CastToRigidParticle();
428 if (RigidHandle && RigidHandle->Disabled() && ResultsView[Index.Result] == 0)
429 {
430 RigidSolver->GetEvolution()->EnableParticle(RigidHandle);
432 }
433 }
434 }
435 }
436 else if (FieldCommand.PhysicsType == EFieldPhysicsType::Field_CollisionGroup)
437 {
439 {
440 static_cast<const FFieldNode<int32>*>(FieldCommand.RootNode.Get())->Evaluate(FieldContext, ResultsView);
441 for (const FFieldContextIndex& Index : FieldContext.GetEvaluatedSamples())
442 {
443 Chaos::FPBDRigidClusteredParticleHandle* RigidHandle = ParticleHandles[Index.Sample]->CastToClustered();
444 if (RigidHandle)
445 {
446 RigidHandle->SetCollisionGroup(ResultsView[Index.Result]);
447 }
448 }
449 }
450 }
451 else if (FieldCommand.PhysicsType == EFieldPhysicsType::Field_PositionStatic)
452 {
454 {
455 static_cast<const FFieldNode<int32>*>(FieldCommand.RootNode.Get())->Evaluate(FieldContext, ResultsView);
456 for (const FFieldContextIndex& Index : FieldContext.GetEvaluatedSamples())
457 {
458 Chaos::FPBDRigidClusteredParticleHandle* RigidHandle = ParticleHandles[Index.Sample]->CastToClustered();
459 if (RigidHandle && ResultsView[Index.Result])
460 {
461 if (TargetedParticles.Contains(Index.Sample))
462 {
463 const int32 ConstraintIndex = TargetedParticles[Index.Sample];
464 PositionTarget.Replace(ConstraintIndex, ParticleHandles[Index.Sample]->GetX());
465 }
466 else
467 {
468 const int32 ConstraintIndex = PositionTarget.NumConstraints();
469 PositionTarget.AddConstraint(RigidHandle, RigidHandle->GetX());
470 TargetedParticles.Add(Index.Sample, ConstraintIndex);
471 }
472 }
473 }
474 }
475 }
476 else if (FieldCommand.PhysicsType == EFieldPhysicsType::Field_DynamicConstraint)
477 {
479 {
480 UE_LOG(LogChaos, Error, TEXT("Dynamic constraint target currently not supported by chaos"));
481 }
482 }
483 }
484
495 static void FieldScalarParameterUpdate(Chaos::FPBDRigidsSolver* RigidSolver, const FFieldSystemCommand& FieldCommand,
497 Chaos::FPBDPositionConstraints& PositionTarget,
499 {
501
502 if (FieldCommand.PhysicsType == EFieldPhysicsType::Field_ExternalClusterStrain)
503 {
505 {
506 FRigidClustering& RigidClustering = RigidSolver->GetEvolution()->GetRigidClustering();
507 static_cast<const FFieldNode<float>*>(FieldCommand.RootNode.Get())->Evaluate(FieldContext, ResultsView);
508 for (const FFieldContextIndex& Index : FieldContext.GetEvaluatedSamples())
509 {
510 const float ExternalStrainValue = ResultsView[Index.Result];
511 if (ExternalStrainValue > 0)
512 {
514 {
515 const FRealSingle CurrentExternalStrains = ClusteredParticle->GetExternalStrain();
516 RigidClustering.SetExternalStrain(ClusteredParticle, FMath::Max(CurrentExternalStrains, ExternalStrainValue));
517 }
518 }
519 }
520 }
521 }
522 else if (FieldCommand.PhysicsType == EFieldPhysicsType::Field_Kill)
523 {
525 {
526 static_cast<const FFieldNode<float>*>(FieldCommand.RootNode.Get())->Evaluate(FieldContext, ResultsView);
527 for (const FFieldContextIndex& Index : FieldContext.GetEvaluatedSamples())
528 {
529 Chaos::FPBDRigidParticleHandle* RigidHandle = ParticleHandles[Index.Sample]->CastToRigidParticle();
530 if (RigidHandle && ResultsView[Index.Result] > 0.0)
531 {
532 RigidSolver->GetEvolution()->DisableParticle(RigidHandle);
533 }
534 }
535 }
536 }
537 else if (FieldCommand.PhysicsType == EFieldPhysicsType::Field_SleepingThreshold)
538 {
540 {
541 static_cast<const FFieldNode<float>*>(FieldCommand.RootNode.Get())->Evaluate(FieldContext, ResultsView);
542 for (const FFieldContextIndex& Index : FieldContext.GetEvaluatedSamples())
543 {
544 Chaos::FPBDRigidParticleHandle* RigidHandle = ParticleHandles[Index.Sample]->CastToRigidParticle();
545 if (RigidHandle && ResultsView.Num() > 0)
546 {
547 UpdateMaterialSleepingThreshold(RigidSolver, RigidHandle, ResultsView[Index.Result]);
548 }
549 }
550 }
551 }
552 else if (FieldCommand.PhysicsType == EFieldPhysicsType::Field_DisableThreshold)
553 {
555 {
556 static_cast<const FFieldNode<float>*>(FieldCommand.RootNode.Get())->Evaluate(FieldContext, ResultsView);
557 for (const FFieldContextIndex& Index : FieldContext.GetEvaluatedSamples())
558 {
559 Chaos::FPBDRigidParticleHandle* RigidHandle = ParticleHandles[Index.Sample]->CastToRigidParticle();
560
561 if (RigidHandle && RigidHandle->ObjectState() == Chaos::EObjectStateType::Dynamic && ResultsView.Num() > 0)
562 {
563 UpdateMaterialDisableThreshold(RigidSolver, RigidHandle, ResultsView[Index.Result]);
564 }
565 }
566 }
567 }
568 else if (FieldCommand.PhysicsType == EFieldPhysicsType::Field_InternalClusterStrain)
569 {
571 {
572 FRigidClustering& RigidClustering = RigidSolver->GetEvolution()->GetRigidClustering();
573 static_cast<const FFieldNode<float>*>(FieldCommand.RootNode.Get())->Evaluate(FieldContext, ResultsView);
574 for (const FFieldContextIndex& Index : FieldContext.GetEvaluatedSamples())
575 {
576 Chaos::FPBDRigidClusteredParticleHandle* RigidHandle = ParticleHandles[Index.Sample]->CastToClustered();
578 {
579 RigidClustering.SetInternalStrain(RigidHandle, RigidHandle->GetInternalStrains() + ResultsView[Index.Result]);
580 }
581 }
582 }
583 }
584 }
585
596 static void FieldVectorParameterUpdate(Chaos::FPBDRigidsSolver* RigidSolver, const FFieldSystemCommand& FieldCommand,
598 Chaos::FPBDPositionConstraints& PositionTarget,
600 {
602
603 if (FieldCommand.PhysicsType == EFieldPhysicsType::Field_LinearVelocity)
604 {
606 {
607 static_cast<const FFieldNode<FVector>*>(FieldCommand.RootNode.Get())->Evaluate(FieldContext, ResultsView);
608 for (const FFieldContextIndex& Index : FieldContext.GetEvaluatedSamples())
609 {
610 Chaos::FPBDRigidParticleHandle* RigidHandle = ParticleHandles[Index.Sample]->CastToRigidParticle();
612 {
613 RigidHandle->SetV(RigidHandle->GetV() + ResultsView[Index.Result]);
614 }
615 }
616 }
617 }
618 else if (FieldCommand.PhysicsType == EFieldPhysicsType::Field_LinearImpulse)
619 {
621 {
622 static_cast<const FFieldNode<FVector>*>(FieldCommand.RootNode.Get())->Evaluate(FieldContext, ResultsView);
623 for (const FFieldContextIndex& Index : FieldContext.GetEvaluatedSamples())
624 {
625 Chaos::FPBDRigidParticleHandle* RigidHandle = ParticleHandles[Index.Sample]->CastToRigidParticle();
627 {
628 const FVec3 CurrentImpulseVelocity = RigidHandle->LinearImpulseVelocity();
629 RigidHandle->SetLinearImpulseVelocity(CurrentImpulseVelocity + (ResultsView[Index.Result] * RigidHandle->InvM()));
630 }
631 }
632 }
633 }
634 else if (FieldCommand.PhysicsType == EFieldPhysicsType::Field_AngularVelociy)
635 {
637 {
638 static_cast<const FFieldNode<FVector>*>(FieldCommand.RootNode.Get())->Evaluate(FieldContext, ResultsView);
639
640 for (const FFieldContextIndex& Index : FieldContext.GetEvaluatedSamples())
641 {
642 Chaos::FPBDRigidParticleHandle* RigidHandle = ParticleHandles[Index.Sample]->CastToRigidParticle();
644 {
645 RigidHandle->SetW(RigidHandle->GetW() + ResultsView[Index.Result]);
646 }
647 }
648 }
649 }
650 else if (FieldCommand.PhysicsType == EFieldPhysicsType::Field_PositionTarget)
651 {
653 {
654 static_cast<const FFieldNode<FVector>*>(FieldCommand.RootNode.Get())->Evaluate(FieldContext, ResultsView);
655 for (const FFieldContextIndex& Index : FieldContext.GetEvaluatedSamples())
656 {
657 Chaos::FPBDRigidClusteredParticleHandle* RigidHandle = ParticleHandles[Index.Sample]->CastToClustered();
658 if (RigidHandle && ResultsView[Index.Result] != FVector(FLT_MAX))
659 {
660 if (TargetedParticles.Contains(Index.Sample))
661 {
662 const int32 ConstraintIndex = TargetedParticles[Index.Sample];
663 PositionTarget.Replace(ConstraintIndex, ResultsView[Index.Result]);
664 }
665 else
666 {
667 const int32 ConstraintIndex = PositionTarget.NumConstraints();
668 PositionTarget.AddConstraint(RigidHandle, ResultsView[Index.Result]);
669 TargetedParticles.Add(Index.Sample, ConstraintIndex);
670 }
671 }
672 }
673 }
674 }
675 else if (FieldCommand.PhysicsType == EFieldPhysicsType::Field_PositionAnimated)
676 {
678 {
679 UE_LOG(LogChaos, Error, TEXT("Position Animated target currently not supported by chaos"));
680 }
681 }
682 }
683
684
685 static void FieldVectorForceUpdate(Chaos::FPBDRigidsSolver* RigidSolver, const FFieldSystemCommand& FieldCommand,
687 {
689
690 static_cast<const FFieldNode<FVector>*>(FieldCommand.RootNode.Get())->Evaluate(FieldContext, ResultsView);
691
692 if (FieldCommand.PhysicsType == EFieldPhysicsType::Field_LinearForce)
693 {
695 {
696 for (const FFieldContextIndex& Index : FieldContext.GetEvaluatedSamples())
697 {
698 Chaos::FPBDRigidParticleHandle* RigidHandle = ParticleHandles[Index.Sample]->CastToRigidParticle();
699 if (RigidHandle && !RigidHandle->Disabled() && (RigidHandle->ObjectState() == Chaos::EObjectStateType::Dynamic || RigidHandle->ObjectState() == Chaos::EObjectStateType::Sleeping))
700 {
701 if (RigidHandle->Sleeping())
702 {
703 RigidHandle->SetObjectStateLowLevel(Chaos::EObjectStateType::Dynamic);
704 }
705 RigidHandle->AddForce(ResultsView[Index.Result]);
706 }
707 }
708 }
709 }
710 else if (FieldCommand.PhysicsType == EFieldPhysicsType::Field_AngularTorque)
711 {
713 {
714 for (const FFieldContextIndex& Index : FieldContext.GetEvaluatedSamples())
715 {
716 Chaos::FPBDRigidParticleHandle* RigidHandle = ParticleHandles[Index.Sample]->CastToRigidParticle();
718 {
719 if (RigidHandle->Sleeping())
720 {
721 RigidHandle->SetObjectStateLowLevel(Chaos::EObjectStateType::Dynamic);
722 }
723 RigidHandle->AddTorque(ResultsView[Index.Result]);
724 }
725 }
726 }
727 }
728 }
729}
730
732{
734 {
735 return (FieldCommand.PhysicsType == EFieldPhysicsType::Field_DynamicState) ||
736 (FieldCommand.PhysicsType == EFieldPhysicsType::Field_ActivateDisabled) ||
737 (FieldCommand.PhysicsType == EFieldPhysicsType::Field_CollisionGroup);
738
739 }
740 else if (FieldCommand.RootNode->Type() == FFieldNodeBase::EFieldType::EField_Float)
741 {
742 return (FieldCommand.PhysicsType == EFieldPhysicsType::Field_ExternalClusterStrain) ||
743 (FieldCommand.PhysicsType == EFieldPhysicsType::Field_Kill) ||
744 (FieldCommand.PhysicsType == EFieldPhysicsType::Field_SleepingThreshold) ||
745 (FieldCommand.PhysicsType == EFieldPhysicsType::Field_DisableThreshold) ||
746 (FieldCommand.PhysicsType == EFieldPhysicsType::Field_InternalClusterStrain);
747 }
748 else if (FieldCommand.RootNode->Type() == FFieldNodeBase::EFieldType::EField_FVector)
749 {
750 return (FieldCommand.PhysicsType == EFieldPhysicsType::Field_LinearVelocity) ||
751 (FieldCommand.PhysicsType == EFieldPhysicsType::Field_AngularVelociy) ||
752 (FieldCommand.PhysicsType == EFieldPhysicsType::Field_LinearImpulse);
753 }
754 return false;
755}
756
758{
760 {
761 return (FieldCommand.PhysicsType == EFieldPhysicsType::Field_LinearForce) ||
762 (FieldCommand.PhysicsType == EFieldPhysicsType::Field_AngularTorque);
763 }
764 return false;
765}
766
#define FORCEINLINE
Definition AndroidPlatform.h:140
#define check(expr)
Definition AssertionMacros.h:314
FPlatformTypes::int8 int8
An 8-bit signed integer.
Definition Platform.h:1121
#define TEXT(x)
Definition Platform.h:1272
FPlatformTypes::int32 int32
A 32-bit signed integer.
Definition Platform.h:1125
#define SCOPE_CYCLE_COUNTER(Stat)
Definition Stats.h:650
UE_FORCEINLINE_HINT TSharedRef< CastToType, Mode > StaticCastSharedRef(TSharedRef< CastFromType, Mode > const &InSharedRef)
Definition SharedPointer.h:127
FORCEINLINE bool IsParameterFieldValid(const FFieldSystemCommand &FieldCommand)
Definition FieldSystemProxyHelper.h:731
FORCEINLINE bool IsForceFieldValid(const FFieldSystemCommand &FieldCommand)
Definition FieldSystemProxyHelper.h:757
EFieldObjectType
Definition FieldSystemTypes.h:103
EFieldResolutionType
Definition FieldSystemTypes.h:72
EFieldPositionType
Definition FieldSystemTypes.h:119
EFieldFilterType
Definition FieldSystemTypes.h:86
#define UE_LOG(CategoryName, Verbosity, Format,...)
Definition LogMacros.h:270
uint8_t uint8
Definition binka_ue_file_header.h:8
Constraint a single particle to a world-space position.
Definition PBDPositionConstraints.h:38
void Replace(const int32 ConstraintIndex, const FVec3 &Position)
Definition PBDPositionConstraints.h:168
FConstraintContainerHandle * AddConstraint(FPBDRigidParticleHandle *Particle, const FVec3 &Position)
Definition PBDPositionConstraints.h:83
int32 NumConstraints() const
Definition PBDPositionConstraints.h:75
Definition PBDRigidsSolver.h:84
static FVec3 GetCoMWorldPosition(T_PARTICLEHANDLE Particle)
Definition ParticleUtilities.h:140
Definition ParticleHandle.h:436
const TPBDRigidClusteredParticleHandleImp< T, d, bPersistent > * CastToClustered() const
Definition ParticleHandle.h:1703
Definition ParticleHandle.h:987
Definition Vector.h:407
@ EField_Float
Definition FieldSystem.h:413
@ EField_FVector
Definition FieldSystem.h:414
@ EField_Int32
Definition FieldSystem.h:412
Definition FieldSystem.h:481
Definition FieldSystem.h:522
Definition FieldSystem.h:185
EFieldFilterType FilterType
Definition FieldSystem.h:192
Definition FieldSystem.h:175
@ ECommandData_Filter
Definition FieldSystem.h:165
@ ECommandData_ProcessingResolution
Definition FieldSystem.h:161
Definition Array.h:670
void SetNum(SizeType NewNum, EAllowShrinking AllowShrinking=UE::Core::Private::AllowShrinkingByDefault< AllocatorType >())
Definition Array.h:2308
Definition FieldArrayView.h:18
Definition UnrealString.h.inl:34
Definition UniquePtr.h:107
Definition SkeletalMeshComponent.h:307
TRigidTransform< FReal, 3 > FRigidTransform3
Definition Core.h:22
FRealDouble FReal
Definition Real.h:22
TSerializablePtr< T > MakeSerializable(const TUniquePtr< T > &Unique)
Definition Serializable.h:60
EObjectStateType
Definition ObjectState.h:10
float FRealSingle
Definition Real.h:14
TVector< FReal, 3 > FVec3
Definition Core.h:17
TPBDRigidClusteredParticleHandle< FReal, 3 > FPBDRigidClusteredParticleHandle
Definition ParticleHandleFwd.h:75
FExpressionResult Evaluate(const CharType *InExpression, const TTokenDefinitions< CharType > &InTokenDefinitions, const FExpressionGrammar &InGrammar, const TIOperatorEvaluationEnvironment< CharType > &InEnvironment)
Definition ExpressionParser.cpp:728
U16 Index
Definition radfft.cpp:71
Definition FieldSystem.h:22
Definition FieldSystem.h:242
Definition FieldSystem.h:76
TArray< Chaos::FGeometryParticleHandle * > ParticleHandles[(uint8) EFieldCommandHandlesType::NumHandles]
Definition FieldSystem.h:84
TArray< FVector > SamplePositions
Definition FieldSystem.h:78
TArray< FFieldContextIndex > SampleIndices
Definition FieldSystem.h:81
Definition PhysSubstepTasks.h:18