UDocumentation UE5.7 10.02.2026 (Source)
API documentation for Unreal Engine 5.7
Convex.h
Go to the documentation of this file.
1// Copyright Epic Games, Inc. All Rights Reserved.
2#pragma once
3
5#include "Chaos/AABB.h"
9#include "ChaosArchive.h"
10#include "ChaosCheck.h"
11#include "ChaosLog.h"
17
18namespace Chaos
19{
20 //
21 // Note: While Convex technically supports a margin, the margin is typically a property of the
22 // instance wrapper (ImplicitScaled, ImplicitTransformed, or ImplicitInstanced). Usually the
23 // margin on the convex itself is zero.
24 //
25 class FConvex final : public FImplicitObject
26 {
27 public:
29
35
36 static constexpr unsigned D = 3;
37
39 : FImplicitObject(EImplicitObject::IsConvex | EImplicitObject::HasBoundingBox, ImplicitObjectType::Convex)
40 , Volume(0.f)
41 , CenterOfMass(FVec3Type(0.f))
42 , UnitMassInertiaTensor(1., 1., 1.)
43 , RotationOfMass(FRotation3::Identity)
44 {}
46 : FImplicitObject(EImplicitObject::IsConvex | EImplicitObject::HasBoundingBox, ImplicitObjectType::Convex)
47 , Planes(MoveTemp(Other.Planes))
48 , Vertices(MoveTemp(Other.Vertices))
49 , LocalBoundingBox(MoveTemp(Other.LocalBoundingBox))
50 , StructureData(MoveTemp(Other.StructureData))
51 , Volume(MoveTemp(Other.Volume))
52 , CenterOfMass(MoveTemp(Other.CenterOfMass))
53 , UnitMassInertiaTensor(MoveTemp(Other.UnitMassInertiaTensor))
54 , RotationOfMass(MoveTemp(Other.RotationOfMass))
55 {}
56
57 // NOTE: This constructor will result in approximate COM and volume calculations, since it does
58 // not have face indices for surface particles.
59 // NOTE: Convex constructed this way will not contain any structure data
60 // @todo(chaos): Keep track of invalid state and ensure on volume or COM access?
61 // @todo(chaos): Add plane vertex indices in the constructor and call CreateStructureData
62 // @todo(chaos): Merge planes? Or assume the input is a good convex hull?
63 UE_DEPRECATED(4.27, "Use the constructor version with the face indices.")
65 : FImplicitObject(EImplicitObject::IsConvex | EImplicitObject::HasBoundingBox, ImplicitObjectType::Convex)
66 , Planes(MoveTemp(InPlanes))
67 , Vertices(MoveTemp(InVertices))
68 {
69 for (int32 ParticleIndex = 0; ParticleIndex < Vertices.Num(); ++ParticleIndex)
70 {
71 LocalBoundingBox.GrowToInclude(Vertices[ParticleIndex]);
72 }
73
74 // For now we approximate COM and volume with the bounding box
75 CenterOfMass = LocalBoundingBox.GetCenterOfMass();
76 Volume = LocalBoundingBox.GetVolume();
77
78 ComputeUnitMassInertiaTensorAndRotationOfMass(Volume);
79 }
80
82 : FImplicitObject(EImplicitObject::IsConvex | EImplicitObject::HasBoundingBox, ImplicitObjectType::Convex)
83 , Planes(MoveTemp(InPlanes))
84 , Vertices(MoveTemp(InVertices))
85 {
86 for (int32 ParticleIndex = 0; ParticleIndex < Vertices.Num(); ++ParticleIndex)
87 {
88 LocalBoundingBox.GrowToInclude(Vertices[ParticleIndex]);
89 }
90
91 // For now we approximate COM and volume with the bounding box
92 CenterOfMass = LocalBoundingBox.GetCenterOfMass();
93 Volume = LocalBoundingBox.GetVolume();
94
95 CreateStructureData(MoveTemp(InFaceIndices));
96
97 ComputeUnitMassInertiaTensorAndRotationOfMass(Volume);
98 }
99
102 : FImplicitObject(EImplicitObject::IsConvex | EImplicitObject::HasBoundingBox, ImplicitObjectType::Convex)
103 , Planes(MoveTemp(InPlanes))
104 , Vertices(MoveTemp(InVertices))
105 {
106 LocalBoundingBox = FAABB3Type(InMin, InMax);
107 CenterOfMass = LocalBoundingBox.GetCenterOfMass();
108
109 Volume = InVolume;
110 RotationOfMass = InRotationMatrix;
111 UnitMassInertiaTensor = InInertiaTensor;
112
113 CreateStructureData(MoveTemp(InFaceIndices), bRegularDatas);
114 }
115
117 : FImplicitObject(EImplicitObject::IsConvex | EImplicitObject::HasBoundingBox, ImplicitObjectType::Convex)
118 , CenterOfMass(FVec3Type(0.f))
119 {
120 const int32 NumVertices = InVertices.Num();
121 if (NumVertices == 0)
122 {
123 return;
124 }
125
127 FConvexBuilder::Build(InVertices, Planes, FaceIndices, Vertices, LocalBoundingBox, BuildMethod);
128 CHAOS_ENSURE(Planes.Num() == FaceIndices.Num());
129
130 // @todo(chaos): this only works with triangles. Fix that an we can run MergeFaces before calling this
131 CalculateVolumeAndCenterOfMass(Vertices, FaceIndices, Volume, CenterOfMass);
132
134 {
135 // it appears that this code path can leave the convex in an undefined state.
136 // @todo(chaos): Tolerances should be based on size, or passed
137 const FRealType DistanceTolerance = 1.0f;
138 const FRealType AngleTolerance = 1.e-6f;
139 FConvexBuilder::MergeFaces(Planes, FaceIndices, Vertices, DistanceTolerance);
140 FConvexBuilder::MergeColinearEdges(Planes, FaceIndices, Vertices, AngleTolerance);
141 CHAOS_ENSURE(Planes.Num() == FaceIndices.Num());
142 }
143
144 CreateStructureData(MoveTemp(FaceIndices));
145
146 ComputeUnitMassInertiaTensorAndRotationOfMass(Volume);
147
149 }
150
151 FConvex& operator=(const FConvex& Other) = delete;
152
154 {
155 // Base class assignment
156 // @todo(chaos): Base class needs protected assignment
157 Type = Other.Type;
158 CollisionType = Other.CollisionType;
159 Margin = Other.Margin;
160 bIsConvex = Other.bIsConvex;
161 bDoCollide = Other.bDoCollide;
162 bHasBoundingBox = Other.bHasBoundingBox;
163#if TRACK_CHAOS_GEOMETRY
164 bIsTracked = Other.bIsTracked;
165#endif
166 // This class assignment
167 Planes = MoveTemp(Other.Planes);
168 Vertices = MoveTemp(Other.Vertices);
169 LocalBoundingBox = MoveTemp(Other.LocalBoundingBox);
170 StructureData = MoveTemp(Other.StructureData);
171 Volume = MoveTemp(Other.Volume);
172 CenterOfMass = MoveTemp(Other.CenterOfMass);
173 UnitMassInertiaTensor = MoveTemp(Other.UnitMassInertiaTensor);
174 RotationOfMass = MoveTemp(Other.RotationOfMass);
175
176 return *this;
177 }
178
180 {
181 return new Chaos::FConvex(*this);
182 }
183
184 UE_DEPRECATED(5.4, "Please use RawCopyAsConvex instead")
186 {
187 check(false);
188 return nullptr;
189 }
190
195
197
198 private:
199 CHAOS_API void CreateStructureData(TArray<TArray<int32>>&& FaceIndices, const bool bRegularDatas = false);
200
201 public:
203 {
205 }
206
207 virtual FReal GetMargin() const override
208 {
209 return Margin;
210 }
211
212 virtual FReal GetRadius() const override
213 {
214 return 0.0f;
215 }
216
217 virtual const FAABB3 BoundingBox() const override
218 {
219 // LWC : conversion from float to double
220 return FAABB3(LocalBoundingBox.Min(), LocalBoundingBox.Max());
221 }
222
224 {
225 return LocalBoundingBox;
226 }
227
228 // Return the distance to the surface
229 virtual FReal PhiWithNormal(const FVec3& X, FVec3& Normal) const override
230 {
231 return PhiWithNormalInternal(X, Normal);
232 }
233
234 virtual FReal PhiWithNormalScaled(const FVec3& X, const FVec3& Scale, FVec3& Normal) const override
235 {
236 return PhiWithNormalScaledInternal(X, Scale, Normal);
237 }
238
239 private:
240 // Distance to the surface
241 FReal PhiWithNormalInternal(const FVec3& X, FVec3& Normal) const
242 {
243 const int32 NumPlanes = Planes.Num();
244 if (NumPlanes == 0)
245 {
246 return FLT_MAX;
247 }
248 check(NumPlanes > 0);
249
251 int32 MaxPlane = 0;
252
253 for (int32 Idx = 0; Idx < NumPlanes; ++Idx)
254 {
255 const FReal Phi = Planes[Idx].SignedDistance(X);
256 if (Phi > MaxPhi)
257 {
258 MaxPhi = Phi;
259 MaxPlane = Idx;
260 }
261 }
262
263 FReal Phi = Planes[MaxPlane].PhiWithNormal(X, Normal);
264 if (Phi <= 0)
265 {
266 return Phi;
267 }
268
269 // If x is outside the convex mesh, we should find for the nearest point to triangles on the plane
271 const FVec3 XOnPlane = X - Phi * Normal;
272 FReal ClosestDistance = TNumericLimits<FReal>::Max();
273 FVec3 ClosestPoint;
274 for (int32 Index = 0; Index < PlaneVerticesNum - 2; Index++)
275 {
279
281 if (XOnPlane == X)
282 {
283 return Phi;
284 }
285
286 const FReal Distance = (Point - XOnPlane).Size();
287 if (Distance < ClosestDistance)
288 {
289 ClosestDistance = Distance;
290 ClosestPoint = Point;
291 }
292 }
293
294 const TVector<FReal, 3> Difference = X - ClosestPoint;
295 Phi = Difference.Size();
296 if (Phi > UE_SMALL_NUMBER)
297 {
298 Normal = (Difference) / Phi;
299 }
300 return Phi;
301 }
302
303 // Distance from a point to the surface for use in the scaled version. When the convex
304 // is scaled, we need to bias the depth calculation to take into account the world-space scale
305 FReal PhiWithNormalScaledInternal(const FVec3& X, const FVec3& Scale, FVec3& Normal) const
306 {
307 const int32 NumPlanes = Planes.Num();
308 if (NumPlanes == 0)
309 {
310 return FLT_MAX;
311 }
312 check(NumPlanes > 0);
313
315 FVec3 MaxNormal = FVec3(0,0,1);
316 int32 MaxPlane = 0;
317 for (int32 Idx = 0; Idx < NumPlanes; ++Idx)
318 {
319 FVec3 PlaneNormal = (Planes[Idx].Normal() / Scale).GetUnsafeNormal();
320 FVec3 PlanePos = Planes[Idx].X() * Scale;
321 FReal PlaneDistance = FVec3::DotProduct(X - PlanePos, PlaneNormal);
322 if (PlaneDistance > MaxPhi)
323 {
325 MaxNormal = PlaneNormal;
326 MaxPlane = Idx;
327 }
328 }
329
331
332 if (MaxPhi < 0)
333 {
334 return MaxPhi;
335 }
336
337 // If X is outside the convex mesh, we should find for the nearest point to triangles on the plane
339 const FVec3 XOnPlane = X - MaxPhi * Normal;
340 FReal ClosestDistance = TNumericLimits<FReal>::Max();
341 FVec3 ClosestPoint;
342 for (int32 Index = 0; Index < PlaneVerticesNum - 2; Index++)
343 {
347
349 if (XOnPlane == X)
350 {
351 return MaxPhi;
352 }
353
354 const FReal Distance = (Point - XOnPlane).Size();
355 if (Distance < ClosestDistance)
356 {
357 ClosestDistance = Distance;
358 ClosestPoint = Point;
359 }
360 }
361
362 const FVec3 Difference = X - ClosestPoint;
363 const FReal DifferenceLen = Difference.Size();
365 {
368 }
369 return MaxPhi;
370 }
371
372
373 public:
379 CHAOS_API 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;
380 CHAOS_API bool RaycastFast(const FVec3& StartPoint, const FVec3& Dir, const FReal Length, const FReal Thickness, FReal& OutTime, FVec3& OutPosition, FVec3& OutNormal, int32& OutFaceIndex) const;
381
382 virtual Pair<FVec3, bool> FindClosestIntersectionImp(const FVec3& StartPoint, const FVec3& EndPoint, const FReal Thickness) const override
383 {
384 const int32 NumPlanes = Planes.Num();
385 TArray<Pair<FReal, FVec3>> Intersections;
386 Intersections.Reserve(FMath::Min(static_cast<int32>(NumPlanes*.1), 16)); // Was NumPlanes, which seems excessive.
387 for (int32 Idx = 0; Idx < NumPlanes; ++Idx)
388 {
389 auto PlaneIntersection = Planes[Idx].FindClosestIntersection(StartPoint, EndPoint, Thickness);
390 if (PlaneIntersection.Second)
391 {
392 Intersections.Add(MakePair((FReal)(PlaneIntersection.First - StartPoint).SizeSquared(), PlaneIntersection.First));
393 }
394 }
395 Intersections.Sort([](const Pair<FReal, FVec3>& Elem1, const Pair<FReal, FVec3>& Elem2) { return Elem1.First < Elem2.First; });
396 for (const auto& Elem : Intersections)
397 {
398 if (this->SignedDistance(Elem.Second) < (Thickness + 1e-4))
399 {
400 return MakePair(Elem.Second, true);
401 }
402 }
403 return MakePair(FVec3(0), false);
404 }
405
406 // Whether the structure data has been created for this convex (will eventually always be true)
407 bool HasStructureData() const { return StructureData.IsValid(); }
408
409 // The convex structure data (mainly exposed for testing)
410 const FConvexStructureData& GetStructureData() const { return StructureData; }
411
412 // Get the index of the plane that most opposes the normal
414
415 // Get the index of the plane that most opposes the normal
417
418 // Get the nearest point on an edge and the edge vertices
419 // Used for manifold generation
421
422 // Get the nearest point on an edge of the specified face
424 {
425 FVec3 Unused0, Unused1;
426 return GetClosestEdge(PlaneIndex, Position, Unused0, Unused1);
427 }
428
430
431 // Get an array of all the plane indices that belong to a vertex (up to MaxVertexPlanes).
432 // Returns the number of planes found.
434
436
437 // The number of vertices that make up the corners of the specified face
438 inline int32 NumPlaneVertices(int32 PlaneIndex) const
439 {
440 if (StructureData.IsValid())
441 {
442 return StructureData.NumPlaneVertices(PlaneIndex);
443 }
444 return 0;
445 }
446
447 // Get the vertex index of one of the vertices making up the corners of the specified face
449 {
450 if (StructureData.IsValid())
451 {
452 return StructureData.GetPlaneVertex(PlaneIndex, PlaneVertexIndex);
453 }
454 return INDEX_NONE;
455 }
456
457 // Get the vertex index of one of the two vertices in an edge
459 {
460 if (StructureData.IsValid())
461 {
462 return StructureData.GetEdgeVertex(EdgeIndex, EdgeVertexIndex);
463 }
464 return INDEX_NONE;
465 }
466
467 // Get the plane index of one of the two planes using an edge
468 inline int32 GetEdgePlane(int32 EdgeIndex, int32 EdgePlaneIndex) const
469 {
470 if (StructureData.IsValid())
471 {
472 return StructureData.GetEdgePlane(EdgeIndex, EdgePlaneIndex);
473 }
474 return INDEX_NONE;
475 }
476
477 // Get the half edge index for a given plane
479 {
480 if (StructureData.IsValid())
481 {
482 return StructureData.GetPlaneHalfEdge(PlaneIndex, PlaneEdgeIndex);
483 }
484 return INDEX_NONE;
485 }
486
487 // Get the half edges associated with an edge
488 inline void GetHalfEdges(int32 EdgeIndex, int32& OutHalfEdge0, int32& OutHalfEdge1) const
489 {
490 if (StructureData.IsValid())
491 {
492 StructureData.GetHalfEdges(EdgeIndex, OutHalfEdge0, OutHalfEdge1);
493 return;
494 }
495
498 return;
499 }
500
501 inline int32 NumPlanes() const
502 {
503 return Planes.Num();
504 }
505
506 inline int32 NumEdges() const
507 {
508 if (StructureData.IsValid())
509 {
510 return StructureData.NumEdges();
511 }
512 return 0;
513 }
514
515 inline int32 NumVertices() const
516 {
517 return (int32)Vertices.Num();
518 }
519
520 // Get the plane at the specified index (e.g., indices from FindVertexPlanes)
522 {
523 // @todo(chaos) this is needed because this API is shared with BOx implicit - we shoudl eventually only need local space planes and be able to use single precision
525 }
526
527 inline void GetPlaneNX(const int32 FaceIndex, FVec3& OutN, FVec3& OutX) const
528 {
529 OutN = FVec3(Planes[FaceIndex].Normal());
530 OutX = FVec3(Planes[FaceIndex].X());
531 }
532
534 {
535 return Planes[FaceIndex];
536 }
537
538 // Get the vertex at the specified index (e.g., indices from GetPlaneVertexs)
539 inline const FVec3Type& GetVertex(int32 VertexIndex) const
540 {
541 return Vertices[VertexIndex];
542 }
543
544
546
548
550 {
551 // For convexes, this function must be called with a face index.
552 // If this ensure is getting hit, fix the caller so that it
553 // passes in a valid face index.
555 {
557 return OpposingFace.Normal();
558 }
559 return OriginalNormal;
560 }
561
562 CHAOS_API virtual int32 FindClosestFaceAndVertices(const FVec3& Position, TArray<FVec3>& FaceVertices, FReal SearchDist = 0.01f) const override;
563
564 // Returns a winding order multiplier used in the manifold clipping and required when we have negative scales (See ImplicitObjectScaled)
566 {
567 return 1.0f;
568 }
569
570 private:
571 FORCEINLINE_DEBUGGABLE int32 GetSupportVertex(const FVec3Type& Direction) const
572 {
575 const int32 NumVertices = Vertices.Num();
576
577 for (int32 Idx = 0; Idx < NumVertices; ++Idx)
578 {
579 const FRealType Dot = FVec3Type::DotProduct(Vertices[Idx], Direction);
580 if (Dot > MaxDot)
581 {
582 MaxDot = Dot;
583 MaxVIdx = Idx;
584 }
585 }
586
587 return MaxVIdx;
588 }
589
590 public:
591
592 // @todo(chaos): Move to utils
593 inline bool IntersectPlanes3(const FVec3& X1, const FVec3& N1, const FVec3& X2, const FVec3& N2, const FVec3& X3, const FVec3& N3, FVec3& OutX, const FReal EpsilonSq = FReal(1.e-6)) const
594 {
595 // Compute determinant, the triple product P1|(P2^P3)==(P1^P2)|P3.
596 const FVec3 N1CrossN2 = FVec3::CrossProduct(N1, N2);
597 const FReal Det = FVec3::DotProduct(N1CrossN2, N3);
599 {
600 // Degenerate.
601 OutX = FVec3(0);
602 return false;
603 }
604 else
605 {
606 // Compute the intersection point, guaranteed valid if determinant is nonzero.
607 const FVec3 N2CrossN3 = FVec3::CrossProduct(N2, N3);
608 const FVec3 N3CrossN1 = FVec3::CrossProduct(N3, N1);
609 const FReal D1 = FVec3::DotProduct(X1, N1);
610 const FReal D2 = FVec3::DotProduct(X2, N2);
611 const FReal D3 = FVec3::DotProduct(X3, N3);
612 OutX = (D1 * N2CrossN3 + D2 * N3CrossN1 + D3 * N1CrossN2) / Det;
613 }
614 return true;
615 }
616
618 {
619 // @chaos(todo): moving the vertices this way based on margin is only valid for small margins. If the margin
620 // is large enough to cause a face to reduce to zero size, vertices should be merged and the path is non-linear.
621 // This can be fixed with some extra data in the convex structure, but for now we accept the fact that large
622 // margins on convexes with small faces can cause non-convex core shapes.
623
624 if (InMargin == FReal(0))
625 {
626 return GetVertex(VertexIndex);
627 }
628
629 // Get any 3 planes that contribute to this vertex
633 const int32 NumVertexPlanes = GetVertexPlanes3(VertexIndex, PlaneIndex0, PlaneIndex1, PlaneIndex2);
634
635 // Move the planes by the margin and recalculate the interection
636 if (NumVertexPlanes >= 3)
637 {
638 FVec3 VertexPos = Vertices[VertexIndex];
640 VertexPos - InMargin * Planes[PlaneIndex0].Normal(), Planes[PlaneIndex0].Normal(),
641 VertexPos - InMargin * Planes[PlaneIndex1].Normal(), Planes[PlaneIndex1].Normal(),
642 VertexPos - InMargin * Planes[PlaneIndex2].Normal(), Planes[PlaneIndex2].Normal(),
643 VertexPos))
644 {
645 if (OutSupportDelta != nullptr)
646 {
647 *OutSupportDelta = (Vertices[VertexIndex] - VertexPos).Size() - InMargin;
648 }
649 return VertexPos;
650 }
651 }
652
653 // If we get here, the convex hull is malformed. Try to handle it anyway
654 // @todo(chaos): track down the invalid hull issue
655
656 if (NumVertexPlanes == 2)
657 {
658 const FVec3 NewPlaneX = GetVertex(VertexIndex);
659 const FVec3 NewPlaneN0 = Planes[PlaneIndex0].Normal();
660 const FVec3 NewPlaneN1 = Planes[PlaneIndex1].Normal();
661 const FVec3 NewPlaneN = (NewPlaneN0 + NewPlaneN1).GetSafeNormal();
662 return NewPlaneX - (InMargin * NewPlaneN);
663 }
664
665 if (NumVertexPlanes == 1)
666 {
667 const FVec3 NewPlaneX = GetVertex(VertexIndex);
668 const FVec3 NewPlaneN = Planes[PlaneIndex0].Normal();
669 return NewPlaneX - (InMargin * NewPlaneN);
670 }
671
672 // Ok now we really are done...just return the outer vertex and duck
673 return GetVertex(VertexIndex);
674 }
675
677 {
678 // Get any 3 planes that contribute to this vertex
682 const int32 NumVertexPlanes = GetVertexPlanes3(VertexIndex, PlaneIndex0, PlaneIndex1, PlaneIndex2);
683 const FVec3 InvScale = FVec3(FReal(1) / Scale.X, FReal(1) / Scale.Y, FReal(1) / Scale.Z);
684
685 // Move the planes by the margin and recalculate the interection
686 if (NumVertexPlanes >= 3)
687 {
688 const FVec3 VertexPos = Scale * Vertices[VertexIndex];
689
690 const FVec3 NewPlaneN0 = (Planes[PlaneIndex0].Normal() * InvScale).GetUnsafeNormal();
691 const FVec3 NewPlaneN1 = (Planes[PlaneIndex1].Normal() * InvScale).GetUnsafeNormal();
692 const FVec3 NewPlaneN2 = (Planes[PlaneIndex2].Normal() * InvScale).GetUnsafeNormal();
693
700 {
701 if (OutSupportDelta != nullptr)
702 {
704 }
705 return AdjustedVertexPos;
706 }
707 }
708
709 // If we get here, the convex hull is malformed. Try to handle it anyway
710 // @todo(chaos): track down the invalid hull issue
711
712 if (NumVertexPlanes == 2)
713 {
714 const FVec3 NewPlaneX = Scale * GetVertex(VertexIndex);
715 const FVec3 NewPlaneN0 = (Planes[PlaneIndex0].Normal() * InvScale).GetUnsafeNormal();
716 const FVec3 NewPlaneN1 = (Planes[PlaneIndex1].Normal() * InvScale).GetUnsafeNormal();
717 const FVec3 NewPlaneN = (NewPlaneN0 + NewPlaneN1).GetSafeNormal();
718 return NewPlaneX - (InMargin * NewPlaneN);
719 }
720
721 if (NumVertexPlanes == 1)
722 {
723 const FVec3 NewPlaneX = Scale * GetVertex(VertexIndex);
724 const FVec3 NewPlaneN = (Planes[PlaneIndex0].Normal() * InvScale).GetUnsafeNormal();
725 return NewPlaneX - (InMargin * NewPlaneN);
726 }
727
728 // Ok now we really are done...just return the outer vertex and duck
729 return GetVertex(VertexIndex) * Scale;
730 }
731
732 public:
733 // Return support point on the core shape (the convex shape with all planes moved inwards by margin).
734 FVec3 SupportCore(const FVec3& Direction, const FReal InMargin, FReal* OutSupportDelta, int32& VertexIndex) const
735 {
736 const int32 SupportVertexIndex = GetSupportVertex(FVec3Type(Direction));
737 VertexIndex = SupportVertexIndex;
739 {
741 }
742 return FVec3(0);
743 }
744
745 // Return support point on the core shape (the convex shape with all planes moved inwards by margin).
758
759
760 // SupportCore with non-uniform scale support. This is required for the margin in scaled
761 // space to by uniform. Note in this version all the inputs are in outer container's (scaled shape) space
762 FVec3 SupportCoreScaled(const FVec3& Direction, FReal InMargin, const FVec3& Scale, FReal* OutSupportDelta, int32& VertexIndex) const
763 {
764 // Find the supporting vertex index
765 const FVec3Type DirectionScaled = FVec3Type(Scale * Direction); // does not need to be normalized
766 const int32 SupportVertexIndex = GetSupportVertex(DirectionScaled);
767 VertexIndex = SupportVertexIndex;
768 // Adjust the vertex position based on margin
770 {
771 if (InMargin == 0.0f)
772 {
773 return FVec3(GetVertex(VertexIndex)) * Scale;
774 }
775 else
776 {
777 // Note: Shapes wrapped in a non-uniform scale should not have their own margin and we assume that here
778 // @chaos(todo): apply an upper limit to the margin to prevent a non-convex or null shape (also see comments in GetMarginAdjustedVertex)
780 }
781 }
782 return FVec3(0);
783 }
784
785 // Return support point on the shape
786 // @todo(chaos): do we need to support thickness?
787 FORCEINLINE FVec3 Support(const FVec3& Direction, const FReal Thickness, int32& VertexIndex) const
788 {
789 const int32 MaxVIdx = GetSupportVertex(FVec3Type(Direction));
790 VertexIndex = MaxVIdx;
791 if (MaxVIdx != INDEX_NONE)
792 {
793 if (Thickness != 0.0f)
794 {
795 return Vertices[MaxVIdx] + Direction.GetUnsafeNormal() * Thickness;
796 }
797 return Vertices[MaxVIdx];
798 }
799 return FVec3(0);
800 }
801
802 FORCEINLINE FVec3 SupportScaled(const FVec3& Direction, const FReal Thickness, const FVec3& Scale, int32& VertexIndex) const
803 {
804 FVec3 SupportPoint = Support(Direction * Scale, 0.0f, VertexIndex) * Scale;
805 if (Thickness > 0.0f)
806 {
807 SupportPoint += Thickness * Direction.GetSafeNormal();
808 }
809 return SupportPoint;
810 }
811
812 virtual FString ToString() const override
813 {
814 return ToStringSummary();
815 }
816
817 // A one-line summary of the convex
818 FString ToStringSummary() const
819 {
820 return FString::Printf(TEXT("Convex: Verts: %d, Edges %d, Planes: %d, Margin %f"), NumVertices(), NumEdges(), NumPlanes(), GetMargin());
821 }
822
823 // Print all the datas
824 FString ToStringFull() const
825 {
826 FString S = ToStringSummary();
827 S.Append(TEXT("\n"));
828 for (int32 VertexIndex = 0; VertexIndex < NumVertices(); ++VertexIndex)
829 {
830 const FVec3 Vert = GetVertex(VertexIndex);
831 S.Append(FString::Printf(TEXT(" Vertex %d: [%f, %f, %f]\n"), VertexIndex, Vert.X, Vert.Y, Vert.Z));
832 }
833 for (int32 PlaneIndex = 0; PlaneIndex < NumPlanes(); ++PlaneIndex)
834 {
835 const TPlaneConcrete<FReal, 3> Plane = GetPlane(PlaneIndex);
836 S.Append(FString::Printf(TEXT(" Plane %d: Normal: [%f, %f, %f], Distance: %f, Verts: ["), PlaneIndex, Plane.Normal().X, Plane.Normal().Y, Plane.Normal().Z, FVec3::DotProduct(Plane.X(), Plane.Normal())));
837 const int32 PlaneVertexCount = NumPlaneVertices(PlaneIndex);
839 {
840 S.Append(FString::Printf(TEXT("%d"), GetPlaneVertex(PlaneIndex, PlaneVertexIndex)));
842 {
843 S.Append(FString::Printf(TEXT(", ")));
844 }
845 }
846 S.Append(FString::Printf(TEXT("]\n")));
847 }
848 S.Append(FString::Printf(TEXT(" Edges: ")));
849 for (int32 EdgeIndex = 0; EdgeIndex < NumEdges(); ++EdgeIndex)
850 {
851 S.Append(FString::Printf(TEXT("[%d, %d]"), GetEdgeVertex(EdgeIndex, 0), GetEdgeVertex(EdgeIndex, 1)));
852 if (EdgeIndex < NumEdges() - 1)
853 {
854 S.Append(FString::Printf(TEXT(", ")));
855 }
856 }
857 S.Append(FString::Printf(TEXT("\n")));
858 return S;
859 }
860
862 {
863 return Vertices;
864 }
865
867 {
868 return Planes;
869 }
870
871 const FReal GetVolume() const
872 {
873 return Volume;
874 }
875
881
883 {
884 return RotationOfMass;
885 }
886
887 const FVec3 GetCenterOfMass() const
888 {
889 return CenterOfMass;
890 }
891
892 virtual uint32 GetTypeHash() const override
893 {
894 uint32 Result = LocalBoundingBox.GetTypeHash();
895
896 for (const FVec3Type& Vertex: Vertices)
897 {
898 Result = HashCombine(Result, ::GetTypeHash(Vertex[0]));
899 Result = HashCombine(Result, ::GetTypeHash(Vertex[1]));
900 Result = HashCombine(Result, ::GetTypeHash(Vertex[2]));
901 }
902
903 for(const FPlaneType& Plane : Planes)
904 {
905 Result = HashCombine(Result, Plane.GetTypeHash());
906 }
907
908 return Result;
909 }
910
912 {
919
921 {
923 Ar << TmpPlanes;
924
925 Planes.SetNum(TmpPlanes.Num());
926 for(int32 Idx = 0; Idx < Planes.Num(); ++Idx)
927 {
928 Planes[Idx] = TmpPlanes[Idx].PlaneConcrete();
929 }
930 }
931 else
932 {
933 Ar << Planes;
934 }
935
936 // Do we use the old Particles array or the new Vertices array?
937 // Note: This change was back-ported to UE4, so we need to check
938 // multiple object versions.
939 // This is a mess because the change was back-integrated to 2 different streams. Be careful...
941 bool bConvexVerticesNewFormatUE5 = (Ar.CustomVer(FUE5MainStreamObjectVersion::GUID) >= FUE5MainStreamObjectVersion::ConvexUsesVerticesArray);
942 bool bConvexVerticesNewFormatFN = (Ar.CustomVer(FFortniteMainBranchObjectVersion::GUID) >= FFortniteMainBranchObjectVersion::ChaosConvexVariableStructureDataAndVerticesArray);
944
946 {
949
951 Vertices.SetNum(NumVertices);
952 for (int32 VertexIndex = 0; VertexIndex < NumVertices; ++VertexIndex)
953 {
954 Vertices[VertexIndex] = TmpSurfaceParticles.GetX(VertexIndex);
955 }
956 }
957 else
958 {
959 Ar << Vertices;
960 }
961
962
963 TBox<FRealType,3>::SerializeAsAABB(Ar, LocalBoundingBox);
964
966 {
967 FRealSingle VolumeFloat = (FRealSingle)Volume; // LWC_TODO : potential precision lossdepending on FRealType, to be changed when we can serialize FReal as double
968 Ar << VolumeFloat;
969 Volume = (FRealType)VolumeFloat;
970
971 // Some assets have stored NaN ( empty convex objects from Geometry Collection )
972 // Fixing this so that next time they get saved the Volume is a valid number
973 if (FMath::IsNaN(Volume) && Ar.IsLoading())
974 {
975 Volume = 0;
976 }
977
978 Ar << CenterOfMass;
979 }
980 else if (Ar.IsLoading())
981 {
982 // Rebuild convex in order to extract face indices.
983 // @todo(chaos): Make it so it can take Vertices as both input and output without breaking...
986 FConvexBuilder::Build(Vertices, Planes, FaceIndices, TempVertices, LocalBoundingBox);
987
988 // Copy vertices and move into particles.
989 CalculateVolumeAndCenterOfMass(Vertices, FaceIndices, Volume, CenterOfMass);
990 }
991
994 {
996 Ar << MarginFloat;
998 }
999
1001 {
1002 Ar << StructureData;
1003 }
1004 else if (Ar.IsLoading())
1005 {
1006 // Generate the structure data from the planes and vertices
1009 CreateStructureData(MoveTemp(FaceIndices));
1010 }
1011
1012 if (Ar.CustomVer(FUE5ReleaseStreamObjectVersion::GUID) >= FUE5ReleaseStreamObjectVersion::AddedInertiaTensorAndRotationOfMassAddedToConvex)
1013 {
1014 Ar << UnitMassInertiaTensor;
1015 Ar << RotationOfMass;
1016 }
1017 else if (Ar.IsLoading())
1018 {
1019 ComputeUnitMassInertiaTensorAndRotationOfMass(Volume);
1020 }
1021 }
1022
1023 virtual void Serialize(FChaosArchive& Ar) override
1024 {
1026 SerializeImp(Ar);
1027 }
1028
1029 virtual void Serialize(FArchive& Ar) override
1030 {
1031 SerializeImp(Ar);
1032 }
1033
1034 virtual bool IsValidGeometry() const override
1035 {
1036 return (Vertices.Num() > 0 && Planes.Num() > 0);
1037 }
1038
1039 virtual bool IsPerformanceWarning() const override
1040 {
1041 return FConvexBuilder::IsPerformanceWarning(Planes.Num(), Vertices.Num());
1042 }
1043
1044 virtual FString PerformanceWarningAndSimplifaction() override
1045 {
1046
1047 FString PerformanceWarningString = FConvexBuilder::PerformanceWarningString(Planes.Num(), Vertices.Num());
1049 {
1050 PerformanceWarningString += ", [Simplifying]";
1052 }
1053
1054 return PerformanceWarningString;
1055 }
1056
1058 {
1060 FConvexBuilder::Simplify(Planes, FaceIndices, Vertices, LocalBoundingBox);
1061
1062 // @todo(chaos): Tolerances should be based on size, or passed in
1063 const FRealType DistanceTolerance = 1.0f;
1064 const FRealType AngleTolerance = 1.e-6f;
1065 FConvexBuilder::MergeFaces(Planes, FaceIndices, Vertices, DistanceTolerance);
1066 FConvexBuilder::MergeColinearEdges(Planes, FaceIndices, Vertices, AngleTolerance);
1067
1068 CreateStructureData(MoveTemp(FaceIndices));
1069 }
1070
1072 {
1073 return GetCenterOfMass();
1074 }
1075
1076#if INTEL_ISPC
1077 // See PerParticlePBDCollisionConstraint.cpp
1078 // ISPC code has matching structs for interpreting FImplicitObjects.
1079 // This is used to verify that the structs stay the same.
1080 struct FISPCDataVerifier
1081 {
1082 static constexpr int32 OffsetOfPlanes() { return offsetof(FConvex, Planes); }
1083 static constexpr int32 SizeOfPlanes() { return sizeof(FConvex::Planes); }
1084 static constexpr int32 OffsetOfVertices() { return offsetof(FConvex, Vertices); }
1085 static constexpr int32 SizeOfVertices() { return sizeof(FConvex::Vertices); }
1086 static constexpr int32 OffsetOfStructureData() { return offsetof(FConvex, StructureData); }
1087 static constexpr int32 SizeOfStructureData() { return sizeof(FConvex::StructureData); }
1088 };
1089 friend FISPCDataVerifier;
1090#endif // #if INTEL_ISPC
1091
1092 private:
1093 CHAOS_API void ComputeUnitMassInertiaTensorAndRotationOfMass(const FReal InVolume);
1094
1095 // IMPORTANT to keep this copy constructor private to avoid unintented expensive copies
1096 FConvex(const FConvex& Other)
1097 : FImplicitObject(EImplicitObject::IsConvex | EImplicitObject::HasBoundingBox, ImplicitObjectType::Convex)
1098 , Planes(Other.Planes)
1099 , Vertices(Other.Vertices)
1100 , LocalBoundingBox(Other.LocalBoundingBox)
1101 , Volume(Other.Volume)
1102 , CenterOfMass(Other.CenterOfMass)
1103 , UnitMassInertiaTensor(Other.UnitMassInertiaTensor)
1104 , RotationOfMass(Other.RotationOfMass)
1105 {
1106 StructureData.CopyFrom(Other.StructureData);
1107 SetMargin(Other.Margin);
1108 }
1109
1110 private:
1111 TArray<FPlaneType> Planes;
1112 TArray<FVec3Type> Vertices; //copy of the vertices that are just on the convex hull boundary
1113 FAABB3Type LocalBoundingBox;
1114 FConvexStructureData StructureData;
1115 FRealType Volume;
1116 FVec3Type CenterOfMass;
1117 FVec3 UnitMassInertiaTensor;
1118 FRotation3 RotationOfMass;
1119 };
1120}
#define FORCEINLINE
Definition AndroidPlatform.h:140
#define check(expr)
Definition AssertionMacros.h:314
#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
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 VectorRegister4Float VectorZeroFloat(void)
Definition UnrealMathFPU.h:331
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
UE_INTRINSIC_CAST UE_REWRITE constexpr std::remove_reference_t< T > && MoveTemp(T &&Obj) noexcept
Definition UnrealTemplate.h:520
uint32 Size
Definition VulkanMemory.cpp:4034
uint32_t uint32
Definition binka_ue_file_header.h:6
Definition ChaosArchive.h:364
Definition ChaosArchive.h:167
static void BuildPlaneVertexIndices(TArray< FPlaneType > &InPlanes, const TArray< FVec3Type > &Vertices, TArray< TArray< int32 > > &OutFaceVertexIndices, const FRealType DistanceTolerance=1.e-3f)
Definition CollisionConvexMesh.h:792
static CHAOS_API void Build(const TArray< FVec3Type > &InVertices, TArray< FPlaneType > &OutPlanes, TArray< TArray< int32 > > &OutFaceIndices, TArray< FVec3Type > &OutVertices, FAABB3Type &OutLocalBounds, EBuildMethod BuildMethod=EBuildMethod::Default)
Definition CollisionConvexMesh.cpp:108
static bool IsGeometryReductionEnabled()
Definition CollisionConvexMesh.h:361
static FString PerformanceWarningString(int32 NumPlanes, int32 NumVertices)
Definition CollisionConvexMesh.h:366
EBuildMethod
Definition CollisionConvexMesh.h:44
@ Default
Definition CollisionConvexMesh.h:45
@ ConvexHull3Simplified
Definition CollisionConvexMesh.h:48
static void Simplify(TArray< FPlaneType > &InOutPlanes, TArray< TArray< int32 > > &InOutFaces, TArray< FVec3Type > &InOutVertices, FAABB3Type &InOutLocalBounds)
Definition CollisionConvexMesh.h:371
static void MergeFaces(TArray< FPlaneType > &InOutPlanes, TArray< TArray< int32 > > &InOutFaceVertexIndices, const TArray< FVec3Type > &Vertices, FRealType DistanceThreshold)
Definition CollisionConvexMesh.h:506
static void MergeColinearEdges(TArray< FPlaneType > &InOutPlanes, TArray< TArray< int32 > > &InOutFaceVertexIndices, TArray< FVec3Type > &InOutVertices, FRealType AngleToleranceCos)
Definition CollisionConvexMesh.h:584
static bool IsPerformanceWarning(int32 NumPlanes, int32 NumVertices)
Definition CollisionConvexMesh.h:351
Definition ConvexStructureData.h:19
int32 GetEdgeVertex(int32 EdgeIndex, int32 EdgeVertexIndex) const
Definition ConvexStructureData.h:220
void GetHalfEdges(int32 EdgeIndex, int32 &OutEdgeIndex0, int32 &OutEdgeIndex1) const
Definition ConvexStructureData.h:250
void CopyFrom(const FConvexStructureData &Other)
Definition ConvexStructureData.h:131
int32 GetPlaneVertex(int32 PlaneIndex, int32 PlaneVertexIndex) const
Definition ConvexStructureData.h:197
int32 NumPlaneVertices(int32 PlaneIndex) const
Definition ConvexStructureData.h:189
int32 GetEdgePlane(int32 EdgeIndex, int32 EdgePlaneIndex) const
Definition ConvexStructureData.h:230
bool IsValid() const
Definition ConvexStructureData.h:157
int32 GetPlaneHalfEdge(int32 PlaneIndex, int32 FaceVertexIndex) const
Definition ConvexStructureData.h:240
int32 NumEdges() const
Definition ConvexStructureData.h:213
Definition Convex.h:26
bool IntersectPlanes3(const FVec3 &X1, const FVec3 &N1, const FVec3 &X2, const FVec3 &N2, const FVec3 &X3, const FVec3 &N3, FVec3 &OutX, const FReal EpsilonSq=FReal(1.e-6)) const
Definition Convex.h:593
FORCEINLINE void SerializeImp(FArchive &Ar)
Definition Convex.h:911
CHAOS_API Chaos::FImplicitObjectPtr CopyGeometryWithScale(const FVec3 &Scale) const override
Definition Convex.cpp:17
FString ToStringSummary() const
Definition Convex.h:818
CHAOS_API Chaos::FImplicitObjectPtr DeepCopyGeometry() const override
Definition Convex.cpp:23
FRealSingle TType
Definition Convex.h:30
virtual const FAABB3 BoundingBox() const override
Definition Convex.h:217
TAABB< FRealType, 3 > FAABB3Type
Definition Convex.h:34
bool HasStructureData() const
Definition Convex.h:407
int32 GetEdgePlane(int32 EdgeIndex, int32 EdgePlaneIndex) const
Definition Convex.h:468
virtual CHAOS_API int32 FindMostOpposingFaceScaled(const FVec3 &Position, const FVec3 &UnitDir, int32 HintFaceIndex, FReal SearchDist, const FVec3 &Scale) const override
Definition Convex.cpp:130
virtual FString ToString() const override
Definition Convex.h:812
TVec3< FRealType > FVec3Type
Definition Convex.h:32
virtual void Serialize(FArchive &Ar) override
Definition Convex.h:1029
const FPlaneType & GetPlaneRaw(int32 FaceIndex) const
Definition Convex.h:533
FConvex::FAABB3Type GetLocalBoundingBox() const
Definition Convex.h:223
static constexpr unsigned D
Definition Convex.h:36
CHAOS_API void MovePlanesAndRebuild(FRealType InDelta)
Definition Convex.cpp:338
const FReal GetVolume() const
Definition Convex.h:871
Chaos::FConvex * RawCopyAsConvex() const
Definition Convex.h:179
FVec3 GetMarginAdjustedVertex(const int32 VertexIndex, const FReal InMargin, FReal *OutSupportDelta) const
Definition Convex.h:617
const TArray< FVec3Type > & GetVertices() const
Definition Convex.h:861
FConvex()
Definition Convex.h:38
CHAOS_API Chaos::FImplicitObjectPtr DeepCopyGeometryWithScale(const FVec3 &Scale) const override
Definition Convex.cpp:28
static constexpr EImplicitObjectType StaticType()
Definition Convex.h:202
int32 NumVertices() const
Definition Convex.h:515
const FVec3Type & GetVertex(int32 VertexIndex) const
Definition Convex.h:539
virtual uint32 GetTypeHash() const override
Definition Convex.h:892
CHAOS_API Chaos::FImplicitObjectPtr CopyGeometry() const override
Definition Convex.cpp:11
int32 GetPlaneVertex(int32 PlaneIndex, int32 PlaneVertexIndex) const
Definition Convex.h:448
FVec3 GetCenter() const
Definition Convex.h:1071
FConvex & operator=(const FConvex &Other)=delete
virtual Pair< FVec3, bool > FindClosestIntersectionImp(const FVec3 &StartPoint, const FVec3 &EndPoint, const FReal Thickness) const override
Definition Convex.h:382
FVec3 SupportCore(const FVec3 &Direction, const FReal InMargin, FReal *OutSupportDelta, int32 &VertexIndex) const
Definition Convex.h:734
virtual FReal GetRadius() const override
Definition Convex.h:212
CHAOS_API int32 FindVertexPlanes(int32 VertexIndex, int32 *OutVertexPlanes, int32 MaxVertexPlanes) const
Definition Convex.cpp:308
FString ToStringFull() const
Definition Convex.h:824
void GetHalfEdges(int32 EdgeIndex, int32 &OutHalfEdge0, int32 &OutHalfEdge1) const
Definition Convex.h:488
VectorRegister4Float SupportCoreSimd(const VectorRegister4Float &Direction, const FReal InMargin) const
Definition Convex.h:746
virtual FReal PhiWithNormal(const FVec3 &X, FVec3 &Normal) const override
Definition Convex.h:229
const FMatrix33 GetInertiaTensor(const FReal Mass) const
Definition Convex.h:876
FConvex(TArray< FPlaneType > &&InPlanes, TArray< TArray< int32 > > &&InFaceIndices, TArray< FVec3Type > &&InVertices)
Definition Convex.h:81
FORCEINLINE FVec3 SupportScaled(const FVec3 &Direction, const FReal Thickness, const FVec3 &Scale, int32 &VertexIndex) const
Definition Convex.h:802
virtual FName GetTypeName() const
Definition ImplicitObject.h:414
int32 GetEdgeVertex(int32 EdgeIndex, int32 EdgeVertexIndex) const
Definition Convex.h:458
const FConvexStructureData & GetStructureData() const
Definition Convex.h:410
TType FRealType
Definition Convex.h:31
virtual CHAOS_API int32 FindMostOpposingFace(const FVec3 &Position, const FVec3 &UnitDir, int32 HintFaceIndex, FReal SearchDist) const override
Definition Convex.cpp:104
CHAOS_API int32 GetVertexPlanes3(int32 VertexIndex, int32 &PlaneIndex0, int32 &PlaneIndex1, int32 &PlaneIndex2) const
Definition Convex.cpp:317
CHAOS_API bool GetClosestEdgeVertices(int32 PlaneIndex, const FVec3 &Position, int32 &OutVertexIndex0, int32 &OutVertexIndex1) const
Definition Convex.cpp:273
int32 NumPlaneVertices(int32 PlaneIndex) const
Definition Convex.h:438
FVec3 SupportCoreScaled(const FVec3 &Direction, FReal InMargin, const FVec3 &Scale, FReal *OutSupportDelta, int32 &VertexIndex) const
Definition Convex.h:762
CHAOS_API int32 GetMostOpposingPlaneScaled(const FVec3 &Normal, const FVec3 &Scale) const
Definition Convex.cpp:212
int32 NumPlanes() const
Definition Convex.h:501
FConvex(TArray< FPlaneType > &&InPlanes, TArray< TArray< int32 > > &&InFaceIndices, TArray< FVec3Type > &&InVertices, const FVec3Type &InMin, const FVec3Type &InMax, const FRealType InVolume, const FVec3Type InInertiaTensor, const FRotation3 &InRotationMatrix, const bool bRegularDatas)
Definition Convex.h:100
int32 NumEdges() const
Definition Convex.h:506
const TArray< FPlaneType > & GetFaces() const
Definition Convex.h:866
virtual FString PerformanceWarningAndSimplifaction() override
Definition Convex.h:1044
CHAOS_API bool RaycastFast(const FVec3 &StartPoint, const FVec3 &Dir, const FReal Length, const FReal Thickness, FReal &OutTime, FVec3 &OutPosition, FVec3 &OutNormal, int32 &OutFaceIndex) const
Definition Convex.cpp:50
const TPlaneConcrete< FReal, 3 > GetPlane(int32 FaceIndex) const
Definition Convex.h:521
CHAOS_API int32 GetMostOpposingPlane(const FVec3 &Normal) const
Definition Convex.cpp:193
FReal GetWindingOrder() const
Definition Convex.h:565
virtual bool IsPerformanceWarning() const override
Definition Convex.h:1039
void GetPlaneNX(const int32 FaceIndex, FVec3 &OutN, FVec3 &OutX) const
Definition Convex.h:527
virtual FReal PhiWithNormalScaled(const FVec3 &X, const FVec3 &Scale, FVec3 &Normal) const override
Definition Convex.h:234
const FVec3 GetCenterOfMass() const
Definition Convex.h:887
TUniquePtr< FConvex > CopyAsConvex() const
Definition Convex.h:185
FConvex(FConvex &&Other)
Definition Convex.h:45
virtual FReal GetMargin() const override
Definition Convex.h:207
virtual bool IsValidGeometry() const override
Definition Convex.h:1034
FConvex & operator=(FConvex &&Other)
Definition Convex.h:153
FVec3 GetClosestEdgePosition(int32 PlaneIndex, const FVec3 &Position) const
Definition Convex.h:423
FVec3 FindGeometryOpposingNormal(const FVec3 &DenormDir, int32 FaceIndex, const FVec3 &OriginalNormal) const
Definition Convex.h:549
virtual void Serialize(FChaosArchive &Ar) override
Definition Convex.h:1023
virtual CHAOS_API int32 FindClosestFaceAndVertices(const FVec3 &Position, TArray< FVec3 > &FaceVertices, FReal SearchDist=0.01f) const override
Definition Convex.cpp:159
CHAOS_API FVec3 GetClosestEdge(int32 PlaneIndexHint, const FVec3 &Position, FVec3 &OutEdgePos0, FVec3 &OutEdgePos1) const
Definition Convex.cpp:233
int32 GetPlaneHalfEdge(int32 PlaneIndex, int32 PlaneEdgeIndex) const
Definition Convex.h:478
FORCEINLINE FVec3 Support(const FVec3 &Direction, const FReal Thickness, int32 &VertexIndex) const
Definition Convex.h:787
void SimplifyGeometry()
Definition Convex.h:1057
FVec3 GetMarginAdjustedVertexScaled(int32 VertexIndex, FReal InMargin, const FVec3 &Scale, FReal *OutSupportDelta) const
Definition Convex.h:676
FRotation3 GetRotationOfMass() const
Definition Convex.h:882
FConvex(const TArray< FVec3Type > &InVertices, const FReal InMargin, FConvexBuilder::EBuildMethod BuildMethod=FConvexBuilder::EBuildMethod::Default)
Definition Convex.h:116
Definition ImplicitObject.h:111
bool bHasBoundingBox
Definition ImplicitObject.h:574
CHAOS_API FReal SignedDistance(const FVec3 &x) const
Definition ImplicitObject.cpp:105
FRealSingle Margin
Definition ImplicitObject.h:571
bool HasBoundingBox() const
Definition ImplicitObject.h:275
EImplicitObjectType CollisionType
Definition ImplicitObject.h:586
bool bIsTracked
Definition ImplicitObject.h:577
EImplicitObjectType Type
Definition ImplicitObject.h:585
bool bDoCollide
Definition ImplicitObject.h:573
bool IsConvex() const
Definition ImplicitObject.h:277
CHAOS_API FImplicitObject(int32 Flags, EImplicitObjectType InType=ImplicitObjectType::Unknown)
Definition ImplicitObject.cpp:25
virtual FName GetTypeName() const
Definition ImplicitObject.h:414
CHAOS_API void SerializeImp(FArchive &Ar)
Definition ImplicitObject.cpp:337
void SetMargin(FReal InMargin)
Definition ImplicitObject.h:567
bool bIsConvex
Definition ImplicitObject.h:572
FORCEINLINE const TVector< T, d > & Max() const
Definition AABB.h:596
FORCEINLINE T GetVolume() const
Definition AABB.h:613
FORCEINLINE TVector< T, d > GetCenterOfMass() const
Definition AABB.h:452
FORCEINLINE void GrowToInclude(const TVector< T, d > &V)
Definition AABB.h:393
FORCEINLINE uint32 GetTypeHash() const
Definition AABB.h:665
FORCEINLINE const TVector< T, d > & Min() const
Definition AABB.h:595
static void SerializeAsAABB(FArchive &Ar, TAABB< T, d > &AABB)
Definition Box.h:467
Definition CorePlane.h:12
const TVec3< T > & Normal() const
Definition CorePlane.h:226
static FORCEINLINE TCorePlane< T > MakeFrom(const TCorePlane< U > &Plane)
Definition CorePlane.h:114
Definition Particles.h:32
Definition Vector.h:1000
Definition Archive.h:1208
virtual CORE_API void UsingCustomVersion(const struct FGuid &Guid)
Definition Archive.cpp:590
UE_FORCEINLINE_HINT bool IsLoading() const
Definition Archive.h:236
CORE_API int32 CustomVer(const struct FGuid &Key) const
Definition Archive.cpp:602
Definition Array.h:670
UE_NODEBUG UE_FORCEINLINE_HINT SizeType Add(ElementType &&Item)
Definition Array.h:2696
UE_NODEBUG void Sort()
Definition Array.h:3418
UE_FORCEINLINE_HINT void Reserve(SizeType Number)
Definition Array.h:3016
Definition UniquePtr.h:107
friend UE_FORCEINLINE_HINT uint32 GetTypeHash(const UE_STRING_CLASS &S)
Definition UnrealString.h.inl:2176
@ Convex
Definition ImplicitObjectType.h:21
Definition SkeletalMeshComponent.h:307
uint8 EImplicitObjectType
Definition ImplicitObjectType.h:41
@ X
Definition SimulationModuleBase.h:152
FRealDouble FReal
Definition Real.h:22
TRotation< FReal, 3 > FRotation3
Definition Core.h:19
TVector< T, d > FindClosestPointOnTriangle(const TVector< T, d > &ClosestPointOnPlane, const TVector< T, d > &P0, const TVector< T, d > &P1, const TVector< T, d > &P2, const TVector< T, d > &P)
Definition Plane.h:168
PMatrix< FReal, 3, 3 > FMatrix33
Definition Core.h:20
Pair< T1, T2 > MakePair(const T1 &First, const T2 &Second)
Definition Pair.h:45
float FRealSingle
Definition Real.h:14
void CalculateVolumeAndCenterOfMass(const FBox &BoundingBox, FVector::FReal &OutVolume, FVector &OutCenterOfMass)
Definition MassProperties.cpp:109
@ Raycast
Definition SimulationModuleBase.h:145
TVector< FReal, 3 > FVec3
Definition Core.h:17
TAABB< FReal, 3 > FAABB3
Definition ImplicitObject.h:34
U16 Index
Definition radfft.cpp:71
Definition Pair.h:8
CORE_API static const FGuid GUID
Definition ExternalPhysicsCustomObjectVersion.h:144
@ AddConvexCenterOfMassAndVolume
Definition ExternalPhysicsCustomObjectVersion.h:73
@ ConvexUsesTPlaneConcrete
Definition ExternalPhysicsCustomObjectVersion.h:106
CORE_API static const FGuid GUID
Definition FortniteMainBranchObjectVersion.h:21
static constexpr UE_FORCEINLINE_HINT T Square(const T A)
Definition UnrealMathUtility.h:578
@ ConvexUsesVerticesArray
Definition PhysicsObjectVersion.h:37
CORE_API static const FGuid GUID
Definition PhysicsObjectVersion.h:78
CORE_API static const FGuid GUID
Definition ReleaseObjectVersion.h:154
@ StructureDataAddedToConvex
Definition ReleaseObjectVersion.h:128
@ MarginAddedToConvexAndBox
Definition ReleaseObjectVersion.h:125
CORE_API static const FGuid GUID
Definition UE5MainStreamObjectVersion.h:22
CORE_API static const FGuid GUID
Definition UE5ReleaseStreamObjectVersion.h:22
Definition NumericLimits.h:41
Definition UnrealMathFPU.h:20