UDocumentation UE5.7 10.02.2026 (Source)
API documentation for Unreal Engine 5.7
ImplicitObjectScaled.h
Go to the documentation of this file.
1// Copyright Epic Games, Inc. All Rights Reserved.
2#pragma once
3
4#include "Chaos/Box.h"
6#include "Chaos/Convex.h"
7#include "Chaos/ImplicitFwd.h"
9#include "Chaos/Transform.h"
10#include "Chaos/Utilities.h" // For ScaleInertia - pull that into mass utils
11#include "ChaosArchive.h"
12#include "Templates/EnableIf.h"
13#include "Math/NumericLimits.h"
14#include "ChaosCheck.h"
15
16namespace Chaos
17{
18struct FMTDInfo;
19
21{
22public:
28
33
34 // Returns a winding order multiplier used in the manifold clipping and required when we have negative scales
36 {
37 return 1.0f;
38 }
39
40
41protected:
43};
44
45template <typename TConcrete>
47{
48public:
49 using T = typename TConcrete::TType;
50 using TType = T;
51 static constexpr int d = TConcrete::D;
52 static constexpr int D = d;
54
56
57 //needed for serialization
63
67 {
68 ensure(IsInstanced(MObject->GetType()) == false); //cannot have an instance of an instance
69 this->bIsConvex = MObject->IsConvex();
70 this->bDoCollide = MObject->GetDoCollide();
72 SetMargin(OuterMargin + MObject->GetMarginf());
73 }
74
78 {
79 ensure(IsInstanced(MObject->GetType()) == false); //cannot have an instance of an instance
80 this->bIsConvex = MObject->IsConvex();
81 this->bDoCollide = MObject->GetDoCollide();
83 SetMargin(OuterMargin + MObject->GetMarginf());
84 }
85
89 {
90 ensureMsgf((IsScaled(MObject->GetType()) == false), TEXT("Scaled objects should not contain each other."));
91 ensureMsgf((IsInstanced(MObject->GetType()) == false), TEXT("Scaled objects should not contain instances."));
92 this->bIsConvex = MObject->IsConvex();
93 this->bDoCollide = MObject->GetDoCollide();
94 this->OuterMargin = Other.OuterMargin;
95 SetMargin(Other.GetMarginf());
96 }
97
99 {
100 return TConcrete::StaticType() | ImplicitObjectType::IsInstanced;
101 }
102
104 {
106 }
107
109 {
110 return MObject.GetReference();
111 }
112
113 UE_DEPRECATED(5.6, "Use GetRadiusf instead")
114 virtual FReal GetRadius() const override
115 {
116 return MObject->GetRadiusf();
117 }
118
119 virtual FRealSingle GetRadiusf() const override
120 {
121 return MObject->GetRadiusf();
122 }
123
124 bool GetDoCollide() const
125 {
126 return MObject->GetDoCollide();
127 }
128
129 virtual FReal PhiWithNormal(const FVec3& X, FVec3& Normal) const override
130 {
131 return MObject->PhiWithNormal(X, Normal);
132 }
133
134 virtual bool Raycast(const FVec3& StartPoint, const FVec3& Dir, const FReal Length, const FReal Thickness, FReal& OutTime, FVec3& OutPosition, FVec3& OutNormal, int32& OutFaceIndex) const override
135 {
136 return MObject->Raycast(StartPoint, Dir, Length, Thickness, OutTime, OutPosition, OutNormal, OutFaceIndex);
137 }
138
139 virtual void Serialize(FChaosArchive& Ar) override
140 {
143 Ar << MObject;
144 }
145
147 {
148 return MObject->FindMostOpposingFace(Position, UnitDir, HintFaceIndex, SearchDist);
149 }
150
152 {
153 return MObject->FindGeometryOpposingNormal(DenormDir, HintFaceIndex, OriginalNormal);
154 }
155
156 virtual bool Overlap(const FVec3& Point, const FReal Thickness) const override
157 {
158 return MObject->Overlap(Point, Thickness);
159 }
160
161 // The support position from the specified direction
162 FORCEINLINE_DEBUGGABLE FVec3 Support(const FVec3& Direction, const FReal Thickness, int32& VertexIndex) const
163 {
164 return MObject->Support(Direction, Thickness, VertexIndex);
165 }
166
167 // this shouldn't be called, but is required until we remove the explicit function implementations in CollisionResolution.cpp
168 FORCEINLINE_DEBUGGABLE FVec3 SupportScaled(const FVec3& Direction, const T Thickness, const FVec3& Scale, int32& VertexIndex) const
169 {
170 return MObject->SupportScaled(Direction, Thickness, Scale, VertexIndex);
171 }
172
173 // The support position from the specified direction, if the shape is reduced by the margin
175 {
176 return MObject->SupportCore(Direction, InMargin, OutSupportDelta, VertexIndex);
177 }
178
187
188 virtual const FAABB3 BoundingBox() const override
189 {
190 return MObject->BoundingBox();
191 }
192
193 const ObjectType Object() const { return MObject; }
194
195 virtual uint32 GetTypeHash() const override
196 {
197 return MObject->GetTypeHash();
198 }
199
200 virtual EImplicitObjectType GetNestedType() const override
201 {
202 return MObject->GetNestedType();
203 }
204
206 {
208 }
209
210 virtual Chaos::FImplicitObjectPtr CopyGeometryWithScale(const FVec3& Scale) const override;
211
212 virtual FString ToString() const override
213 {
214 return FString::Printf(TEXT("Instanced %s, Margin %f"), *MObject->ToString(), GetMarginf());
215 }
216
218 {
219 if constexpr (std::is_same_v<TConcrete,FImplicitObject>)
220 {
221 //can cast any instanced to ImplicitObject base
222 check(IsInstanced(Obj.GetType()));
223 }
224 else
225 {
226 check(StaticType() == Obj.GetType());
227 }
228 return static_cast<const TImplicitObjectInstanced<TConcrete>&>(Obj);
229 }
230
232 {
233 if constexpr (std::is_same_v<TConcrete, FImplicitObject>)
234 {
235 //can cast any scaled to ImplicitObject base
236 return IsInstanced(Obj.GetType()) ? static_cast<const TImplicitObjectInstanced<TConcrete>*>(&Obj) : nullptr;
237 }
238 else
239 {
240 return StaticType() == Obj.GetType() ? static_cast<const TImplicitObjectInstanced<TConcrete>*>(&Obj) : nullptr;
241 }
242 }
243
245 {
246 if constexpr (std::is_same_v<TConcrete, FImplicitObject>)
247 {
248 //can cast any scaled to ImplicitObject base
249 return IsInstanced(Obj.GetType()) ? static_cast<TImplicitObjectInstanced<TConcrete>*>(&Obj) : nullptr;
250 }
251 else
252 {
253 return StaticType() == Obj.GetType() ? static_cast<TImplicitObjectInstanced<TConcrete>*>(&Obj) : nullptr;
254 }
255 }
256
258 template <typename QueryGeomType>
259 bool LowLevelSweepGeom(const QueryGeomType& B, const TRigidTransform<T, d>& BToATM, const TVector<T, d>& LocalDir, const T Length, T& OutTime, TVector<T, d>& LocalPosition, TVector<T, d>& LocalNormal, int32& OutFaceIndex, TVector<T, d>& OutFaceNormal, T Thickness = 0, bool bComputeMTD = false) const
260 {
261 return MObject->SweepGeom(B, BToATM, LocalDir, Length, OutTime, LocalPosition, LocalNormal, OutFaceIndex, OutFaceNormal, Thickness, bComputeMTD);
262 }
263
265 template <typename QueryGeomType>
266 bool LowLevelOverlapGeom(const QueryGeomType& B,const TRigidTransform<T,d>& BToATM,T Thickness = 0, FMTDInfo* OutMTD = nullptr) const
267 {
268 return MObject->OverlapGeom(B,BToATM,Thickness, OutMTD);
269 }
270
271 template <typename QueryGeomType>
272 bool GJKContactPoint(const QueryGeomType& A, const FRigidTransform3& AToBTM, const FReal Thickness, FVec3& Location, FVec3& Normal, FReal& Penetration, int32& FaceIndex) const
273 {
274 return MObject->GJKContactPoint(A, AToBTM, Thickness, Location, Normal, Penetration, FaceIndex);
275 }
276
278 {
279 return MObject->GetMaterialIndex(HintIndex);
280 }
281
282 // Get the index of the plane that most opposes the normal
284 {
285 return MObject->GetMostOpposingPlane(Normal);
286 }
287
288 // Get the nearest point on an edge of the specified face
290 {
291 return MObject->GetClosestEdge(PlaneIndex, Position, OutEdgePos0, OutEdgePos1);
292 }
293
294 // Get the nearest point on an edge of the specified face
296 {
297 return MObject->GetClosestEdgePosition(PlaneIndex, Position);
298 }
299
304
305 // Get an array of all the plane indices that belong to a vertex (up to MaxVertexPlanes).
306 // Returns the number of planes found.
308 {
309 return MObject->FindVertexPlanes(VertexIndex, OutVertexPlanes, MaxVertexPlanes);
310 }
311
312 // Get up to the 3 plane indices that belong to a vertex
313 // Returns the number of planes found.
315 {
316 return MObject->GetVertexPlanes3(VertexIndex, PlaneIndex0, PlaneIndex1, PlaneIndex2);
317 }
318
319 // The number of vertices that make up the corners of the specified face
320 int32 NumPlaneVertices(int32 PlaneIndex) const
321 {
322 return MObject->NumPlaneVertices(PlaneIndex);
323 }
324
325 // Get the vertex index of one of the vertices making up the corners of the specified face
327 {
328 return MObject->GetPlaneVertex(PlaneIndex, PlaneVertexIndex);
329 }
330
332 {
333 return MObject->GetEdgeVertex(EdgeIndex, EdgeVertexIndex);
334 }
335
337 {
338 return MObject->GetEdgePlane(EdgeIndex, EdgePlaneIndex);
339 }
340
342 {
343 return MObject->NumPlanes();
344 }
345
347 {
348 return MObject->NumEdges();
349 }
350
352 {
353 return MObject->NumVertices();
354 }
355
356 // Get the plane at the specified index (e.g., indices from FindVertexPlanes)
358 {
359 return MObject->GetPlane(FaceIndex);
360 }
361
363 {
364 MObject->GetPlaneNX(FaceIndex, OutN, OutX);
365 }
366
367 // Get the vertex at the specified index (e.g., indices from GetPlaneVertexs)
368 const FVec3 GetVertex(int32 VertexIndex) const
369 {
370 return MObject->GetVertex(VertexIndex);
371 }
372
373 const FVec3 GetCenterOfMass() const
374 {
375 return MObject->GetCenterOfMass();
376 }
377
379 {
380 return GetRotationOfMass();
381 }
382
384 {
385 return MObject->GetInertiaTensor(Mass);
386 }
387
388protected:
390
395};
396
398{
399public:
401 : FImplicitObject(Flags, InType | ImplicitObjectType::IsScaled)
402 , MScale(1)
403 , MInvScale(1)
404 , OuterMargin(0.0f)
405 , MLocalBoundingBox(FAABB3::EmptyAABB())
406 {
407 }
408
413
414 // Returns a winding order multiplier used in the manifold clipping and required when we have negative scales
416 {
418 return SignVector.X * SignVector.Y * SignVector.Z;
419 }
420
421 // UE_DEPRECATED(5.6, "Use GetScalef instead")
422 const FVec3 GetScale() const
423 {
424 return FVec3(MScale);
425 }
426
427 // UE_DEPRECATED(5.6, "Use GetInvScalef instead")
428 const FVec3 GetInvScale() const
429 {
430 return FVec3(MInvScale);
431 }
432
433 virtual const FAABB3 BoundingBox() const override
434 {
435 return MLocalBoundingBox;
436 }
437
438protected:
441 FRealSingle OuterMargin; //Allows us to inflate the instance before the scale is applied. This is useful when sweeps need to apply a non scale on a geometry with uniform thickness
443};
444
445template<typename TConcrete, bool bInstanced = true>
447{
448public:
449 using T = typename TConcrete::TType;
450 using TType = T;
451 static constexpr int d = TConcrete::D;
452 static constexpr int D = d;
453
456
457 using ObjectTypeDeprecated = std::conditional_t<bInstanced, TSerializablePtr<TConcrete>, TUniquePtr<TConcrete>>;
458
459 UE_DEPRECATED(5.4, "Constructor no longer used anymore")
465
466 UE_DEPRECATED(5.4, "Constructor no longer used anymore")
472
473 UE_DEPRECATED(5.4, "Constructor no longer used anymore")
479
481 : FImplicitObjectScaled(EImplicitObject::HasBoundingBox, Object->GetType())
482 , MObject(Object)
483 {
484 InitScaledImplicit(Scale, FRealSingle(InMargin));
485 }
486
488 : FImplicitObjectScaled(EImplicitObject::HasBoundingBox, Object->GetType())
489 , MObject(Object)
490 {
491 // Transient if raw pointer not already stored in a ref counted one
492 if(Object && (Object->GetRefCount() == 1))
493 {
494 Object->MakePersistent();
495 }
496 InitScaledImplicit(Scale, FRealSingle(InMargin));
497 }
498
501 : FImplicitObjectScaled(EImplicitObject::HasBoundingBox, Other.MObject->GetType() | ImplicitObjectType::IsScaled)
502 , MObject(MoveTemp(Other.MObject))
503 {
504 ensureMsgf((IsScaled(MObject->GetType()) == false), TEXT("Scaled objects should not contain each other."));
505 ensureMsgf((IsInstanced(MObject->GetType()) == false), TEXT("Scaled objects should not contain instances."));
506 this->bIsConvex = MObject->IsConvex();
507 this->bDoCollide = MObject->GetDoCollide();
508 this->OuterMargin = Other.OuterMargin;
509 this->MScale = Other.MScale;
510 this->MInvScale = Other.MInvScale;
511 this->OuterMargin = Other.OuterMargin;
512 this->MLocalBoundingBox = Other.MLocalBoundingBox;
513 SetMargin(Other.GetMarginf());
514 }
516
518 {
519 return TConcrete::StaticType() | ImplicitObjectType::IsScaled;
520 }
521
523 {
524 if constexpr (std::is_same_v<TConcrete, FImplicitObject>)
525 {
526 //can cast any scaled to ImplicitObject base
527 check(IsScaled(Obj.GetType()));
528 }
529 else
530 {
531 check(StaticType() == Obj.GetType());
532 }
533 return static_cast<const TImplicitObjectScaled<TConcrete>&>(Obj);
534 }
535
537 {
538 if constexpr (std::is_same_v<TConcrete, FImplicitObject>)
539 {
540 //can cast any scaled to ImplicitObject base
541 check(IsScaled(Obj.GetType()));
542 }
543 else
544 {
545 check(StaticType() == Obj.GetType());
546 }
547 return static_cast<TImplicitObjectScaled<TConcrete>&>(Obj);
548 }
549
551 {
552 if constexpr (std::is_same_v<TConcrete, FImplicitObject>)
553 {
554 //can cast any scaled to ImplicitObject base
555 return IsScaled(Obj.GetType()) ? static_cast<const TImplicitObjectScaled<TConcrete>*>(&Obj) : nullptr;
556 }
557 else
558 {
559 return StaticType() == Obj.GetType() ? static_cast<const TImplicitObjectScaled<TConcrete>*>(&Obj) : nullptr;
560 }
561 }
562
564 {
565 if constexpr (std::is_same_v<TConcrete, FImplicitObject>)
566 {
567 //can cast any scaled to ImplicitObject base
568 return IsScaled(Obj.GetType()) ? static_cast<TImplicitObjectScaled<TConcrete>*>(&Obj) : nullptr;
569 }
570 else
571 {
572 return StaticType() == Obj.GetType() ? static_cast<TImplicitObjectScaled<TConcrete>*>(&Obj) : nullptr;
573 }
574 }
575
577 {
578 return MakeSerializable(MObject);
579 }
580
582 {
583 return MObject.GetReference();
584 }
585
586 virtual EImplicitObjectType GetNestedType() const override
587 {
588 return MObject->GetNestedType();
589 }
590
591 virtual FReal GetRadius() const override
592 {
593 return (MObject->GetRadiusf() > 0.0f) ? Margin : 0.0f;
594 }
595
596 virtual FRealSingle GetRadiusf() const override
597 {
598 return (MObject->GetRadiusf() > 0.0f) ? Margin : 0.0f;
599 }
600
601 virtual FReal PhiWithNormal(const FVec3& X, FVec3& Normal) const override
602 {
603 return MObject->PhiWithNormalScaled(X, MScale, Normal);
604 }
605
606 virtual bool Raycast(const FVec3& StartPoint, const FVec3& Dir, const FReal Length, const FReal Thickness, FReal& OutTime, FVec3& OutPosition, FVec3& OutNormal, int32& OutFaceIndex) const override
607 {
608 ensure(Length > 0);
610 ensure(Thickness == 0 || (FMath::IsNearlyEqual(MScale[0], MScale[1]) && FMath::IsNearlyEqual(MScale[0], MScale[2]))); //non uniform turns sphere into an ellipsoid so no longer a raycast and requires a more expensive sweep
611
612 const FVec3 UnscaledStart = MInvScale * StartPoint;
613 const FVec3 UnscaledDirDenorm = MInvScale * Dir;
614 const FReal LengthScale = UnscaledDirDenorm.Size();
615 if (ensure(LengthScale > TNumericLimits<FReal>::Min()))
616 {
617 const FReal LengthScaleInv = FReal(1) / LengthScale;
618 const FReal UnscaledLength = Length * LengthScale;
620
624
625 if (MObject->Raycast(UnscaledStart, UnscaledDir, UnscaledLength, Thickness * MInvScale[0], UnscaledTime, UnscaledPosition, UnscaledNormal, OutFaceIndex))
626 {
627 //We double check that NewTime < Length because of potential precision issues. When that happens we always keep the shortest hit first
628 const FReal NewTime = LengthScaleInv * UnscaledTime;
629 if (NewTime == 0) // Normal/Position output may be uninitialized with TOI 0 so we use ray information for that as the ray origin is likely inside the shape
630 {
631 OutPosition = StartPoint;
632 OutNormal = -Dir;
633 OutTime = NewTime;
634 return true;
635 }
636 else if (NewTime < Length)
637 {
638 OutPosition = MScale * UnscaledPosition;
639 OutNormal = (MInvScale * UnscaledNormal).GetSafeNormal(TNumericLimits<FRealSingle>::Min());
640 OutTime = NewTime;
641 return true;
642 }
643 }
644 }
645
646 return false;
647 }
648
650 template <typename QueryGeomType>
651 bool LowLevelSweepGeom(const QueryGeomType& B, const TRigidTransform<T, d>& BToATM, const TVector<T, d>& LocalDir, const T Length, T& OutTime, TVector<T, d>& LocalPosition, TVector<T, d>& LocalNormal, int32& OutFaceIndex, TVector<T, d>& OutFaceNormal, T Thickness = 0, bool bComputeMTD = false) const
652 {
653 ensure(Length >= 0);
654 ensure(FMath::IsNearlyEqual(LocalDir.SizeSquared(), (T)1, (T)UE_KINDA_SMALL_NUMBER));
655 ensure(Thickness == 0 || (FMath::IsNearlyEqual(MScale[0], MScale[1]) && FMath::IsNearlyEqual(MScale[0], MScale[2])));
656
657 const TVector<T, d> UnscaledDirDenorm = MInvScale * LocalDir;
658 const T LengthScale = UnscaledDirDenorm.Size();
659 if (ensure(LengthScale > TNumericLimits<T>::Min()))
660 {
661 const T LengthScaleInv = 1.f / LengthScale;
662 const T UnscaledLength = Length * LengthScale;
664
668
669 TRigidTransform<T, d> BToATMNoScale(BToATM.GetLocation() * FVec3(MInvScale), BToATM.GetRotation());
670
671 if (MObject->SweepGeom(B, BToATMNoScale, UnscaledDir, UnscaledLength, UnscaledTime, UnscaledPosition, UnscaledNormal, OutFaceIndex, OutFaceNormal, Thickness, bComputeMTD, MScale))
672 {
673 const T NewTime = LengthScaleInv * UnscaledTime;
674 //We double check that NewTime < Length because of potential precision issues. When that happens we always keep the shortest hit first
675 if (NewTime < Length)
676 {
677 OutTime = NewTime;
678 LocalPosition = MScale * UnscaledPosition;
679 LocalNormal = (MInvScale * UnscaledNormal).GetSafeNormal();
680 return true;
681 }
682 }
683 }
684
685 return false;
686 }
687
689 template <typename QueryGeomType>
690 bool LowLevelSweepGeomCCD(const QueryGeomType& B, const TRigidTransform<T, d>& BToATM, const TVector<T, d>& LocalDir, const T Length, const FReal IgnorePenetration, const FReal TargetPenetration, T& OutTOI, T& OutPhi, TVector<T, d>& LocalPosition, TVector<T, d>& LocalNormal, int32& OutFaceIndex, TVector<T, d>& OutFaceNormal) const
691 {
692 ensure(Length > 0);
693 ensure(FMath::IsNearlyEqual(LocalDir.SizeSquared(), (T)1, (T)UE_KINDA_SMALL_NUMBER));
694
695 const TVector<T, d> UnscaledDirDenorm = MInvScale * LocalDir;
696 const T LengthScale = UnscaledDirDenorm.Size();
697 if (ensure(LengthScale > TNumericLimits<T>::Min()))
698 {
699 const T LengthScaleInv = 1.f / LengthScale;
700 const T UnscaledLength = Length * LengthScale;
702
705 T TOI;
706 T Phi;
707
708 TRigidTransform<T, d> BToATMNoScale(BToATM.GetLocation() * FVec3(MInvScale), BToATM.GetRotation());
709
710 if (MObject->SweepGeomCCD(B, BToATMNoScale, UnscaledDir, UnscaledLength, IgnorePenetration, TargetPenetration, TOI, Phi, UnscaledPosition, UnscaledNormal, OutFaceIndex, OutFaceNormal, MScale))
711 {
712 if (TOI < FReal(1))
713 {
714 OutTOI = TOI;
715 OutPhi = Phi;
716 LocalPosition = MScale * UnscaledPosition;
717 LocalNormal = (MInvScale * UnscaledNormal).GetSafeNormal();
718 return true;
719 }
720 }
721 }
722
723 return false;
724 }
725
726 template <typename QueryGeomType>
727 bool GJKContactPoint(const QueryGeomType& A, const FRigidTransform3& AToBTM, const FReal Thickness, FVec3& Location, FVec3& Normal, FReal& Penetration, int32& FaceIndex) const
728 {
729 TRigidTransform<T, d> AToBTMNoScale(AToBTM.GetLocation() * FVec3(MInvScale), AToBTM.GetRotation());
730
731 // Thickness is a culling distance which cannot be non-uniformly scaled. This gets passed into the ImplicitObject API unscaled so that
732 // if can do the right thing internally if possible, but it makes the API a little confusing. (This is only exists used TriMesh and Heightfield.)
733 // See FTriangleMeshImplicitObject::GJKContactPointImp
734 const FReal UnscaledThickness = Thickness;
735
736 auto ScaledA = MakeScaledHelper(A, MInvScale);
737 return MObject->GJKContactPoint(ScaledA, AToBTMNoScale, UnscaledThickness, Location, Normal, Penetration, FaceIndex, MScale);
738 }
739
741 template <typename QueryGeomType>
742 bool LowLevelOverlapGeom(const QueryGeomType& B, const TRigidTransform<T, d>& BToATM, T Thickness = 0, FMTDInfo* OutMTD = nullptr) const
743 {
744 ensure(Thickness == 0 || (FMath::IsNearlyEqual(MScale[0], MScale[1]) && FMath::IsNearlyEqual(MScale[0], MScale[2])));
745
746 auto ScaledB = MakeScaledHelper(B, MInvScale);
747 TRigidTransform<T, d> BToATMNoScale(BToATM.GetLocation() * FVec3(MInvScale), BToATM.GetRotation());
748 return MObject->OverlapGeom(ScaledB, BToATMNoScale, Thickness, OutMTD, MScale);
749 }
750
751 // Get the index of the plane that most opposes the normal
753 {
754 return MObject->GetMostOpposingPlaneScaled(Normal, MScale);
755 }
756
757 // Get the nearest point on an edge of the specified face
759 {
760 FVec3 EdgePos = MObject->GetClosestEdge(PlaneIndex, MInvScale * Position, OutEdgePos0, OutEdgePos1);
763 return EdgePos * MScale;
764 }
765
766 // Get the nearest point on an edge of the specified face
768 {
769 return MObject->GetClosestEdgePosition(PlaneIndex, MInvScale * Position) * MScale;
770 }
771
773 {
774 return MObject->GetClosestEdgeVertices(PlaneIndex, MInvScale * Position, OutVertexIndex0, OutVertexIndex1);
775 }
776
777 // Get an array of all the plane indices that belong to a vertex (up to MaxVertexPlanes).
778 // Returns the number of planes found.
780 {
781 return MObject->FindVertexPlanes(VertexIndex, OutVertexPlanes, MaxVertexPlanes);
782 }
783
784 // Get up to the 3 plane indices that belong to a vertex
785 // Returns the number of planes found.
787 {
788 return MObject->GetVertexPlanes3(VertexIndex, PlaneIndex0, PlaneIndex1, PlaneIndex2);
789 }
790
791 // The number of vertices that make up the corners of the specified face
792 int32 NumPlaneVertices(int32 PlaneIndex) const
793 {
794 return MObject->NumPlaneVertices(PlaneIndex);
795 }
796
797 // Get the vertex index of one of the vertices making up the corners of the specified face
799 {
800 return MObject->GetPlaneVertex(PlaneIndex, PlaneVertexIndex);
801 }
802
804 {
805 return MObject->GetEdgeVertex(EdgeIndex, EdgeVertexIndex);
806 }
807
809 {
810 return MObject->GetEdgePlane(EdgeIndex, EdgePlaneIndex);
811 }
812
814 {
815 return MObject->NumPlanes();
816 }
817
819 {
820 return MObject->NumEdges();
821 }
822
824 {
825 return MObject->NumVertices();
826 }
827
828 // Get the plane at the specified index (e.g., indices from FindVertexPlanes)
830 {
831 const TPlaneConcrete<FReal, 3> InnerPlane = MObject->GetPlane(FaceIndex);
832 return TPlaneConcrete<FReal, 3>::MakeScaledUnsafe(InnerPlane, MScale, MInvScale); // "Unsafe" means scale must have no zeros
833 }
834
836 {
838 MObject->GetPlaneNX(FaceIndex, InnerN, InnerX);
839 TPlaneConcrete<FReal>::MakeScaledUnsafe(InnerN, InnerX, MScale, MInvScale, OutN, OutX); // "Unsafe" means scale must have no zeros
840 }
841
842 // Get the vertex at the specified index (e.g., indices from GetPlaneVertex)
843 const FVec3 GetVertex(int32 VertexIndex) const
844 {
845 const FVec3 InnerVertex = MObject->GetVertex(VertexIndex);
846 return MScale * InnerVertex;
847 }
848
849
851 {
852 return MObject->FindMostOpposingFaceScaled(Position, UnitDir, HintFaceIndex, SearchDist, MScale);
853 }
854
856 {
857 // @todo(chaos): we need a virtual FindGeometryOpposingNormal. Some types (Convex, Box) can just return the
858 // normal from the face index without needing calculating the unscaled normals.
860
861 // Get unscaled dir and normal
868 : FVec3(0, 0, 1);
869
870 // Compute final normal
871 const FVec3 LocalNormal = MObject->FindGeometryOpposingNormal(LocalDenormDir, HintFaceIndex, LocalOriginalNormal);
874 if (NormalLength == 0)
875 {
876 CHAOS_ENSURE(false);
878 }
879
880 return Normal;
881 }
882
883 virtual bool Overlap(const FVec3& Point, const FReal Thickness) const override
884 {
886
887 // TODO: consider alternative that handles thickness scaling properly in 3D, only works for uniform scaling right now
888 const FReal UnscaleThickness = MInvScale[0] * Thickness;
889
890 return MObject->Overlap(UnscaledPoint, UnscaleThickness);
891 }
892
893 virtual Pair<FVec3, bool> FindClosestIntersectionImp(const FVec3& StartPoint, const FVec3& EndPoint, const FReal Thickness) const override
894 {
895 ensure(OuterMargin == 0); //not supported: do we care?
896 const FVec3 UnscaledStart = MInvScale * StartPoint;
897 const FVec3 UnscaledEnd = MInvScale * EndPoint;
898 auto ClosestIntersection = MObject->FindClosestIntersection(UnscaledStart, UnscaledEnd, Thickness);
899 if (ClosestIntersection.Second)
900 {
902 }
903 return ClosestIntersection;
904 }
905
906 virtual int32 FindClosestFaceAndVertices(const FVec3& Position, TArray<FVec3>& FaceVertices, FReal SearchDist = FReal(0.01)) const override
907 {
909 const FReal UnscaledSearchDist = SearchDist * MInvScale.Max(); //this is not quite right since it's no longer a sphere, but the whole thing is fuzzy anyway
910 int32 FaceIndex = MObject->FindClosestFaceAndVertices(UnscaledPoint, FaceVertices, UnscaledSearchDist);
911 if (FaceIndex != INDEX_NONE)
912 {
913 for (FVec3& Vec : FaceVertices)
914 {
915 Vec = Vec * MScale;
916 }
917 }
918 return FaceIndex;
919 }
920
921
922 FORCEINLINE_DEBUGGABLE FVec3 Support(const FVec3& Direction, const FReal Thickness, int32& VertexIndex) const
923 {
924 // Support_obj(dir) = pt => for all x in obj, pt \dot dir >= x \dot dir
925 // We want Support_objScaled(dir) = Support_obj(dir') where dir' is some modification of dir so we can use the unscaled support function
926 // If objScaled = Aobj where A is a transform, then we can say Support_objScaled(dir) = pt => for all x in obj, pt \dot dir >= Ax \dot dir
927 // But this is the same as pt \dot dir >= dir^T Ax = (dir^TA) x = (A^T dir)^T x
928 //So let dir' = A^T dir.
929 //Since we only support scaling on the principal axes A is a diagonal (and therefore symmetric) matrix and so a simple component wise multiplication is sufficient
930 const FVec3 UnthickenedPt = MObject->Support(Direction * MScale, 0.0f, VertexIndex) * MScale;
931 return Thickness > 0 ? FVec3(UnthickenedPt + Direction.GetSafeNormal() * Thickness) : UnthickenedPt;
932 }
933
935 {
936 return MObject->SupportCoreScaled(Direction, InMargin, MScale, OutSupportDelta, VertexIndex);
937 }
938
940 {
942 VectorStoreFloat3(Direction, &DirectionVec3);
943 int32 VertexIndex = INDEX_NONE;
944 FVec3 SupportVert = MObject->SupportCoreScaled(DirectionVec3, InMargin, MScale, nullptr, VertexIndex);
946 }
947
948 // UE_DEPRECATED(5.6, "Use SetScale(FVec3f) in single precision instead")
949 void SetScale(const FVec3& Scale)
950 {
952 }
953
954 void SetScale(const FVec3f& Scale)
955 {
956 constexpr FRealSingle MinMagnitude = 1e-6f;
957 for (int Axis = 0; Axis < 3; ++Axis)
958 {
959 if (!CHAOS_ENSURE(FMath::Abs(Scale[Axis]) >= MinMagnitude))
960 {
962 }
963 else
964 {
965 MScale[Axis] = Scale[Axis];
966 }
967
968 MInvScale[Axis] = 1 / MScale[Axis];
969 }
970 SetMargin(OuterMargin + MScale[0] * MObject->GetMarginf());
971 UpdateBounds();
972 }
973
974 const FReal GetVolume() const
975 {
976 return FMath::Abs(MScale.X * MScale.Y * MScale.Z) * MObject->GetVolume();
977 }
978
979 const FVec3 GetCenterOfMass() const
980 {
981 return MScale * MObject->GetCenterOfMass();
982 }
983
985 {
986 return MObject->GetRotationOfMass();
987 }
988
990 {
991 return Utilities::ScaleInertia(MObject->GetInertiaTensor(Mass), MScale, false);
992 }
993
994 const ObjectType Object() const { return MObject; }
995
996 UE_DEPRECATED(5.4, "Please use Object instead")
997 TSharedPtr<TConcrete, ESPMode::ThreadSafe> GetSharedObject() const { check(false); return nullptr; }
998
1012
1013 virtual uint32 GetTypeHash() const override
1014 {
1015 return HashCombine(MObject->GetTypeHash(), UE::Math::GetTypeHash(MScale));
1016 }
1017
1018 virtual uint16 GetMaterialIndex(uint32 HintIndex) const override
1019 {
1020 return MObject->GetMaterialIndex(HintIndex);
1021 }
1022
1024 {
1025 return Chaos::FImplicitObjectPtr(CopyHelper(this));
1026 }
1027
1029 {
1030 TImplicitObjectScaled<TConcrete, bInstanced>* Obj = CopyHelper(this);
1031 Obj->SetScale(Obj->GetScale() * Scale);
1032 return Chaos::FImplicitObjectPtr(Obj);
1033 }
1034
1035 virtual FString ToString() const override
1036 {
1037 return FString::Printf(TEXT("Scaled %s, Scale: [%f, %f, %f], Margin: %f"), *MObject->ToString(), MScale.X, MScale.Y, MScale.Z, GetMarginf());
1038 }
1039
1040private:
1041 ObjectType MObject;
1042
1043 //needed for serialization
1045 : FImplicitObjectScaled(EImplicitObject::HasBoundingBox, StaticType())
1046 {}
1047 friend FImplicitObject; //needed for serialization
1048
1050 {
1051 return new TImplicitObjectScaled<TConcrete, true>(Obj->MObject, Obj->MScale, Obj->OuterMargin);
1052 }
1053
1055 {
1056 Chaos::FImplicitObjectPtr DuplicatedShape = Obj->MObject->CopyGeometry();
1057
1058 // We know the actual type of the underlying object pointer so we can cast it to the required type to make a copy of this implicit
1059 return new TImplicitObjectScaled<TConcrete, false>(reinterpret_cast<TRefCountPtr<TConcrete>&&>(DuplicatedShape), Obj->MScale, Obj->OuterMargin);
1060 }
1061
1062 void InitScaledImplicit(const FVec3& Scale, FRealSingle InMargin = 0)
1063 {
1064 ensureMsgf((IsScaled(MObject->GetType()) == false), TEXT("Scaled objects should not contain each other."));
1065 ensureMsgf((IsInstanced(MObject->GetType()) == false), TEXT("Scaled objects should not contain instances."));
1066 switch (MObject->GetType())
1067 {
1070 check(false); //scale is only supported for concrete types like sphere, capsule, convex, levelset, etc... Nothing that contains other objects
1071 default:
1072 break;
1073 }
1074 this->bIsConvex = MObject->IsConvex();
1075 this->bDoCollide = MObject->GetDoCollide();
1076 this->OuterMargin = InMargin;
1077 SetScale(Scale);
1078 }
1079
1080 void UpdateBounds()
1081 {
1082 const FAABB3 UnscaledBounds = MObject->BoundingBox();
1083 const FVec3 Vector1 = UnscaledBounds.Min() * MScale;
1084 MLocalBoundingBox = FAABB3(Vector1, Vector1); //need to grow it out one vector at a time in case scale is negative
1085 const FVec3 Vector2 = UnscaledBounds.Max() * MScale;
1087 }
1088
1089 template <typename QueryGeomType>
1090 static auto MakeScaledHelper(const QueryGeomType& B, const TVector<T,d>& InvScale )
1091 {
1092 return TImplicitObjectScaled<QueryGeomType,true>(const_cast<QueryGeomType*>(&B), InvScale);
1093 }
1094
1095 template <typename QueryGeomType>
1096 static auto MakeScaledHelper(const TImplicitObjectScaled<QueryGeomType>& B, const TVector<T,d>& InvScale)
1097 {
1098 //if scaled of scaled just collapse into one scaled
1099 TImplicitObjectScaled<QueryGeomType> ScaledB(B.Object(), InvScale * B.GetScale());
1100 return ScaledB;
1101 }
1102
1103};
1104
1105template <typename TConcrete>
1107
1108template <typename T, int d>
1110
1111template<typename TConcrete>
1116
1117template<>
1119{
1120 // Is InType derived from FImplicitObjectInstanced
1122 {
1124 }
1125};
1126
1127template<>
1129{
1130 // Is InType derived from FImplicitObjectScaled
1132 {
1134 }
1135};
1136
1137
1142template<typename T>
1144{
1145 OutScale = FVec3(1);
1146 OutMargin = FReal(0);
1147
1148 if (const TImplicitObjectScaled<T>* ScaledImplicit = Implicit.template GetObject<TImplicitObjectScaled<T>>())
1149 {
1150 OutScale = ScaledImplicit->GetScale();
1151 OutMargin = FReal(ScaledImplicit->GetMarginf());
1152 return ScaledImplicit->GetUnscaledObject();
1153 }
1154 else if (const TImplicitObjectInstanced<T>* InstancedImplicit = Implicit.template GetObject<TImplicitObjectInstanced<T>>())
1155 {
1156 OutMargin = FReal(InstancedImplicit->GetMarginf());
1157 return InstancedImplicit->GetInstancedObject();
1158 }
1159 else if (const T* RawImplicit = Implicit.template GetObject<T>())
1160 {
1161 OutMargin = FReal(RawImplicit->GetMarginf());
1162 return RawImplicit;
1163 }
1164 else
1165 {
1166 return nullptr;
1167 }
1168}
1169}
1170
1171
1172
#define FORCEINLINE
Definition AndroidPlatform.h:140
#define check(expr)
Definition AssertionMacros.h:314
#define ensureMsgf( InExpression, InFormat,...)
Definition AssertionMacros.h:465
#define ensure( InExpression)
Definition AssertionMacros.h:464
#define CHAOS_ENSURE(Condition)
Definition ChaosCheck.h:22
@ INDEX_NONE
Definition CoreMiscDefines.h:150
#define FORCEINLINE_DEBUGGABLE
Definition CoreMiscDefines.h:74
#define UE_DEPRECATED(Version, Message)
Definition CoreMiscDefines.h:302
#define TEXT(x)
Definition Platform.h:1272
FPlatformTypes::int32 int32
A 32-bit signed integer.
Definition Platform.h:1125
UE_FORCEINLINE_HINT TSharedRef< CastToType, Mode > StaticCastSharedRef(TSharedRef< CastFromType, Mode > const &InSharedRef)
Definition SharedPointer.h:127
ESPMode
Definition SharedPointerFwd.h:12
constexpr uint32 HashCombine(uint32 A, uint32 C)
Definition TypeHash.h:36
FORCEINLINE VectorRegister4Float MakeVectorRegister(uint32 X, uint32 Y, uint32 Z, uint32 W)
Definition UnrealMathFPU.h:195
FORCEINLINE void VectorStoreFloat3(const VectorRegister4Float &Vec, float *Dst)
Definition UnrealMathFPU.h:594
FORCEINLINE VectorRegister4Float MakeVectorRegisterFloatFromDouble(const VectorRegister4Double &Vec4d)
Definition UnrealMathFPU.h:262
#define UE_SMALL_NUMBER
Definition UnrealMathUtility.h:130
#define UE_KINDA_SMALL_NUMBER
Definition UnrealMathUtility.h:131
UE_INTRINSIC_CAST UE_REWRITE constexpr std::remove_reference_t< T > && MoveTemp(T &&Obj) noexcept
Definition UnrealTemplate.h:520
uint16_t uint16
Definition binka_ue_file_header.h:7
uint32_t uint32
Definition binka_ue_file_header.h:6
Definition ChaosArchive.h:364
Definition ChaosArchive.h:167
Definition ImplicitObjectScaled.h:21
virtual TSerializablePtr< FImplicitObject > GetInnerObject() const
Definition ImplicitObjectScaled.h:29
FImplicitObjectInstanced(int32 Flags, EImplicitObjectType InType)
Definition ImplicitObjectScaled.h:23
FRealSingle OuterMargin
Definition ImplicitObjectScaled.h:42
FORCEINLINE FReal GetWindingOrder() const
Definition ImplicitObjectScaled.h:35
Definition ImplicitObjectScaled.h:398
FAABB3 MLocalBoundingBox
Definition ImplicitObjectScaled.h:442
const FVec3 GetInvScale() const
Definition ImplicitObjectScaled.h:428
FVec3f MInvScale
Definition ImplicitObjectScaled.h:440
FVec3f MScale
Definition ImplicitObjectScaled.h:439
const FVec3 GetScale() const
Definition ImplicitObjectScaled.h:422
virtual TSerializablePtr< FImplicitObject > GetInnerObject() const
Definition ImplicitObjectScaled.h:409
virtual const FAABB3 BoundingBox() const override
Definition ImplicitObjectScaled.h:433
FImplicitObjectScaled(int32 Flags, EImplicitObjectType InType)
Definition ImplicitObjectScaled.h:400
FRealSingle OuterMargin
Definition ImplicitObjectScaled.h:441
FORCEINLINE FReal GetWindingOrder() const
Definition ImplicitObjectScaled.h:415
Definition ImplicitObject.h:111
FRealSingle Margin
Definition ImplicitObject.h:571
bool HasBoundingBox() const
Definition ImplicitObject.h:275
EImplicitObjectType Type
Definition ImplicitObject.h:585
bool bDoCollide
Definition ImplicitObject.h:573
virtual FName GetTypeName() const
Definition ImplicitObject.h:414
CHAOS_API void SerializeImp(FArchive &Ar)
Definition ImplicitObject.cpp:337
CHAOS_API EImplicitObjectType GetType() const
Definition ImplicitObject.cpp:67
void SetMargin(FReal InMargin)
Definition ImplicitObject.h:567
bool bIsConvex
Definition ImplicitObject.h:572
virtual FRealSingle GetMarginf() const
Definition ImplicitObject.h:212
FORCEINLINE const TAABB< T, d > & BoundingBox() const
Definition AABB.h:156
FORCEINLINE void GrowToInclude(const TVector< T, d > &V)
Definition AABB.h:393
static void SerializeAsAABB(FArchive &Ar, TAABB< T, d > &AABB)
Definition Box.h:467
Definition CorePlane.h:12
static FORCEINLINE TCorePlane< T > MakeScaledUnsafe(const TCorePlane< U > &Plane, const TVec3< T > &Scale, const TVec3< T > &InvScale)
Definition CorePlane.h:72
Definition ImplicitObjectScaled.h:47
static constexpr int d
Definition ImplicitObjectScaled.h:51
virtual TSerializablePtr< FImplicitObject > GetInnerObject() const override
Definition ImplicitObjectScaled.h:103
TImplicitObjectInstanced(const ObjectType &&Object, const FReal InMargin=0)
Definition ImplicitObjectScaled.h:64
TImplicitObjectInstanced(const ObjectType &Object, const FReal InMargin=0)
Definition ImplicitObjectScaled.h:75
const TConcrete * GetInstancedObject() const
Definition ImplicitObjectScaled.h:108
typename TConcrete::TType T
Definition ImplicitObjectScaled.h:49
int32 NumPlaneVertices(int32 PlaneIndex) const
Definition ImplicitObjectScaled.h:320
const ObjectType Object() const
Definition ImplicitObjectScaled.h:193
virtual EImplicitObjectType GetNestedType() const override
Definition ImplicitObjectScaled.h:200
virtual Chaos::FImplicitObjectPtr CopyGeometry() const override
Definition ImplicitObjectScaled.h:205
static constexpr EImplicitObjectType StaticType()
Definition ImplicitObjectScaled.h:98
virtual FString ToString() const override
Definition ImplicitObjectScaled.h:212
virtual int32 FindMostOpposingFace(const FVec3 &Position, const FVec3 &UnitDir, int32 HintFaceIndex, FReal SearchDist) const override
Definition ImplicitObjectScaled.h:146
virtual bool Raycast(const FVec3 &StartPoint, const FVec3 &Dir, const FReal Length, const FReal Thickness, FReal &OutTime, FVec3 &OutPosition, FVec3 &OutNormal, int32 &OutFaceIndex) const override
Definition ImplicitObjectScaled.h:134
virtual const FAABB3 BoundingBox() const override
Definition ImplicitObjectScaled.h:188
virtual Chaos::FImplicitObjectPtr CopyGeometryWithScale(const FVec3 &Scale) const override
Definition ImplicitObjectScaled.h:1112
FORCEINLINE_DEBUGGABLE FVec3 SupportCore(const FVec3 &Direction, const FReal InMargin, FReal *OutSupportDelta, int32 &VertexIndex) const
Definition ImplicitObjectScaled.h:174
FORCEINLINE_DEBUGGABLE FVec3 SupportScaled(const FVec3 &Direction, const T Thickness, const FVec3 &Scale, int32 &VertexIndex) const
Definition ImplicitObjectScaled.h:168
T TType
Definition ImplicitObjectScaled.h:50
bool LowLevelOverlapGeom(const QueryGeomType &B, const TRigidTransform< T, d > &BToATM, T Thickness=0, FMTDInfo *OutMTD=nullptr) const
Definition ImplicitObjectScaled.h:266
bool LowLevelSweepGeom(const QueryGeomType &B, const TRigidTransform< T, d > &BToATM, const TVector< T, d > &LocalDir, const T Length, T &OutTime, TVector< T, d > &LocalPosition, TVector< T, d > &LocalNormal, int32 &OutFaceIndex, TVector< T, d > &OutFaceNormal, T Thickness=0, bool bComputeMTD=false) const
Definition ImplicitObjectScaled.h:259
int32 FindVertexPlanes(int32 VertexIndex, int32 *OutVertexPlanes, int32 MaxVertexPlanes) const
Definition ImplicitObjectScaled.h:307
virtual uint16 GetMaterialIndex(uint32 HintIndex) const
Definition ImplicitObjectScaled.h:277
bool GJKContactPoint(const QueryGeomType &A, const FRigidTransform3 &AToBTM, const FReal Thickness, FVec3 &Location, FVec3 &Normal, FReal &Penetration, int32 &FaceIndex) const
Definition ImplicitObjectScaled.h:272
bool GetClosestEdgeVertices(int32 PlaneIndexHint, const FVec3 &Position, int32 &OutVertexIndex0, int32 &OutVertexIndex1) const
Definition ImplicitObjectScaled.h:300
virtual void Serialize(FChaosArchive &Ar) override
Definition ImplicitObjectScaled.h:139
static constexpr int D
Definition ImplicitObjectScaled.h:52
int32 GetVertexPlanes3(int32 VertexIndex, int32 &PlaneIndex0, int32 &PlaneIndex1, int32 &PlaneIndex2) const
Definition ImplicitObjectScaled.h:314
FRotation3 GetRotationOfMass() const
Definition ImplicitObjectScaled.h:378
const FVec3 GetCenterOfMass() const
Definition ImplicitObjectScaled.h:373
int32 GetMostOpposingPlane(const FVec3 &Normal) const
Definition ImplicitObjectScaled.h:283
virtual FName GetTypeName() const
Definition ImplicitObject.h:414
const FVec3 GetVertex(int32 VertexIndex) const
Definition ImplicitObjectScaled.h:368
virtual bool Overlap(const FVec3 &Point, const FReal Thickness) const override
Definition ImplicitObjectScaled.h:156
int32 NumEdges() const
Definition ImplicitObjectScaled.h:346
void GetPlaneNX(const int32 FaceIndex, FVec3 &OutN, FVec3 &OutX) const
Definition ImplicitObjectScaled.h:362
TImplicitObjectInstanced()
Definition ImplicitObjectScaled.h:58
int32 NumVertices() const
Definition ImplicitObjectScaled.h:351
virtual uint32 GetTypeHash() const override
Definition ImplicitObjectScaled.h:195
virtual FReal GetRadius() const override
Definition ImplicitObjectScaled.h:114
int32 GetEdgePlane(int32 EdgeIndex, int32 EdgePlaneIndex) const
Definition ImplicitObjectScaled.h:336
bool GetDoCollide() const
Definition ImplicitObjectScaled.h:124
static const TImplicitObjectInstanced< TConcrete > * AsInstanced(const FImplicitObject &Obj)
Definition ImplicitObjectScaled.h:231
static TImplicitObjectInstanced< TConcrete > * CopyHelper(const TImplicitObjectInstanced< TConcrete > *Obj)
Definition ImplicitObjectScaled.h:391
FVec3 GetClosestEdge(int32 PlaneIndex, const FVec3 &Position, FVec3 &OutEdgePos0, FVec3 &OutEdgePos1) const
Definition ImplicitObjectScaled.h:289
FVec3 GetClosestEdgePosition(int32 PlaneIndex, const FVec3 &Position) const
Definition ImplicitObjectScaled.h:295
static TImplicitObjectInstanced< TConcrete > * AsInstanced(FImplicitObject &Obj)
Definition ImplicitObjectScaled.h:244
virtual FReal PhiWithNormal(const FVec3 &X, FVec3 &Normal) const override
Definition ImplicitObjectScaled.h:129
ObjectType MObject
Definition ImplicitObjectScaled.h:389
const FMatrix33 GetInertiaTensor(const FReal Mass) const
Definition ImplicitObjectScaled.h:383
int32 NumPlanes() const
Definition ImplicitObjectScaled.h:341
static const TImplicitObjectInstanced< TConcrete > & AsInstancedChecked(const FImplicitObject &Obj)
Definition ImplicitObjectScaled.h:217
virtual FRealSingle GetRadiusf() const override
Definition ImplicitObjectScaled.h:119
const TPlaneConcrete< FReal, 3 > GetPlane(int32 FaceIndex) const
Definition ImplicitObjectScaled.h:357
FORCEINLINE_DEBUGGABLE FVec3 Support(const FVec3 &Direction, const FReal Thickness, int32 &VertexIndex) const
Definition ImplicitObjectScaled.h:162
FORCEINLINE_DEBUGGABLE VectorRegister4Float SupportCoreSimd(const VectorRegister4Float &Direction, const FReal InMargin) const
Definition ImplicitObjectScaled.h:179
int32 GetEdgeVertex(int32 EdgeIndex, int32 EdgeVertexIndex) const
Definition ImplicitObjectScaled.h:331
TImplicitObjectInstanced(TImplicitObjectInstanced< TConcrete > &&Other)
Definition ImplicitObjectScaled.h:86
int32 GetPlaneVertex(int32 PlaneIndex, int32 PlaneVertexIndex) const
Definition ImplicitObjectScaled.h:326
virtual FVec3 FindGeometryOpposingNormal(const FVec3 &DenormDir, int32 HintFaceIndex, const FVec3 &OriginalNormal) const override
Definition ImplicitObjectScaled.h:151
Definition ImplicitObjectScaled.h:447
static constexpr int D
Definition ImplicitObjectScaled.h:452
virtual EImplicitObjectType GetNestedType() const override
Definition ImplicitObjectScaled.h:586
bool GJKContactPoint(const QueryGeomType &A, const FRigidTransform3 &AToBTM, const FReal Thickness, FVec3 &Location, FVec3 &Normal, FReal &Penetration, int32 &FaceIndex) const
Definition ImplicitObjectScaled.h:727
TImplicitObjectScaled(const TImplicitObjectScaled< TConcrete, bInstanced > &Other)=delete
bool LowLevelSweepGeomCCD(const QueryGeomType &B, const TRigidTransform< T, d > &BToATM, const TVector< T, d > &LocalDir, const T Length, const FReal IgnorePenetration, const FReal TargetPenetration, T &OutTOI, T &OutPhi, TVector< T, d > &LocalPosition, TVector< T, d > &LocalNormal, int32 &OutFaceIndex, TVector< T, d > &OutFaceNormal) const
Definition ImplicitObjectScaled.h:690
virtual Pair< FVec3, bool > FindClosestIntersectionImp(const FVec3 &StartPoint, const FVec3 &EndPoint, const FReal Thickness) const override
Definition ImplicitObjectScaled.h:893
virtual FReal GetRadius() const override
Definition ImplicitObjectScaled.h:591
static constexpr int d
Definition ImplicitObjectScaled.h:451
const FReal GetVolume() const
Definition ImplicitObjectScaled.h:974
virtual bool Overlap(const FVec3 &Point, const FReal Thickness) const override
Definition ImplicitObjectScaled.h:883
virtual Chaos::FImplicitObjectPtr CopyGeometryWithScale(const FVec3 &Scale) const override
Definition ImplicitObjectScaled.h:1028
static const TImplicitObjectScaled< TConcrete > & AsScaledChecked(const FImplicitObject &Obj)
Definition ImplicitObjectScaled.h:522
virtual FVec3 FindGeometryOpposingNormal(const FVec3 &DenormDir, int32 HintFaceIndex, const FVec3 &OriginalNormal) const override
Definition ImplicitObjectScaled.h:855
void SetScale(const FVec3f &Scale)
Definition ImplicitObjectScaled.h:954
void SetScale(const FVec3 &Scale)
Definition ImplicitObjectScaled.h:949
FORCEINLINE_DEBUGGABLE FVec3 Support(const FVec3 &Direction, const FReal Thickness, int32 &VertexIndex) const
Definition ImplicitObjectScaled.h:922
virtual void Serialize(FChaosArchive &Ar) override
Definition ImplicitObjectScaled.h:999
int32 NumPlaneVertices(int32 PlaneIndex) const
Definition ImplicitObjectScaled.h:792
int32 GetMostOpposingPlane(const FVec3 &Normal) const
Definition ImplicitObjectScaled.h:752
virtual int32 FindClosestFaceAndVertices(const FVec3 &Position, TArray< FVec3 > &FaceVertices, FReal SearchDist=FReal(0.01)) const override
Definition ImplicitObjectScaled.h:906
FORCEINLINE_DEBUGGABLE VectorRegister4Float SupportCoreSimd(const VectorRegister4Float &Direction, const FReal InMargin) const
Definition ImplicitObjectScaled.h:939
const FVec3 GetVertex(int32 VertexIndex) const
Definition ImplicitObjectScaled.h:843
TImplicitObjectScaled(ObjectType Object, const FVec3 &Scale, FReal InMargin=0)
Definition ImplicitObjectScaled.h:480
TSharedPtr< TConcrete, ESPMode::ThreadSafe > GetSharedObject() const
Definition ImplicitObjectScaled.h:997
static TImplicitObjectScaled< TConcrete > & AsScaledChecked(FImplicitObject &Obj)
Definition ImplicitObjectScaled.h:536
TImplicitObjectScaled(TImplicitObjectScaled< TConcrete, bInstanced > &&Other)
Definition ImplicitObjectScaled.h:500
TImplicitObjectScaled(TConcrete *Object, const FVec3 &Scale, FReal InMargin=0)
Definition ImplicitObjectScaled.h:487
virtual uint16 GetMaterialIndex(uint32 HintIndex) const override
Definition ImplicitObjectScaled.h:1018
T TType
Definition ImplicitObjectScaled.h:450
FRotation3 GetRotationOfMass() const
Definition ImplicitObjectScaled.h:984
const FMatrix33 GetInertiaTensor(const FReal Mass) const
Definition ImplicitObjectScaled.h:989
void GetPlaneNX(const int32 FaceIndex, FVec3 &OutN, FVec3 &OutX) const
Definition ImplicitObjectScaled.h:835
const FVec3 GetCenterOfMass() const
Definition ImplicitObjectScaled.h:979
virtual FName GetTypeName() const
Definition ImplicitObject.h:414
~TImplicitObjectScaled()
Definition ImplicitObjectScaled.h:515
virtual TSerializablePtr< FImplicitObject > GetInnerObject() const override
Definition ImplicitObjectScaled.h:576
virtual FReal PhiWithNormal(const FVec3 &X, FVec3 &Normal) const override
Definition ImplicitObjectScaled.h:601
virtual uint32 GetTypeHash() const override
Definition ImplicitObjectScaled.h:1013
virtual int32 FindMostOpposingFace(const FVec3 &Position, const FVec3 &UnitDir, int32 HintFaceIndex, FReal SearchDist) const override
Definition ImplicitObjectScaled.h:850
virtual FString ToString() const override
Definition ImplicitObjectScaled.h:1035
int32 GetEdgePlane(int32 EdgeIndex, int32 EdgePlaneIndex) const
Definition ImplicitObjectScaled.h:808
virtual bool Raycast(const FVec3 &StartPoint, const FVec3 &Dir, const FReal Length, const FReal Thickness, FReal &OutTime, FVec3 &OutPosition, FVec3 &OutNormal, int32 &OutFaceIndex) const override
Definition ImplicitObjectScaled.h:606
typename TConcrete::TType T
Definition ImplicitObjectScaled.h:449
const ObjectType Object() const
Definition ImplicitObjectScaled.h:994
int32 GetVertexPlanes3(int32 VertexIndex, int32 &PlaneIndex0, int32 &PlaneIndex1, int32 &PlaneIndex2) const
Definition ImplicitObjectScaled.h:786
TRefCountPtr< TConcrete > ObjectType
Definition ImplicitObjectScaled.h:454
FVec3 GetClosestEdge(int32 PlaneIndex, const FVec3 &Position, FVec3 &OutEdgePos0, FVec3 &OutEdgePos1) const
Definition ImplicitObjectScaled.h:758
static TImplicitObjectScaled< TConcrete > * AsScaled(FImplicitObject &Obj)
Definition ImplicitObjectScaled.h:563
FVec3 GetClosestEdgePosition(int32 PlaneIndex, const FVec3 &Position) const
Definition ImplicitObjectScaled.h:767
int32 NumEdges() const
Definition ImplicitObjectScaled.h:818
int32 GetEdgeVertex(int32 EdgeIndex, int32 EdgeVertexIndex) const
Definition ImplicitObjectScaled.h:803
virtual FRealSingle GetRadiusf() const override
Definition ImplicitObjectScaled.h:596
bool GetClosestEdgeVertices(int32 PlaneIndex, const FVec3 &Position, int32 &OutVertexIndex0, int32 &OutVertexIndex1) const
Definition ImplicitObjectScaled.h:772
virtual Chaos::FImplicitObjectPtr CopyGeometry() const override
Definition ImplicitObjectScaled.h:1023
static const TImplicitObjectScaled< TConcrete > * AsScaled(const FImplicitObject &Obj)
Definition ImplicitObjectScaled.h:550
const TPlaneConcrete< FReal, 3 > GetPlane(int32 FaceIndex) const
Definition ImplicitObjectScaled.h:829
int32 NumPlanes() const
Definition ImplicitObjectScaled.h:813
FORCEINLINE_DEBUGGABLE FVec3 SupportCore(const FVec3 &Direction, const FReal InMargin, FReal *OutSupportDelta, int32 &VertexIndex) const
Definition ImplicitObjectScaled.h:934
std::conditional_t< bInstanced, TSerializablePtr< TConcrete >, TUniquePtr< TConcrete > > ObjectTypeDeprecated
Definition ImplicitObjectScaled.h:457
const TConcrete * GetUnscaledObject() const
Definition ImplicitObjectScaled.h:581
int32 NumVertices() const
Definition ImplicitObjectScaled.h:823
bool LowLevelOverlapGeom(const QueryGeomType &B, const TRigidTransform< T, d > &BToATM, T Thickness=0, FMTDInfo *OutMTD=nullptr) const
Definition ImplicitObjectScaled.h:742
static constexpr EImplicitObjectType StaticType()
Definition ImplicitObjectScaled.h:517
int32 FindVertexPlanes(int32 VertexIndex, int32 *OutVertexPlanes, int32 MaxVertexPlanes) const
Definition ImplicitObjectScaled.h:779
int32 GetPlaneVertex(int32 PlaneIndex, int32 PlaneVertexIndex) const
Definition ImplicitObjectScaled.h:798
bool LowLevelSweepGeom(const QueryGeomType &B, const TRigidTransform< T, d > &BToATM, const TVector< T, d > &LocalDir, const T Length, T &OutTime, TVector< T, d > &LocalPosition, TVector< T, d > &LocalNormal, int32 &OutFaceIndex, TVector< T, d > &OutFaceNormal, T Thickness=0, bool bComputeMTD=false) const
Definition ImplicitObjectScaled.h:651
Definition Transform.h:115
Definition Serializable.h:10
Definition Vector.h:407
FRealSingle Max() const
Definition Vector.h:519
FRealSingle SafeNormalize(FRealSingle Epsilon=1e-4f)
Definition Vector.h:567
virtual CORE_API void UsingCustomVersion(const struct FGuid &Guid)
Definition Archive.cpp:590
CORE_API int32 CustomVer(const struct FGuid &Key) const
Definition Archive.cpp:602
Definition Array.h:670
uint32 GetRefCount()
Definition RefCounting.h:604
UE_FORCEINLINE_HINT ReferencedType * GetReference() const
Definition RefCounting.h:584
Definition SharedPointer.h:692
Definition UniquePtr.h:107
@ IsInstanced
Definition ImplicitObjectType.h:35
@ Union
Definition ImplicitObjectType.h:18
@ IsScaled
Definition ImplicitObjectType.h:36
@ Transformed
Definition ImplicitObjectType.h:17
TVec3< T > ScaleInertia(const TVec3< T > &Inertia, const TVec3< T > &Scale, const bool bScaleMass)
Definition Utilities.h:519
Definition SkeletalMeshComponent.h:307
TVector< FRealSingle, 3 > FVec3f
Definition Core.h:27
TRefCountPtr< FImplicitObject > FImplicitObjectPtr
Definition ImplicitFwd.h:33
uint8 EImplicitObjectType
Definition ImplicitObjectType.h:41
@ X
Definition SimulationModuleBase.h:152
FORCEINLINE bool IsInstanced(EImplicitObjectType Type)
Definition ImplicitObjectType.h:43
FRealDouble FReal
Definition Real.h:22
TSerializablePtr< T > MakeSerializable(const TUniquePtr< T > &Unique)
Definition Serializable.h:60
float FRealSingle
Definition Real.h:14
FORCEINLINE bool IsScaled(EImplicitObjectType Type)
Definition ImplicitObjectType.h:48
TVector< FReal, 3 > FVec3
Definition Core.h:17
const T * UnwrapImplicit(const FImplicitObject &Implicit, FVec3 &OutScale, FReal &OutMargin)
Remove the Instanced or Scaled wrapper from an ImplicitObject of a known inner type and extract the i...
Definition ImplicitObjectScaled.h:1143
TAABB< FReal, 3 > FAABB3
Definition ImplicitObject.h:34
uint32 GetTypeHash(const TBox< T > &Box)
Definition Box.h:1008
Definition GeometryQueries.h:27
Definition Pair.h:8
static bool IsBaseOf(const EImplicitObjectType InType)
Definition ImplicitObjectScaled.h:1121
static bool IsBaseOf(const EImplicitObjectType InType)
Definition ImplicitObjectScaled.h:1131
Definition ImplicitObject.h:83
CORE_API static const FGuid GUID
Definition ExternalPhysicsCustomObjectVersion.h:144
@ ScaledGeometryIsConcrete
Definition ExternalPhysicsCustomObjectVersion.h:49
static UE_FORCEINLINE_HINT bool IsNearlyEqual(float A, float B, float ErrorTolerance=UE_SMALL_NUMBER)
Definition UnrealMathUtility.h:388
Definition NumericLimits.h:41
T Z
Definition Vector.h:68
T Y
Definition Vector.h:65
T X
Definition Vector.h:62
TVector< T > GetSignVector() const
Definition Vector.h:1823
T Size() const
Definition Vector.h:1716
Definition UnrealMathFPU.h:20