Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
25 commits
Select commit Hold shift + click to select a range
f644a33
Initial non-working DeformableTerrainWheel made by friend
May 20, 2026
4c7b87d
Add support for TerrainWheelForceModel in contact material
May 26, 2026
03abb11
Indentation fix
May 26, 2026
c7fbc5d
Adjusted agxdotnet for terrain friction model moved to agx, and alias…
May 26, 2026
65cd0af
Add all WheelDeformationProperties as properties on the component (fo…
May 26, 2026
3eabc04
Also terrain wheel settings (for now)
May 26, 2026
838a680
Terrain height change renderer
May 27, 2026
db1ae2e
Hide contact material fields if using TerrainWheelForceModel
Jun 4, 2026
f97cdfb
Configure contact material to ensure correct solver is used etc
Jun 4, 2026
7778264
Setting to warn if using íncorrect contact material
Jun 4, 2026
557e629
Remove debug settings, fix initialization bug
Jun 4, 2026
5835312
Merge branch 'master' into feature/wheel-terrain
Jun 4, 2026
3081378
Icon
Jun 4, 2026
1f8438e
Profiling for terrain height change renderer
Jun 4, 2026
037ec32
Add TerrainWheelDebugRenderer and move settings for terrain wheel to …
Jun 4, 2026
d6405b8
Field to property
Jun 4, 2026
8a96a53
Menu alternatives for terrain wheel and settings
Jun 5, 2026
022fafb
Merge branch 'master' into feature/wheel-terrain
Jun 8, 2026
4a33391
Remove wheel debug rendering for now
Jun 8, 2026
8d9cd73
Fix error when not having FM
Jun 9, 2026
41b7398
Fix for legacy rules for attributes
Jun 9, 2026
bef71ce
Missing shapematerial bug workaround
Jun 9, 2026
2c74cfd
Start of terrain wheel tests
Jun 9, 2026
aa508c1
Add tests with terrain contacts
Jun 9, 2026
58438d3
Add test with correct friction model
Jun 9, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 19 additions & 1 deletion AGXUnity/ContactMaterial.cs
Original file line number Diff line number Diff line change
Expand Up @@ -128,6 +128,7 @@ public FrictionModel FrictionModel
/// Get or set Young's modulus of this contact material.
/// </summary>
[ClampAboveZeroInInspector]
[DynamicallyShowInInspector( nameof( IsNotTerrainWheelForceModel ) )]
[Tooltip( "This specifies the stiffness of the contact between the interacting geometries/bodies" )]
public float YoungsModulus
{
Expand All @@ -150,6 +151,7 @@ public float YoungsModulus
/// Get or set surface viscosity of this contact material.
/// </summary>
[ClampAboveZeroInInspector( true )]
[DynamicallyShowInInspector( nameof( IsNotTerrainWheelForceModel ) )]
[Tooltip( "The viscosity of a surface material is the same thing as compliance but for friction in contacts" )]
public Vector2 SurfaceViscosity
{
Expand All @@ -174,6 +176,7 @@ public Vector2 SurfaceViscosity
/// Get or set friction coefficients of this contact material.
/// </summary>
[ClampAboveZeroInInspector( true )]
[DynamicallyShowInInspector( nameof( IsNotTerrainWheelForceModel ) )]
[Tooltip( "The coefficients of friction in the friction frame (default: world frame)" )]
public Vector2 FrictionCoefficients
{
Expand All @@ -198,6 +201,7 @@ public Vector2 FrictionCoefficients
/// Get or set restitution of this contact material.
/// </summary>
[ClampAboveZeroInInspector( true )]
[DynamicallyShowInInspector( nameof( IsNotTerrainWheelForceModel ) )]
[Tooltip( "This defines the \"bounciness\" of a contact." )]
public float Restitution
{
Expand Down Expand Up @@ -242,6 +246,7 @@ public float Damping
/// Adhesive force of the contacts with this contact material.
/// </summary>
[ClampAboveZeroInInspector( true )]
[DynamicallyShowInInspector( nameof( IsNotTerrainWheelForceModel ) )]
[Tooltip( "Determines a force used for keeping colliding objects together" )]
public float AdhesiveForce
{
Expand All @@ -266,6 +271,7 @@ public float AdhesiveForce
/// at higher overlap, the (usual) contact force.
/// </summary>
[ClampAboveZeroInInspector( true )]
[DynamicallyShowInInspector( nameof( IsNotTerrainWheelForceModel ) )]
[Tooltip( "allowed overlap from surface for resting contact. At this overlap, no force is applied. At lower overlap, the adhesion force will work, at higher overlap, the (usual) contact force" )]
public float AdhesiveOverlap
{
Expand All @@ -287,6 +293,7 @@ public float AdhesiveOverlap
/// <summary>
/// Enable/disable contact area approach of contacts using this contact material.
/// </summary>
[DynamicallyShowInInspector( nameof( IsNotTerrainWheelForceModel ) )]
[Tooltip( "If set to “true”, an approximation to the contact area will be geometrically computed for each contact involving this contact material. For each contact, its area will then be evenly distributed between its contact points. The contact compliance will be scaled with the inverse of the area for each contact point." )]
public bool UseContactArea
{
Expand All @@ -308,6 +315,7 @@ public bool UseContactArea
/// <summary>
/// Contact reduction mode, default Geometry.
/// </summary>
[DynamicallyShowInInspector( nameof( IsNotTerrainWheelForceModel ) )]
[Tooltip( " Specifies at which level the contact reduction algorithm should be run. None, Geometry, or Geometry and Rigidbody" )]
public ContactReductionType ContactReductionMode
{
Expand All @@ -329,6 +337,7 @@ public ContactReductionType ContactReductionMode
/// <summary>
/// Contact reduction level when contact reduction is enabled (ContactReductionMode != None).
/// </summary>
[DynamicallyShowInInspector( nameof( IsNotTerrainWheelForceModel ) )]
[Tooltip( "Contact reduction level when contact reduction is enabled (ContactReductionMode != None)" )]
public ContactReductionLevelType ContactReductionLevel
{
Expand Down Expand Up @@ -362,6 +371,7 @@ public ContactReductionLevelType ContactReductionLevel
/// The primary (x) friction coefficient is used along the wire and the secondary (y) is
/// along the contact edge on the object the wire interacts with.
/// </summary>
[DynamicallyShowInInspector( nameof( IsNotTerrainWheelForceModel ) )]
[ClampAboveZeroInInspector( true )]
[Tooltip( "Wire friction coefficients of this contact material, used by the contact nodes on a wire. The primary (x) friction coefficient is used along the wire and the secondary (y) is along the contact edge on the object the wire interacts with." )]
public Vector2 WireFrictionCoefficients
Expand All @@ -377,6 +387,8 @@ public Vector2 WireFrictionCoefficients
}
}

private bool IsNotTerrainWheelForceModel => (FrictionModel != null) ? FrictionModel.IsNotTerrainWheelForceModel : true;

public ContactMaterial RestoreLocalDataFrom( agx.ContactMaterial contactMaterial )
{
YoungsModulus = Convert.ToSingle( contactMaterial.getYoungsModulus() );
Expand Down Expand Up @@ -478,7 +490,13 @@ protected override bool Initialize()
m_contactMaterial = GetSimulation().getMaterialManager().getOrCreateContactMaterial( m1, m2 );

if ( FrictionModel != null ) {
m_contactMaterial.setFrictionModel( FrictionModel.GetInitialized<FrictionModel>().Native );
if ( FrictionModel.Type == FrictionModel.EType.TerrainWheelForceModel ) {
agxTerrain.TerrainWheel.configureContactMaterial( m_contactMaterial );
}
else {
m_contactMaterial.setFrictionModel( FrictionModel.GetInitialized<FrictionModel>().Native );
}

// When the user changes friction model type (enum = BoxFriction, ScaleBoxFriction etc.)
// the friction model object will create a new native instance. We'll receive callbacks
// when this happens so we can assign it to our native contact material.
Expand Down
20 changes: 17 additions & 3 deletions AGXUnity/FrictionModel.cs
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,8 @@ public enum EType
IterativeProjectedFriction = 0,
ScaleBoxFriction,
BoxFriction,
ConstantNormalForceBoxFriction
ConstantNormalForceBoxFriction,
TerrainWheelForceModel
}

public enum PrimaryDirection
Expand Down Expand Up @@ -86,6 +87,8 @@ public static EType FindType( agx.FrictionModel native )
{
if ( native == null || native.asIterativeProjectedConeFriction() != null )
return EType.IterativeProjectedFriction;
else if ( native.asTerrainWheelForceModel() != null )
return EType.TerrainWheelForceModel;
else if ( native.asScaleBoxFrictionModel() != null )
return EType.ScaleBoxFriction;
else if ( native.asConstantNormalForceOrientedBoxFrictionModel() != null )
Expand All @@ -112,6 +115,7 @@ public static EType FindType( agx.FrictionModel native )
/// <summary>
/// Get or set solve type of this friction model.
/// </summary>
[DynamicallyShowInInspector( nameof( IsNotTerrainWheelForceModel ) )]
[Tooltip( "Get or set solve type of this friction model." )]
public ESolveType SolveType
{
Expand Down Expand Up @@ -148,12 +152,14 @@ public ESolveType SolveType
/// * Scale Box - Will attempt to scale the friction bounds throughout the solve stage.
/// * Box - Has fixed friction bounds throughout the solve stage, performant but low accuracy. Makes a guess at the normal force to solve for friction.
/// * Constant Normal Force Box - Like Box, but will use a provided constant normal force magnitude.
/// * Terrain Wheel Force Model - Special model used for cylinder / terrain frictions. Used with TerrainWheel component.
/// </summary>
[Tooltip( "Specifies the friction model to use for this contact materials using this asset.\n" +
"* Iterative Projected Cone - The default model. Provides a good base model which handles anisotripic frictions better than the box models.\n" +
"* Scale Box - Will attempt to scale the friction bounds throughout the solve stage.\n" +
"* Box - Has fixed friction bounds throughout the solve stage, performant but low accuracy. Makes a guess at the normal force to solve for friction.\n" +
"* Constant Normal Force Box - Like Box, but will use a provided constant normal force magnitude." )]
"* Constant Normal Force Box - Like Box, but will use a provided constant normal force magnitude." +
"* Terrain Wheel Force Model - Special model used for cylinder / terrain frictions. Used with TerrainWheel component." )]
public EType Type
{
get { return m_type; }
Expand All @@ -177,6 +183,8 @@ public EType Type
/// Enable to mark that this friction model will be used for ContactMaterials involving track. This allows the friction frame to be set up automatically for these materials.
/// </summary>
[Tooltip( "Enable to mark that this friction model will be used for ContactMaterials involving track. This allows the friction frame to be set up automatically for these materials" )]
[DynamicallyShowInInspector( nameof( IsNotTerrainWheelForceModel ) )]

public bool TrackFrictionModel { get; set; } = false;

/// <summary>
Expand All @@ -186,7 +194,10 @@ public EType Type
[SerializeField]
private float m_normalForceMagnitude = 100.0f;

[HideInInspector]
private bool IsConstantNormalForceModel => Type == EType.ConstantNormalForceBoxFriction;
[HideInInspector]
public bool IsNotTerrainWheelForceModel => Type != EType.TerrainWheelForceModel;

/// <summary>
/// Normal force magnitude used in ConstantNormalForceBoxFriction.
Expand Down Expand Up @@ -271,7 +282,10 @@ public agx.FrictionModel CreateNative( EType type,

agx.FrictionModel frictionModel = null;

if ( TrackFrictionModel ) {
if ( type == EType.TerrainWheelForceModel) {
frictionModel = new agx.TerrainWheelForceModel();
}
else if ( TrackFrictionModel ) {
frictionModel = type switch
{
EType.IterativeProjectedFriction => new agxVehicle.TrackIterativeProjectedConeFrictionModel( Convert( solveType ) ),
Expand Down
Loading
Loading