p.Chaos.CCD.NewTargetDepthMode
p.Chaos.CCD.NewTargetDepthMode
#Overview
name: p.Chaos.CCD.NewTargetDepthMode
This variable is created as a Console Variable (cvar).
- type:
Var
- help:
Find the first contact with that results in a penetration of (CCDAllowedDepthBoundsScale*Size) as opposed to the first contact
It is referenced in 9
C++ source files.
#Summary
#Usage in the C++ source code
The purpose of p.Chaos.CCD.NewTargetDepthMode is to control the behavior of Continuous Collision Detection (CCD) in Unreal Engine 5’s Chaos physics system. Specifically, it determines how the system finds contact points during collision detection.
This setting variable is primarily used in the Chaos physics subsystem, which is part of Unreal Engine’s experimental features. It is referenced in the collision detection and physics simulation code, particularly in the CCDUtilities, ContactPointsMiscShapes, HeightField, and TriangleMeshImplicitObject modules.
The value of this variable is set using an FAutoConsoleVariableRef, which means it can be modified at runtime through console commands. It is initialized to true by default.
The associated boolean variable bCCDNewTargetDepthMode interacts directly with this setting. They share the same value and are used interchangeably in the code.
Developers should be aware that when this variable is true (default), the CCD system will find the first contact that results in a penetration of (CCDAllowedDepthBoundsScale*Size), as opposed to simply finding the first contact when it’s false. This can significantly affect collision behavior, especially in scenarios involving complex geometries or fast-moving objects.
Best practices when using this variable include:
- Testing thoroughly when changing its value, as it can affect gameplay and physics simulations.
- Considering performance implications, as the new target depth mode might be more computationally expensive.
- Using it in conjunction with other CCD-related variables for fine-tuning collision detection.
Regarding the associated variable bCCDNewTargetDepthMode:
The purpose of bCCDNewTargetDepthMode is to serve as the actual boolean flag that controls the behavior described above. It is used directly in the physics code to determine which collision detection method to use.
This variable is used in the same Chaos physics subsystem modules as p.Chaos.CCD.NewTargetDepthMode.
Its value is set by the console variable p.Chaos.CCD.NewTargetDepthMode, allowing for runtime modification.
When using this variable, developers should be aware that it directly affects the collision detection logic in various parts of the Chaos physics system, including heightfields and triangle meshes.
Best practices include:
- Ensuring consistency when modifying this variable, as it’s used in multiple places throughout the physics code.
- Considering its impact on both performance and accuracy of collision detection.
- Using it as a quick way to toggle between different CCD behaviors for testing and optimization purposes.
#References in C++ code
#Callsites
This variable is referenced in the following C++ source code:
#Loc: <Workspace>/Engine/Source/Runtime/Experimental/Chaos/Private/Chaos/CCDUtilities.cpp:42
Scope (from outer to inner):
file
namespace Chaos
namespace CVars
Source code excerpt:
// could happen when colliding with the floor near the base of a ramp for example.
bool bCCDNewTargetDepthMode = true;
FAutoConsoleVariableRef CVarCCDNewTargetDepthMode(TEXT("p.Chaos.CCD.NewTargetDepthMode"), bCCDNewTargetDepthMode, TEXT("Find the first contact with that results in a penetration of (CCDAllowedDepthBoundsScale*Size) as opposed to the first contact"));
int32 CCDAxisThresholdMode = 2;
FAutoConsoleVariableRef CVarCCDAxisThresholdMode(TEXT("p.Chaos.CCD.AxisThresholdMode"), CCDAxisThresholdMode , TEXT("Change the mode used to generate CCD axis threshold bounds for particle geometries.\n0: Use object bounds\n1: Find the thinnest object bound on any axis and use it for all CCD axes\n2: On each axis, use the thinnest shape bound on that axis\n3: Find the thinnest shape bound on any axis and use this for all axes"));
bool bCCDAxisThresholdUsesProbeShapes = false;
FAutoConsoleVariableRef CVarCCDAxisThresholdUsesProbeShapes(TEXT("p.Chaos.CCD.CCDAxisThresholdUsesProbeShapes"), bCCDAxisThresholdUsesProbeShapes , TEXT("When true, probe shapes are considered for CCD axis threshold computation, and can generate contacts in the initial CCD phase."));
#Associated Variable and Callsites
This variable is associated with another variable named bCCDNewTargetDepthMode
. They share the same value. See the following C++ source code.
#Loc: <Workspace>/Engine/Source/Runtime/Experimental/Chaos/Private/Chaos/CCDUtilities.cpp:41
Scope (from outer to inner):
file
namespace Chaos
namespace CVars
Source code excerpt:
// This fixes the issue where (when disabled) we would set TOI to some value that would leave us penetrating another (later) object. This
// could happen when colliding with the floor near the base of a ramp for example.
bool bCCDNewTargetDepthMode = true;
FAutoConsoleVariableRef CVarCCDNewTargetDepthMode(TEXT("p.Chaos.CCD.NewTargetDepthMode"), bCCDNewTargetDepthMode, TEXT("Find the first contact with that results in a penetration of (CCDAllowedDepthBoundsScale*Size) as opposed to the first contact"));
int32 CCDAxisThresholdMode = 2;
FAutoConsoleVariableRef CVarCCDAxisThresholdMode(TEXT("p.Chaos.CCD.AxisThresholdMode"), CCDAxisThresholdMode , TEXT("Change the mode used to generate CCD axis threshold bounds for particle geometries.\n0: Use object bounds\n1: Find the thinnest object bound on any axis and use it for all CCD axes\n2: On each axis, use the thinnest shape bound on that axis\n3: Find the thinnest shape bound on any axis and use this for all axes"));
bool bCCDAxisThresholdUsesProbeShapes = false;
FAutoConsoleVariableRef CVarCCDAxisThresholdUsesProbeShapes(TEXT("p.Chaos.CCD.CCDAxisThresholdUsesProbeShapes"), bCCDAxisThresholdUsesProbeShapes , TEXT("When true, probe shapes are considered for CCD axis threshold computation, and can generate contacts in the initial CCD phase."));
#Loc: <Workspace>/Engine/Source/Runtime/Experimental/Chaos/Private/Chaos/Collision/ContactPointsMiscShapes.cpp:170
Scope (from outer to inner):
file
namespace Chaos
Source code excerpt:
// Calculate TOI to leave objects penetrating by TargetPhi. This is used by the legacy path that finds the first contacting shape pair and then ignores all others after that
// even if they would have a smaller TOI at TargetPenetration. It is only called if the low level sweep code has not already called ComputeSweptContactTOIAndPhiAtTargetPenetration.
// See CVars::bCCDNewTargetDepthMode
void LegacyComputeSweptContactTOIAndPhiAtTargetPenetration(const FReal DirDotNormal, const FReal Length, const FReal IgnorePenetration, const FReal TargetPenetration, FReal& InOutTOI, FReal& InOutPhi)
{
if (InOutTOI <= 1)
{
if (InOutTOI != 0)
{
#Loc: <Workspace>/Engine/Source/Runtime/Experimental/Chaos/Private/Chaos/HeightField.cpp:25
Scope (from outer to inner):
file
namespace Chaos
namespace CVars
Source code excerpt:
namespace CVars
{
extern bool bCCDNewTargetDepthMode;
}
extern FRealSingle Chaos_Collision_EdgePrunePlaneDistance;
extern bool bChaos_Collision_OneSidedHeightField;
#Loc: <Workspace>/Engine/Source/Runtime/Experimental/Chaos/Private/Chaos/HeightField.cpp:2231
Scope (from outer to inner):
file
namespace Chaos
function bool FHeightField::SweepGeomCCDImp
Source code excerpt:
{
// Emulate the old TargetPenetration mode which always uses the first contact encountered, as opposed to the first contact which reaches a depth of TargetPenetration
const FReal IgnorePenetration = CVars::bCCDNewTargetDepthMode ? InIgnorePenetration : 0;
const FReal TargetPenetration = CVars::bCCDNewTargetDepthMode ? InTargetPenetration : 0;
const FAABB3 QueryBounds = QueryGeom.BoundingBox().TransformedAABB(FRigidTransform3(FVec3(0), StartTM.GetRotation()));
bool bHit = false;
THeightfieldSweepVisitorCCD<QueryGeomType> SQVisitor(&GeomData, QueryGeom, QueryBounds, StartTM, Dir, Length, IgnorePenetration, TargetPenetration);
const FVec3 StartPoint = StartTM.TransformPositionNoScale(QueryBounds.Center());
#Loc: <Workspace>/Engine/Source/Runtime/Experimental/Chaos/Private/Chaos/HeightField.cpp:2249
Scope (from outer to inner):
file
namespace Chaos
function bool FHeightField::SweepGeomCCDImp
Source code excerpt:
{
// @todo(chaos): Legacy path to be removed when fully tested. See ComputeSweptContactTOIAndPhiAtTargetPenetration
if (!CVars::bCCDNewTargetDepthMode)
{
LegacyComputeSweptContactTOIAndPhiAtTargetPenetration(FVec3::DotProduct(Dir, SQVisitor.OutNormal), Length, InIgnorePenetration, InTargetPenetration, TOI, Phi);
}
OutTOI = TOI;
OutPhi = Phi;
#Loc: <Workspace>/Engine/Source/Runtime/Experimental/Chaos/Private/Chaos/TriangleMeshImplicitObject.cpp:20
Scope (from outer to inner):
file
namespace Chaos
namespace CVars
Source code excerpt:
namespace CVars
{
extern bool bCCDNewTargetDepthMode;
}
extern FRealSingle Chaos_Collision_EdgePrunePlaneDistance;
// Note that if this is re-enabled when previously off, the cooked trimeshes won't have the vertex map serialized, so the change will not take effect until re-cooked.
bool TriMeshPerPolySupport = 1;
#Loc: <Workspace>/Engine/Source/Runtime/Experimental/Chaos/Private/Chaos/TriangleMeshImplicitObject.cpp:1682
Scope (from outer to inner):
file
namespace Chaos
function bool FTriangleMeshImplicitObject::SweepGeomCCDImp
lambda-function
Source code excerpt:
{
// Emulate the old TargetPenetration mode which always uses the first contact encountered, as opposed to the first contact which reaches a depth of TargetPenetration
const FReal IgnorePenetration = CVars::bCCDNewTargetDepthMode ? InIgnorePenetration : 0;
const FReal TargetPenetration = CVars::bCCDNewTargetDepthMode ? InTargetPenetration : 0;
const FReal CullsBackFaceRaycastCode = bCullsBackFaceRaycast ? GetWindingOrder(TriMeshScale) : 0.f;
using VisitorType = FTriangleMeshSweepVisitorCCD<QueryGeomType, decltype(Elements[0][0])>;
VisitorType SQVisitor(*this, Elements, QueryGeom, ScaledDirNormalized, LengthScale, Length, ScaledStartTM, TriMeshScale, CullsBackFaceRaycastCode, IgnorePenetration, TargetPenetration);
const FAABB3 QueryBounds = QueryGeom.CalculateTransformedBounds(FRigidTransform3(FVec3::ZeroVector, StartTM.GetRotation()));
#Loc: <Workspace>/Engine/Source/Runtime/Experimental/Chaos/Private/Chaos/TriangleMeshImplicitObject.cpp:1699
Scope (from outer to inner):
file
namespace Chaos
function bool FTriangleMeshImplicitObject::SweepGeomCCDImp
lambda-function
Source code excerpt:
// @todo(chaos): Legacy path to be removed when fully tested. See ComputeSweptContactTOIAndPhiAtTargetPenetration
if (!CVars::bCCDNewTargetDepthMode)
{
LegacyComputeSweptContactTOIAndPhiAtTargetPenetration(FVec3::DotProduct(Dir, SQVisitor.OutNormal), LengthScale * Length, InIgnorePenetration, InTargetPenetration, TOI, Phi);
}
if (TOI <= 1)
{