Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
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
29 changes: 17 additions & 12 deletions Editor/BuoyantObjectEditor.cs
Original file line number Diff line number Diff line change
Expand Up @@ -7,32 +7,38 @@ namespace WaterSystem.Physics
[CustomEditor(typeof(BuoyantObject))]
public class BuoyantObjectEditor : Editor
{
private BuoyantObject obj;
private BuoyantObject Obj => serializedObject.targetObject as BuoyantObject;
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does performance matter in this script? There's some overhead added by using a property getter, plus I'm pretty sure it will do the cast each time this is accessed.


[SerializeField]
private bool _heightsDebugBool;

[SerializeField]
private bool _generalSettingsBool;

private void OnEnable()
{
obj = serializedObject.targetObject as BuoyantObject;
}

public override void OnInspectorGUI()
{
_generalSettingsBool = EditorGUILayout.Foldout(_generalSettingsBool, "General Settings");
if (!EditorApplication.isPlaying)
{
base.OnInspectorGUI();
return;
}

_generalSettingsBool = EditorGUILayout.BeginFoldoutHeaderGroup(_generalSettingsBool, "General Settings");
EditorGUILayout.EndFoldoutHeaderGroup();
if (_generalSettingsBool)
{
base.OnInspectorGUI();
}

if (EditorGUILayout.BeginFoldoutHeaderGroup(_heightsDebugBool, "Height Debug Values"))
_heightsDebugBool = EditorGUILayout.BeginFoldoutHeaderGroup(_heightsDebugBool, "Height Debug Values");
EditorGUILayout.EndFoldoutHeaderGroup();
if (_heightsDebugBool)
{
if (obj.Heights != null)
if (Obj.Heights != null)
{
for (var i = 0; i < obj.Heights.Length; i++)
for (var i = 0; i < Obj.Heights.Length; i++)
{
var h = obj.Heights[i];
var h = Obj.Heights[i];
EditorGUILayout.LabelField($"{i})Wave(heights):", $"X:{h.x:00.00} Y:{h.y:00.00} Z:{h.z:00.00}");
}
}
Expand All @@ -41,7 +47,6 @@ public override void OnInspectorGUI()
EditorGUILayout.HelpBox("Height debug info only available in playmode.", MessageType.Info);
}
}
EditorGUILayout.EndFoldoutHeaderGroup();
}
}
}
4 changes: 3 additions & 1 deletion Runtime/GerstnerWavesJobs.cs
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,9 @@ public static void Cleanup()
_waterHeightHandle.Complete();

DepthGenerator.CleanUp();


Registry.Clear();

//Cleanup native arrays
_waveData.Dispose();
_positions.Dispose();
Expand Down
101 changes: 60 additions & 41 deletions Runtime/Physics/BuoyantObject.cs
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,9 @@ public class BuoyantObject : MonoBehaviour
private DebugDrawing[] _debugInfo; // For drawing force gizmos
[NonSerialized] public float PercentSubmerged;

private bool IsPhysicsBased => _buoyancyType == BuoyancyType.Physical || _buoyancyType == BuoyancyType.PhysicalVoxel;
private bool IsVoxelBased => _buoyancyType == BuoyancyType.NonPhysicalVoxel || _buoyancyType == BuoyancyType.PhysicalVoxel;

[ContextMenu("Initialize")]
private void Init()
{
Expand Down Expand Up @@ -82,7 +85,7 @@ private void Init()

private void SetupVoxels()
{
if (_buoyancyType == BuoyancyType.NonPhysicalVoxel || _buoyancyType == BuoyancyType.PhysicalVoxel)
if (IsVoxelBased)
{
SliceIntoVoxels();
}
Expand All @@ -106,6 +109,8 @@ private void OnEnable()
_guid = gameObject.GetInstanceID();
Init();
LocalToWorldConversion();

StartCoroutine(LateFixedUpdate());
}

private void SetupColliders()
Expand All @@ -121,35 +126,31 @@ private void SetupColliders()

private void Update()
{
if (IsPhysicsBased)
return;

#if STATIC_EVERYTHING
var dt = 0.0f;
#else
var dt = Time.deltaTime;
#endif

switch (_buoyancyType)
{
case BuoyancyType.NonPhysical:
{
_samplePoints[0] = transform.position;
var t = transform;
var vec = t.position;
vec.y = Heights[0].y + waterLevelOffset;
t.position = vec;
var up = t.up;
t.up = Vector3.Slerp(up, _normals[0], dt);
break;
}
{
_samplePoints[0] = transform.position;
var t = transform;
var vec = t.position;
vec.y = Heights[0].y + waterLevelOffset;
t.position = vec;
var up = t.up;
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I know you didn't write the original, but the assignment to up isn't needed. t.up will be evaluated first in the next line before overwriting it. t.up = Vector3.Slerp(t.up, _normals[0], dt)

t.up = Vector3.Slerp(up, _normals[0], dt);
break;
}
case BuoyancyType.NonPhysicalVoxel:
// do the voxel non-physical
break;
case BuoyancyType.Physical:
LocalToWorldJob.CompleteJob(_guid);
GetVelocityPoints();
break;
case BuoyancyType.PhysicalVoxel:
LocalToWorldJob.CompleteJob(_guid);
GetVelocityPoints();
break;
default:
throw new ArgumentOutOfRangeException();
}
Expand All @@ -160,38 +161,51 @@ private void Update()

private void FixedUpdate()
{
if (!IsPhysicsBased)
return;

var submergedAmount = 0f;


LocalToWorldJob.CompleteJob(_guid);
GetVelocityPoints();
GerstnerWavesJobs.UpdateSamplePoints(ref _samplePoints, _guid);
GerstnerWavesJobs.GetData(_guid, ref Heights, ref _normals);

switch (_buoyancyType)
{
case BuoyancyType.PhysicalVoxel:
{
LocalToWorldJob.CompleteJob(_guid);
//Debug.Log("new pass: " + gameObject.name);
UnityPhysics.autoSyncTransforms = false;

for (var i = 0; i < _voxels.Length; i++)
BuoyancyForce(_samplePoints[i], _velocity[i], Heights[i].y + waterLevelOffset, ref submergedAmount, ref _debugInfo[i]);
UnityPhysics.SyncTransforms();
UnityPhysics.autoSyncTransforms = true;
UpdateDrag(submergedAmount);
break;
}
{
var autoSyncTransforms = UnityPhysics.autoSyncTransforms;
UnityPhysics.autoSyncTransforms = false;

for (var i = 0; i < _voxels.Length; i++)
BuoyancyForce(_samplePoints[i], _velocity[i], Heights[i].y + waterLevelOffset, ref submergedAmount, ref _debugInfo[i]);

UnityPhysics.SyncTransforms();
UnityPhysics.autoSyncTransforms = autoSyncTransforms;

UpdateDrag(submergedAmount);
break;
}
case BuoyancyType.Physical:
//LocalToWorldJob.CompleteJob(_guid);
BuoyancyForce(Vector3.zero, _velocity[0], Heights[0].y + waterLevelOffset, ref submergedAmount, ref _debugInfo[0]);
//UpdateDrag(submergedAmount);
break;
case BuoyancyType.NonPhysical:
break;
case BuoyancyType.NonPhysicalVoxel:
break;
default:
throw new ArgumentOutOfRangeException();
}
}

private void LateUpdate() { LocalToWorldConversion(); }
private static readonly WaitForFixedUpdate YieldLateFixedUpdate = new WaitForFixedUpdate();
private System.Collections.IEnumerator LateFixedUpdate()
{
while (true)
{
yield return YieldLateFixedUpdate;

LocalToWorldConversion();
}
}

private void OnDestroy()
{
Expand All @@ -200,7 +214,9 @@ private void OnDestroy()

void CleanUp()
{
if (_buoyancyType == BuoyancyType.Physical || _buoyancyType == BuoyancyType.PhysicalVoxel)
StopAllCoroutines();

if (IsPhysicsBased)
{
LocalToWorldJob.Cleanup(_guid);
}
Expand All @@ -212,7 +228,7 @@ void CleanUp()

private void LocalToWorldConversion()
{
if (_buoyancyType != BuoyancyType.Physical && _buoyancyType != BuoyancyType.PhysicalVoxel) return;
if (!IsPhysicsBased) return;

var transformMatrix = transform.localToWorldMatrix;
LocalToWorldJob.ScheduleJob(_guid, transformMatrix);
Expand Down Expand Up @@ -258,6 +274,7 @@ private void SliceIntoVoxels()
var size = t.localScale;
t.SetPositionAndRotation(Vector3.zero, Quaternion.identity);
t.localScale = Vector3.one;
UnityPhysics.SyncTransforms();

_voxels = null;
var points = new List<Vector3>();
Expand Down Expand Up @@ -294,6 +311,8 @@ private void SliceIntoVoxels()
_voxels = points.ToArray();
t.SetPositionAndRotation(pos, rot);
t.localScale = size;
UnityPhysics.SyncTransforms();

var voxelVolume = Mathf.Pow(voxelResolution, 3f) * _voxels.Length;
var rawVolume = rawBounds.size.x * rawBounds.size.y * rawBounds.size.z;
volume = Mathf.Min(rawVolume, voxelVolume);
Expand Down Expand Up @@ -387,7 +406,7 @@ private void OnDrawGizmosSelected()
water.y = debug.WaterHeight;
Gizmos.DrawLine(debug.Position, water); // draw the water line
Gizmos.DrawSphere(water, gizmoSize * 4f);
if(_buoyancyType == BuoyancyType.Physical || _buoyancyType == BuoyancyType.PhysicalVoxel)
if(IsPhysicsBased)
{
Gizmos.color = Color.red;
Gizmos.DrawRay(debug.Position, debug.Force / _rb.mass); // draw force
Expand Down