Repository URL to install this package:
Version:
1.0.0 ▾
|
ai.fluctio.fluctio-sim
/
Core
/
Components
/
Prefabs
/
Primitives
/
Base
/
PrimitivePhysicsProperties.cs
|
---|
using Fluctio.FluctioSim.Common.Configuration;
using Fluctio.FluctioSim.Core.Components.Base;
using Fluctio.FluctioSim.Core.Components.MujocoGeom;
using Mujoco;
using UnityEngine;
using PhysicsMaterial = Fluctio.FluctioSim.Core.Components.PhysicsMaterials.PhysicsMaterial;
#if UNITY_EDITOR
using UnityEditor;
#endif
namespace Fluctio.FluctioSim.Core.Components.Prefabs.Primitives.Base
{
[ExecuteInEditMode]
[RequireComponent(typeof(MujocoStructure))]
[AddComponentMenu(Config.PrefixedName+"/Physics/Geom Settings/Physics Properties", Config.ComponentMenuOrder + 60)]
[DisallowMultipleComponent]
public sealed class PrimitivePhysicsProperties : EditorComponent
{
[Tooltip("Multiplier applied to the global gravity configured in Unity project settings\n1 = normal gravity\n0 = no gravity\n-1 = inversed gravity")]
[SerializeField] public float gravityMultiplier = 1;
[SerializeField] public MassDefinitionType massDefinitionType = MassDefinitionType.Density;
[SerializeField] public PhysicsMaterial physicsMaterial;
[SerializeField] public float density = 1000;
[SerializeField] public float mass = 10;
private MjBody _bodyComponent;
private MjGeom _geomComponent;
protected override void Initialize()
{
base.Initialize();
var structure = GetComponent<MujocoStructure>();
_bodyComponent = structure.BodyComponent;
_geomComponent = structure.GeomComponent;
}
private void ToGeom()
{
switch (massDefinitionType)
{
case MassDefinitionType.Density:
_geomComponent.Mass = 0;
_geomComponent.Density = density;
break;
case MassDefinitionType.Material:
density = physicsMaterial.density;
goto case MassDefinitionType.Density;
case MassDefinitionType.Mass:
_geomComponent.Mass = mass;
break;
default:
Debug.LogError($"Wrong value for {nameof(massDefinitionType)}: {massDefinitionType}");
massDefinitionType = MassDefinitionType.Density;
break;
}
}
private void FromGeom()
{
if (_geomComponent.Mass != 0)
{
massDefinitionType = MassDefinitionType.Mass;
mass = _geomComponent.Mass;
return;
}
if (massDefinitionType == MassDefinitionType.Mass)
{
massDefinitionType = MassDefinitionType.Density;
}
// ReSharper disable once CompareOfFloatsByEqualityOperator
if (_geomComponent.Density != density)
{
massDefinitionType = MassDefinitionType.Density;
density = _geomComponent.Density;
}
}
private void ConstrainValues()
{
density = Mathf.Max(density, Config.MinFloat);
mass = Mathf.Max(mass, Config.MinFloat);
physicsMaterial ??= PhysicsMaterial.Default;
}
public override void OnSelfChanged()
{
base.OnSelfChanged();
ConstrainValues();
_bodyComponent.GravityCompensation = 1 - gravityMultiplier;
ToGeom();
}
public override void OnOtherChanged()
{
base.OnOtherChanged();
gravityMultiplier = 1 - _bodyComponent.GravityCompensation;
FromGeom();
}
}
public enum MassDefinitionType
{
Density,
Material,
Mass,
}
#if UNITY_EDITOR
[CustomEditor(typeof(PrimitivePhysicsProperties), true)]
[CanEditMultipleObjects]
public class PrimitivePhysicsPropertiesEditor : EditorComponentEditor
{
// ReSharper disable once InconsistentNaming
private new PrimitivePhysicsProperties target => (PrimitivePhysicsProperties)base.target;
public override void OnInspectorGUI()
{
serializedObject.Update();
var gravityMultiplierProperty = serializedObject.FindProperty("gravityMultiplier");
EditorGUILayout.PropertyField(gravityMultiplierProperty);
var massDefinitionTypeProperty = serializedObject.FindProperty("massDefinitionType");
EditorGUILayout.PropertyField(massDefinitionTypeProperty);
// TODO: show all three fields and recalculate all of them when one changes
var densityProperty = serializedObject.FindProperty("density");
var physicsMaterialProperty = serializedObject.FindProperty("physicsMaterial");
var massProperty = serializedObject.FindProperty("mass");
if (!massDefinitionTypeProperty.hasMultipleDifferentValues)
{
switch (target.massDefinitionType)
{
case MassDefinitionType.Density:
EditorGUILayout.PropertyField(densityProperty);
break;
case MassDefinitionType.Material:
EditorGUILayout.PropertyField(physicsMaterialProperty);
GUI.enabled = false;
EditorGUILayout.PropertyField(densityProperty);
GUI.enabled = true;
break;
case MassDefinitionType.Mass:
EditorGUILayout.PropertyField(massProperty);
break;
default:
// ReSharper disable once Unity.PerformanceCriticalCodeInvocation
Debug.LogError(
$"Wrong value for {nameof(target.massDefinitionType)}: {target.massDefinitionType}");
target.massDefinitionType = MassDefinitionType.Density;
break;
}
}
serializedObject.ApplyModifiedProperties();
}
}
#endif
}