diff --git a/AGXUnity/Model/DeformableTerrain.cs b/AGXUnity/Model/DeformableTerrain.cs index aa3c3b9a..2a49c43b 100644 --- a/AGXUnity/Model/DeformableTerrain.cs +++ b/AGXUnity/Model/DeformableTerrain.cs @@ -2,9 +2,7 @@ using AGXUnity.Collide; using AGXUnity.Utils; using System; -using System.Collections.Generic; using UnityEngine; -using GUI = AGXUnity.Utils.GUI; namespace AGXUnity.Model { @@ -42,37 +40,6 @@ public Terrain Terrain [HideInInspector] public int TerrainDataResolution { get { return TerrainUtils.TerrainDataResolution( TerrainData ); } } - [SerializeField] - private List m_shovels = new List(); - - [SerializeField] - private bool m_tempDisplayShovelForces = false; - - [HideInInspector] - public bool TempDisplayShovelForces - { - get { return m_tempDisplayShovelForces; } - set - { - m_tempDisplayShovelForces = value; - - if ( !Application.isPlaying ) - return; - - if ( m_tempDisplayShovelForces && - Shovels.Length > 0 && - GUIWindowHandler.Instance.GetWindowData( ShowForces ) == null ) { - var windowSize = new Vector2( 750, 125 ); - GUIWindowHandler.Instance.Show( ShowForces, - windowSize, - new Vector2( Screen.width - windowSize.x - 20, 20 ), - "Shovel forces" ); - } - else if ( !m_tempDisplayShovelForces && GUIWindowHandler.HasInstance ) - GUIWindowHandler.Instance.Close( ShowForces ); - } - } - /// /// Resets heights of the Unity terrain and recreate native instance. /// @@ -104,8 +71,6 @@ protected override bool Initialize() // Only printing the errors if something is wrong. LicenseManager.LicenseInfo.HasModuleLogError( LicenseInfo.Module.AGXTerrain | LicenseInfo.Module.AGXGranular, this ); - RemoveInvalidShovels( true, true ); - m_initialHeights = TerrainData.GetHeights( 0, 0, TerrainDataResolution, TerrainDataResolution ); InitializeNative(); @@ -135,9 +100,6 @@ protected override void OnDestroy() } Native = null; - if ( GUIWindowHandler.HasInstance ) - GUIWindowHandler.Instance.Close( ShowForces ); - base.OnDestroy(); } @@ -156,10 +118,6 @@ private void InitializeNative() Native.setTransform( Utils.TerrainUtils.CalculateNativeOffset( transform, TerrainData ) ); - - foreach ( var shovel in Shovels ) - Native.add( shovel.GetInitialized()?.Native ); - GetSimulation().add( Native ); } @@ -209,50 +167,6 @@ private void UpdateHeights( agxTerrain.ModifiedVerticesVector modifiedVertices ) TerrainData.SyncHeightmap(); } - private GUIStyle m_textLabelStyle = null; - private void ShowForces( EventType eventType ) - { - if ( m_textLabelStyle == null ) { - m_textLabelStyle = new GUIStyle( GUI.Skin.label ); - m_textLabelStyle.alignment = TextAnchor.MiddleLeft; - - var fonts = Font.GetOSInstalledFontNames(); - foreach ( var font in fonts ) { - if ( font == "Consolas" ) { - m_textLabelStyle.font = Font.CreateDynamicFontFromOSFont( font, 24 ); - break; - } - } - } - - var textColor = Color.Lerp( Color.black, Color.white, 1.0f ); - var valueColor = Color.Lerp( Color.green, Color.white, 0.45f ); - Func Vec3Content = ( name, v ) => - { - return GUI.MakeLabel( string.Format( "{0} [{1}, {2}, {3}] kN", - GUI.AddColorTag( name, textColor ), - GUI.AddColorTag( v.x.ToString( "0.00" ).PadLeft( 7, ' ' ), valueColor ), - GUI.AddColorTag( v.y.ToString( "0.00" ).PadLeft( 7, ' ' ), valueColor ), - GUI.AddColorTag( v.z.ToString( "0.00" ).PadLeft( 7, ' ' ), valueColor ) ) ); - }; - - var shovel = m_shovels[ 0 ].Native; - var penetrationForce = new agx.Vec3(); - var penetrationTorque = new agx.Vec3(); - Native.getPenetrationForce( shovel, ref penetrationForce, ref penetrationTorque ); - var separationForce = -Native.getSeparationContactForce( shovel ); - var deformerForce = -Native.getDeformationContactForce( shovel ); - var contactForce = -Native.getContactForce( shovel ); - - GUILayout.Label( Vec3Content( "Penetration force:", 1.0E-3 * penetrationForce ), m_textLabelStyle ); - GUILayout.Space( 4 ); - GUILayout.Label( Vec3Content( "Separation force: ", 1.0E-3 * separationForce ), m_textLabelStyle ); - GUILayout.Space( 4 ); - GUILayout.Label( Vec3Content( "Deformer force: ", 1.0E-3 * deformerForce ), m_textLabelStyle ); - GUILayout.Space( 4 ); - GUILayout.Label( Vec3Content( "Contact force: ", 1.0E-3 * contactForce ), m_textLabelStyle ); - } - private Terrain m_terrain = null; private float[,] m_initialHeights = null; @@ -260,57 +174,11 @@ private void ShowForces( EventType eventType ) // ------------------------------- Implementation of DeformableTerrainBase ----------------------------------- // ----------------------------------------------------------------------------------------------------------- public override float ElementSize => TerrainData.size.x / ( TerrainDataResolution - 1 ); - public override DeformableTerrainShovel[] Shovels => m_shovels.ToArray(); public override agx.GranularBodyPtrArray GetParticles() { return Native?.getSoilSimulationInterface()?.getSoilParticles(); } public override Uuid GetParticleMaterialUuid() => Native?.getMaterial( agxTerrain.Terrain.MaterialType.PARTICLE ).getUuid(); public override agxTerrain.SoilSimulationInterface GetSoilSimulationInterface() { return Native?.getSoilSimulationInterface(); } public override agxTerrain.TerrainProperties GetProperties() { return Native?.getProperties(); } - public override bool Add( DeformableTerrainShovel shovel ) - { - if ( shovel == null || m_shovels.Contains( shovel ) ) - return false; - - m_shovels.Add( shovel ); - - // Initialize shovel if we're initialized. - if ( Native != null ) - Native.add( shovel.GetInitialized().Native ); - - return true; - } - - public override bool Remove( DeformableTerrainShovel shovel ) - { - if ( shovel == null || !m_shovels.Contains( shovel ) ) - return false; - - if ( Native != null ) - Native.remove( shovel.Native ); - - return m_shovels.Remove( shovel ); - } - - public override bool Contains( DeformableTerrainShovel shovel ) - { - return shovel != null && m_shovels.Contains( shovel ); - } - - public override void RemoveInvalidShovels( bool removeDisabled = false, bool warn = false ) - { - m_shovels.RemoveAll( shovel => shovel == null ); - if ( removeDisabled ) { - int removed = m_shovels.RemoveAll( shovel => !shovel.isActiveAndEnabled ); - if ( removed > 0 ) { - if ( warn ) - Debug.LogWarning( $"Removed {removed} disabled shovels from terrain {gameObject.name}." + - " Disabled shovels should not be added to the terrain on play and should instead be added manually when enabled during runtime." + - " To fix this warning, please remove any disabled shovels from the terrain." ); - else - Debug.Log( $"Removed {removed} disabled shovels from terrain {gameObject.name}." ); - } - } - } public override void ConvertToDynamicMassInShape( Shape failureVolume ) { if ( !IsNativeNull() ) diff --git a/AGXUnity/Model/DeformableTerrainBase.cs b/AGXUnity/Model/DeformableTerrainBase.cs index 7cb5a771..3a17851c 100644 --- a/AGXUnity/Model/DeformableTerrainBase.cs +++ b/AGXUnity/Model/DeformableTerrainBase.cs @@ -140,12 +140,6 @@ public float MaximumDepth /// abstract public float ElementSize { get; } - /// - /// Shovels associated to this terrain. - /// - [HideInInspector] - abstract public DeformableTerrainShovel[] Shovels { get; } - protected override void OnEnable() { SetEnable( true ); @@ -183,33 +177,6 @@ protected override void OnDisable() /// virtual public void OnPropertiesUpdated() { } - /// - /// Associate shovel instance to this terrain. - /// - /// Shovel instance to add. - /// True if added, false if null or already added. - abstract public bool Add( DeformableTerrainShovel shovel ); - - /// - /// Disassociate shovel instance to this terrain. - /// - /// Shovel instance to remove. - /// True if removed, false if null or not associated to this terrain. - abstract public bool Remove( DeformableTerrainShovel shovel ); - - /// - /// Find if shovel has been associated to this terrain. - /// - /// Shovel instance to check. - /// True if associated, otherwise false. - abstract public bool Contains( DeformableTerrainShovel shovel ); - - /// - /// Verifies so that all added shovels still exists. Shovels that - /// has been deleted are removed. - /// - abstract public void RemoveInvalidShovels( bool removeDisabled = false, bool warn = false ); - /// /// Converts any part of the terrain that overlaps the provided shape into dynamic mass /// diff --git a/AGXUnity/Model/DeformableTerrainPager.cs b/AGXUnity/Model/DeformableTerrainPager.cs index bbd656b6..aac40479 100644 --- a/AGXUnity/Model/DeformableTerrainPager.cs +++ b/AGXUnity/Model/DeformableTerrainPager.cs @@ -38,6 +38,7 @@ public class DeformableTerrainPager : DeformableTerrainBase [SerializeField] private List> m_shovels = new List>(); + /// /// Shovels along with their respective load radii that are associated with this terrainPager /// @@ -47,6 +48,12 @@ public class DeformableTerrainPager : DeformableTerrainBase [HideInInspector] public PagingBody[] PagingShovels { get { return m_shovels.ToArray(); } } + /// + /// Rigidbodies associated to this terrain. + /// + [HideInInspector] + public DeformableTerrainShovel[] Shovels { get { return m_shovels.Select( rb => rb.Body ).ToArray(); } } + [SerializeField] private List> m_rigidbodies = new List>(); @@ -178,6 +185,23 @@ public bool Add( DeformableTerrainShovel shovel, float requiredRadius = 5, float return true; } + /// + /// Disassociate shovel instance to this terrain. + /// + /// Shovel instance to remove. + /// True if removed, false if null or not associated to this terrain. + public bool Remove( DeformableTerrainShovel shovel ) + { + if ( shovel == null || m_shovels.Find( pagingRigidBody => pagingRigidBody.Body == shovel ) == null ) + return false; + + if ( Native != null ) + Native.remove( shovel.Native ); + + m_shovels.RemoveAt( m_shovels.FindIndex( pagingRigidBody => pagingRigidBody.Body == shovel ) ); + return true; + } + /// /// Associates the given rigidbody instance to this terrain. /// @@ -316,8 +340,6 @@ protected override bool Initialize() if ( AutoTileOnPlay ) RecalculateParameters(); - RemoveInvalidShovels( true ); - // Create a new adapter using the terrain attached to this gameobject as the root // This attaches DeformableTerrainConnector components to each connected Unity terrain which must be done before InitializeNative is called m_terrainDataSource = new UnityTerrainAdapter( Terrain, MaximumDepth ); @@ -370,6 +392,8 @@ private void InitializeNative() Native.setTerrainDataSource( m_terrainDataSource ); Native.setShouldStoreCompaction( m_compactionStoreDepth.UseOverride, (uint)m_compactionStoreDepth.OverrideValue ); + GetSimulation().add( Native ); + // Add Rigidbodies and shovels to pager foreach ( var shovel in m_shovels ) Native.add( shovel.Body.GetInitialized().Native, shovel.requiredRadius, shovel.preloadRadius ); @@ -378,9 +402,6 @@ private void InitializeNative() if ( MaterialPatches.Length != 0 ) Debug.LogWarning( "Nonhomogenous terrain is not yet supported for DeformableTerrainPager.", this ); - - - GetSimulation().add( Native ); } protected override void OnDestroy() @@ -590,50 +611,11 @@ public static bool IsInteger( float v ) // ----------------------------------------------------------------------------------------------------------- public override float ElementSize => TerrainData.size.x / ( TerrainDataResolution - 1 ); - public override DeformableTerrainShovel[] Shovels => m_shovels.Select( shovel => shovel.Body ).ToArray(); public override agx.GranularBodyPtrArray GetParticles() { return Native?.getSoilSimulationInterface()?.getSoilParticles(); } public override agx.Uuid GetParticleMaterialUuid() => Native?.getTemplateTerrain()?.getMaterial( agxTerrain.Terrain.MaterialType.PARTICLE ).getUuid(); public override agxTerrain.TerrainProperties GetProperties() { return Native?.getTemplateTerrain()?.getProperties(); } public override agxTerrain.SoilSimulationInterface GetSoilSimulationInterface() { return Native?.getSoilSimulationInterface(); } public override void OnPropertiesUpdated() { Native?.applyChangesToTemplateTerrain(); } - public override bool Add( DeformableTerrainShovel shovel ) - { - return Add( shovel, requiredRadius: default, preloadRadius: default ); - } - public override bool Remove( DeformableTerrainShovel shovel ) - { - if ( shovel == null || m_shovels.Find( pagingShovel => pagingShovel.Body == shovel ) == null ) - return false; - - if ( Native != null ) - Native.remove( shovel.Native ); - - m_shovels.RemoveAt( m_shovels.FindIndex( pagingShovel => pagingShovel.Body == shovel ) ); - return true; - } - public override bool Contains( DeformableTerrainShovel shovel ) - { - return m_shovels.Find( s => s.Body == shovel ) != null; - } - public override void RemoveInvalidShovels( bool removeDisabled = false, bool warn = false ) - { - m_shovels.RemoveAll( shovel => shovel.Body == null ); - m_rigidbodies.RemoveAll( rb => rb.Body == null ); - - if ( removeDisabled ) { - int remShovels = m_shovels.RemoveAll( shovel => !shovel.Body.isActiveAndEnabled ); - int remRBs = m_rigidbodies.RemoveAll( rb => !rb.Body.isActiveAndEnabled ); - if ( remShovels + remRBs > 0 ) { - if ( warn ) - Debug.LogWarning( $"Removed {remShovels} disabled shovels and {remRBs} disabled rigid bodies from terrain {gameObject.name}." + - " Disabled objects should not be added to the terrain on play and should instead be added manually when enabled during runtime." + - " To fix this warning, please remove any disabled objects from the terrain." ); - else - Debug.Log( $"Removed {remShovels} disabled shovels and {remRBs} disabled rigid bodies from terrain {gameObject.name}." ); - - } - } - } public override void ConvertToDynamicMassInShape( Shape failureVolume ) { if ( Native != null ) { diff --git a/AGXUnity/Model/DeformableTerrainShovel.cs b/AGXUnity/Model/DeformableTerrainShovel.cs index 582cb2c7..41735249 100644 --- a/AGXUnity/Model/DeformableTerrainShovel.cs +++ b/AGXUnity/Model/DeformableTerrainShovel.cs @@ -84,20 +84,6 @@ public DeformableTerrainShovelSettings Settings } } - [SerializeField] - private bool m_autoAddToTerrains = false; - - public bool AutoAddToTerrains - { - get => m_autoAddToTerrains; - set - { - m_autoAddToTerrains = value; - if ( Native != null && m_autoAddToTerrains ) - AddToAllTerrains(); - } - } - /// /// Checks if top, cutting edges and cutting direction is valid. /// @@ -137,28 +123,19 @@ protected override bool Initialize() Settings.name = "[Temporary]Shovel Settings"; } - if ( AutoAddToTerrains ) - AddToAllTerrains(); + Simulation.Instance.Native.add( Native ); return true; } - private void AddToAllTerrains() - { -#if UNITY_2022_2_OR_NEWER - foreach ( var terr in FindObjectsByType( FindObjectsSortMode.None ) ) - terr.Add( this ); -#else - foreach ( var terr in FindObjectsOfType() ) - terr.Add( this ); -#endif - } - protected override void OnDestroy() { if ( Settings != null ) Settings.Unregister( this ); + if ( Simulation.HasInstance ) + Simulation.Instance.Native.remove( Native ); + Native = null; base.OnDestroy(); diff --git a/AGXUnity/Model/DeformableTerrainShovelSettings.cs b/AGXUnity/Model/DeformableTerrainShovelSettings.cs index b9c2c1de..abb397c6 100644 --- a/AGXUnity/Model/DeformableTerrainShovelSettings.cs +++ b/AGXUnity/Model/DeformableTerrainShovelSettings.cs @@ -17,7 +17,7 @@ public int NumberOfTeeth set { m_numberOfTeeth = value; - Propagate( shovel => shovel.setNumberOfTeeth( Convert.ToUInt64( m_numberOfTeeth ) ) ); + Propagate( shovel => shovel.getSettings().setNumberOfTeeth( Convert.ToUInt64( m_numberOfTeeth ) ) ); } } @@ -32,7 +32,7 @@ public float ToothLength set { m_toothLength = value; - Propagate( shovel => shovel.setToothLength( m_toothLength ) ); + Propagate( shovel => shovel.getSettings().setToothLength( m_toothLength ) ); } } @@ -48,114 +48,115 @@ public RangeReal ToothRadius { m_toothRadius = value; Propagate( shovel => { - shovel.setToothMinimumRadius( m_toothRadius.Min ); - shovel.setToothMaximumRadius( m_toothRadius.Max ); + shovel.getSettings().setToothMinimumRadius( m_toothRadius.Min ); + shovel.getSettings().setToothMaximumRadius( m_toothRadius.Max ); } ); } } [SerializeField] - private float m_noMergeExtensionDistance = 0.5f; + private float m_verticalBladeSoilMergeDistance = 0.0f; [ClampAboveZeroInInspector( true )] - [Tooltip( "The margin outside the shovel bonding box where soil particle merging is forbidden. " )] - public float NoMergeExtensionDistance + [Tooltip( "The vertical distance under the blade cutting edge that the soil is allowed to instantly merge up to. " )] + public float VerticalBladeSoilMergeDistance { - get { return m_noMergeExtensionDistance; } + get { return m_verticalBladeSoilMergeDistance; } set { - m_noMergeExtensionDistance = value; - Propagate( shovel => shovel.setNoMergeExtensionDistance( m_noMergeExtensionDistance ) ); + m_verticalBladeSoilMergeDistance = value; + Propagate( shovel => shovel.getSettings().setVerticalBladeSoilMergeDistance( m_verticalBladeSoilMergeDistance ) ); } } [SerializeField] - private float m_minimumSubmergedContactLengthFraction = 0.5f; + private float m_penetrationDepthThreshold = 0.2f; - [FloatSliderInInspector( 0.0f, 1.0f )] - [Tooltip( "The minimum submerged cutting edge length fraction that generates submerged cutting. " )] - public float MinimumSubmergedContactLengthFraction + [ClampAboveZeroInInspector( true )] + [Tooltip( "The vertical penetration depth threshold for when the shovel tooth for penetration resistance should reach full effectiveness. The penetration depth is defined as the vertical distance between the tip of a shovel tooth and the surface position of the height field. The penetration resistance will increase from a baseline of 10% until maximum effectiveness is reached when the vertical penetration depth of the shovel reaches the specified value." )] + public float PenetrationDepthThreshold { - get { return m_minimumSubmergedContactLengthFraction; } + get { return m_penetrationDepthThreshold; } set { - m_minimumSubmergedContactLengthFraction = value; - Propagate( shovel => shovel.setMinimumSubmergedContactLengthFraction( m_minimumSubmergedContactLengthFraction ) ); + m_penetrationDepthThreshold = value; + Propagate( shovel => shovel.getSettings().setPenetrationDepthThreshold( m_penetrationDepthThreshold ) ); } } [SerializeField] - private float m_verticalBladeSoilMergeDistance = 0.0f; + private float m_penetrationForceScaling = 1.0f; [ClampAboveZeroInInspector( true )] - [Tooltip( "The vertical distance under the blade cutting edge that the soil is allowed to instantly merge up to. " )] - public float VerticalBladeSoilMergeDistance + [Tooltip( "The coefficient for scaling the penetration force that the terrain will give on this shovel." )] + public float PenetrationForceScaling { - get { return m_verticalBladeSoilMergeDistance; } + get { return m_penetrationForceScaling; } set { - m_verticalBladeSoilMergeDistance = value; - Propagate( shovel => shovel.setVerticalBladeSoilMergeDistance( m_verticalBladeSoilMergeDistance ) ); + m_penetrationForceScaling = value; + Propagate( shovel => shovel.getSettings().setPenetrationForceScaling( m_penetrationForceScaling ) ); } } [SerializeField] - private float m_secondarySeparationDeadloadLimit = 0.8f; + private float m_maxPenetrationForce = float.PositiveInfinity; [ClampAboveZeroInInspector( true )] - [Tooltip( "The dead-load limit where secondary separation will start to active where the forward direction starts to change according to the virtual separation plate created by the material inside the shovel " )] - public float SecondarySeparationDeadloadLimit + [Tooltip( "The maximum limit on penetration force (N) that the terrain will generate on this shovel. " )] + public float MaxPenetrationForce { - get { return m_secondarySeparationDeadloadLimit; } + get { return m_maxPenetrationForce; } set { - m_secondarySeparationDeadloadLimit = value; - Propagate( shovel => shovel.setSecondarySeparationDeadloadLimit( m_secondarySeparationDeadloadLimit ) ); + m_maxPenetrationForce = value; + Propagate( shovel => shovel.getSettings().setMaxPenetrationForce( m_maxPenetrationForce ) ); } } [SerializeField] - private float m_penetrationDepthThreshold = 0.2f; + private float m_noMergeExtensionDistance = 0.5f; [ClampAboveZeroInInspector( true )] - [Tooltip( "The vertical penetration depth threshold for when the shovel tooth for penetration resistance should reach full effectiveness. The penetration depth is defined as the vertical distance between the tip of a shovel tooth and the surface position of the height field. The penetration resistance will increase from a baseline of 10% until maximum effectiveness is reached when the vertical penetration depth of the shovel reaches the specified value." )] - public float PenetrationDepthThreshold + [InspectorGroupBegin( Name = "Advanced" )] + [Tooltip( "The margin outside the shovel bonding box where soil particle merging is forbidden. " )] + public float NoMergeExtensionDistance { - get { return m_penetrationDepthThreshold; } + get { return m_noMergeExtensionDistance; } set { - m_penetrationDepthThreshold = value; - Propagate( shovel => shovel.setPenetrationDepthThreshold( m_penetrationDepthThreshold ) ); + m_noMergeExtensionDistance = value; + Propagate( shovel => shovel.getAdvancedSettings().setNoMergeExtensionDistance( m_noMergeExtensionDistance ) ); } } [SerializeField] - private float m_penetrationForceScaling = 1.0f; + private float m_minimumSubmergedContactLengthFraction = 0.5f; - [ClampAboveZeroInInspector( true )] - [Tooltip( "The coefficient for scaling the penetration force that the terrain will give on this shovel." )] - public float PenetrationForceScaling + [FloatSliderInInspector( 0.0f, 1.0f )] + [Tooltip( "The minimum submerged cutting edge length fraction that generates submerged cutting. " )] + public float MinimumSubmergedContactLengthFraction { - get { return m_penetrationForceScaling; } + get { return m_minimumSubmergedContactLengthFraction; } set { - m_penetrationForceScaling = value; - Propagate( shovel => shovel.setPenetrationForceScaling( m_penetrationForceScaling ) ); + m_minimumSubmergedContactLengthFraction = value; + Propagate( shovel => shovel.getAdvancedSettings().setMinimumSubmergedContactLengthFraction( m_minimumSubmergedContactLengthFraction ) ); } } [SerializeField] - private float m_maxPenetrationForce = float.PositiveInfinity; + private float m_secondarySeparationDeadloadLimit = 0.8f; [ClampAboveZeroInInspector( true )] - [Tooltip( "The maximum limit on penetration force (N) that the terrain will generate on this shovel. " )] - public float MaxPenetrationForce + [Tooltip( "The dead-load limit where secondary separation will start to active where the forward direction starts to change according to the virtual separation plate created by the material inside the shovel " )] + public float SecondarySeparationDeadloadLimit { - get { return m_maxPenetrationForce; } + get { return m_secondarySeparationDeadloadLimit; } set { - m_maxPenetrationForce = value; - Propagate( shovel => shovel.setMaxPenetrationForce( m_maxPenetrationForce ) ); + m_secondarySeparationDeadloadLimit = value; + Propagate( shovel => shovel.getAdvancedSettings().setSecondarySeparationDeadloadLimit( m_secondarySeparationDeadloadLimit ) ); } } @@ -175,7 +176,7 @@ public bool RemoveContacts set { m_removeContacts = value; - Propagate( shovel => shovel.setAlwaysRemoveShovelContacts( m_removeContacts ) ); + Propagate( shovel => shovel.getAdvancedSettings().setAlwaysRemoveShovelContacts( m_removeContacts ) ); } } @@ -220,6 +221,7 @@ public agxTerrain.Shovel.ExcavationSettings ToNative() }; [InspectorSeparator] + [InspectorGroupEnd] public ExcavationSettings PrimaryExcavationSettings { get { return m_primaryExcavationSettings; } @@ -345,15 +347,15 @@ protected override bool Initialize() private void OnBottomContactThresholdOverrideValue( float newValue ) { if ( m_contactRegionThreshold.UseOverride ) - Propagate( shovel => shovel.setContactRegionThreshold( newValue ) ); + Propagate( shovel => shovel.getAdvancedSettings().setContactRegionThreshold( newValue ) ); } private void OnBottomContactThresholdUseOverrideToggle( bool newValue ) { if ( newValue ) - Propagate( shovel => shovel.setContactRegionThreshold( m_contactRegionThreshold.OverrideValue ) ); - else - Propagate( shovel => shovel.setContactRegionThreshold( shovel.computeDefaultContactRegionThreshold() ) ); + Propagate( shovel => shovel.getAdvancedSettings().setContactRegionThreshold( m_contactRegionThreshold.OverrideValue ) ); + //else + // Propagate( shovel => shovel.getAdvancedSettings().setContactRegionThreshold( shovel.getAdvancedSettings().computeDefaultContactRegionThreshold() ) ); } private void Propagate( Action action ) diff --git a/AGXUnity/Model/MovableTerrain.cs b/AGXUnity/Model/MovableTerrain.cs index 1560283a..ee5cc0f6 100644 --- a/AGXUnity/Model/MovableTerrain.cs +++ b/AGXUnity/Model/MovableTerrain.cs @@ -1,7 +1,6 @@ using AGXUnity.Collide; using AGXUnity.Utils; using System; -using System.Collections.Generic; using UnityEngine; using Mesh = UnityEngine.Mesh; @@ -78,9 +77,6 @@ public RigidBody RigidBody } } - [SerializeField] - private List m_shovels = new List(); - [SerializeField] private Vector2 m_sizeMeters = new Vector2(2,2); @@ -178,8 +174,6 @@ protected override bool Initialize() // Only printing the errors if something is wrong. LicenseManager.LicenseInfo.HasModuleLogError( LicenseInfo.Module.AGXTerrain | LicenseInfo.Module.AGXGranular, this ); - RemoveInvalidShovels(); - InitializeNative(); Simulation.Instance.StepCallbacks.PostStepForward += OnPostStepForward; @@ -225,9 +219,6 @@ private void InitializeNative() false, depth ); - foreach ( var shovel in Shovels ) - Native.add( shovel.GetInitialized()?.Native ); - GetSimulation().add( Native ); var rb = RigidBody; @@ -356,57 +347,11 @@ private void OnDrawGizmosSelected() // ----------------------------------------------------------------------------------------------------------- protected override float ElementSizeGetter => ElementSize; - public override DeformableTerrainShovel[] Shovels => m_shovels.ToArray(); public override agx.GranularBodyPtrArray GetParticles() { return Native?.getSoilSimulationInterface().getSoilParticles(); } public override agx.Uuid GetParticleMaterialUuid() => Native?.getMaterial( agxTerrain.Terrain.MaterialType.PARTICLE ).getUuid(); public override agxTerrain.SoilSimulationInterface GetSoilSimulationInterface() { return Native?.getSoilSimulationInterface(); } public override agxTerrain.TerrainProperties GetProperties() { return Native?.getProperties(); } - public override bool Add( DeformableTerrainShovel shovel ) - { - if ( shovel == null || m_shovels.Contains( shovel ) ) - return false; - - m_shovels.Add( shovel ); - - // Initialize shovel if we're initialized. - if ( Native != null ) - Native.add( shovel.GetInitialized().Native ); - - return true; - } - - public override bool Remove( DeformableTerrainShovel shovel ) - { - if ( shovel == null || !m_shovels.Contains( shovel ) ) - return false; - - if ( Native != null ) - Native.remove( shovel.Native ); - - return m_shovels.Remove( shovel ); - } - public override bool Contains( DeformableTerrainShovel shovel ) - { - return shovel != null && m_shovels.Contains( shovel ); - } - - public override void RemoveInvalidShovels( bool removeDisabled = false, bool warn = false ) - { - m_shovels.RemoveAll( shovel => shovel == null ); - if ( removeDisabled ) { - int removed = m_shovels.RemoveAll( shovel => !shovel.isActiveAndEnabled ); - if ( removed > 0 ) { - if ( warn ) - Debug.LogWarning( $"Removed {removed} disabled shovels from terrain {gameObject.name}." + - " Disabled shovels should not be added to the terrain on play and should instead be added manually when enabled during runtime." + - " To fix this warning, please remove any disabled shovels from the terrain." ); - else - Debug.Log( $"Removed {removed} disabled shovels from terrain {gameObject.name}." ); - } - } - } - public override void ConvertToDynamicMassInShape( Collide.Shape failureVolume ) { if ( Native != null ) diff --git a/Editor/AGXUnityEditor/Tools/DeformableTerrainBaseTool.cs b/Editor/AGXUnityEditor/Tools/DeformableTerrainBaseTool.cs index a676598c..d51d0991 100644 --- a/Editor/AGXUnityEditor/Tools/DeformableTerrainBaseTool.cs +++ b/Editor/AGXUnityEditor/Tools/DeformableTerrainBaseTool.cs @@ -1,6 +1,5 @@ using AGXUnity; using AGXUnity.Model; -using System.Linq; using UnityEditor; using UnityEngine; using static AGXUnityEditor.InspectorGUI; @@ -20,7 +19,6 @@ public DeformableTerrainBaseTool( Object[] targets ) public override void OnPreTargetMembersGUI() { - DeformableTerrainBase.RemoveInvalidShovels( false ); } public override void OnPostTargetMembersGUI() @@ -30,21 +28,7 @@ public override void OnPostTargetMembersGUI() RenderMaterialHandles(); - Undo.RecordObject( DeformableTerrainBase, "Shovel add/remove." ); - - ToolListGUI( this, - DeformableTerrainBase.Shovels, - "Shovels", - shovel => DeformableTerrainBase.Add( shovel ), - shovel => DeformableTerrainBase.Remove( shovel ) ); - ToolArrayGUI( this, DeformableTerrainBase.MaterialPatches, "Material Patches" ); - - if ( DeformableTerrainBase.Shovels.Any( shovel => !shovel.isActiveAndEnabled ) ) { - EditorGUILayout.HelpBox( "Terrain contains disabled shovels. This is not supported and they will be removed on play. Disabled shovels must be added manually to the terrain when enabled", MessageType.Warning ); - if ( GUILayout.Button( "Remove disabled shovels" ) ) - DeformableTerrainBase.RemoveInvalidShovels( true, false ); - } } protected void RenderMaterialHandles() diff --git a/Editor/AGXUnityEditor/Tools/DeformableTerrainPagerTool.cs b/Editor/AGXUnityEditor/Tools/DeformableTerrainPagerTool.cs index 6ba49ad5..321773c3 100644 --- a/Editor/AGXUnityEditor/Tools/DeformableTerrainPagerTool.cs +++ b/Editor/AGXUnityEditor/Tools/DeformableTerrainPagerTool.cs @@ -27,8 +27,6 @@ public DeformableTerrainPagerTool( Object[] targets ) public override void OnPreTargetMembersGUI() { - TerrainPager.RemoveInvalidShovels( false ); - if ( GetTargets().Any( pager => !TerrainUtils.IsValid( pager ) ) ) { InspectorGUI.WarningLabel( "INVALID CONFIGURATION\n\n" + "One or more AGXUnity.Model.DeformableTerrain and/or " + @@ -122,12 +120,6 @@ public override void OnPostTargetMembersGUI() RadiiEditor, null ); - - if ( TerrainPager.Shovels.Any( shovel => !shovel.isActiveAndEnabled ) || TerrainPager.RigidBodies.Any( rb => !rb.isActiveAndEnabled ) ) { - EditorGUILayout.HelpBox( "Terrain contains disabled objects. This is not supported and they will be removed on play. Disabled objects must be added manually to the terrain when enabled", MessageType.Warning ); - if ( GUILayout.Button( "Remove disabled objects" ) ) - TerrainPager.RemoveInvalidShovels( true, false ); - } } public override void OnSceneViewGUI( SceneView sceneView ) diff --git a/Editor/AGXUnityEditor/Tools/DeformableTerrainShovelTool.cs b/Editor/AGXUnityEditor/Tools/DeformableTerrainShovelTool.cs index 39710f90..7cb4fdbb 100644 --- a/Editor/AGXUnityEditor/Tools/DeformableTerrainShovelTool.cs +++ b/Editor/AGXUnityEditor/Tools/DeformableTerrainShovelTool.cs @@ -70,13 +70,14 @@ public override void OnSceneViewGUI( SceneView sceneView ) var rayCenter = 0.5f * ( CuttingEdgeLineTool.Line.Center + TopEdgeLineTool.Line.Center ); var rayDir = Vector3.Cross( cuttingDir, cuttingToTop ).normalized; - if ( Vector3.Dot( cuttingDir, TopEdgeLineTool.Line.Direction ) < 0.95f ) + var absDot = Mathf.Abs(Vector3.Dot( cuttingDir, TopEdgeLineTool.Line.Direction )); + if ( absDot < 0.95f ) m_edgeIssues.Add( "\u2022 " + GUI.AddColorTag( "Top", Color.Lerp( Color.yellow, Color.white, 0.35f ) ) + " and " + GUI.AddColorTag( "Cutting", Color.Lerp( Color.red, Color.white, 0.35f ) ) + - " edge direction expected to be approximately parallel with dot product > 0.95, currently: " + - GUI.AddColorTag( Vector3.Dot( cuttingDir, TopEdgeLineTool.Line.Direction ).ToString(), Color.red ) ); + " edge direction expected to be approximately parallel with (absolute) dot product > 0.95, currently: " + + GUI.AddColorTag( absDot.ToString(), Color.red ) ); if ( !Utils.Raycast.Intersect( new Ray( rayCenter, rayDir ), Shovel.GetComponentsInChildren() ).Hit ) m_edgeIssues.Add( "\u2022 " + GUI.AddColorTag( "Top", Color.Lerp( Color.yellow, Color.white, 0.35f ) ) + diff --git a/Editor/AGXUnityEditor/Tools/MovableTerrainTool.cs b/Editor/AGXUnityEditor/Tools/MovableTerrainTool.cs index 0ac0a06d..bcfcfe84 100644 --- a/Editor/AGXUnityEditor/Tools/MovableTerrainTool.cs +++ b/Editor/AGXUnityEditor/Tools/MovableTerrainTool.cs @@ -25,8 +25,6 @@ public enum SizeUnit public override void OnPreTargetMembersGUI() { - MovableTerrain.RemoveInvalidShovels(); - EditorGUILayout.Space(); sizeToUse = (SizeUnit)EditorGUILayout.EnumPopup( "Size Units", sizeToUse );