Files
Fishing2/Packages/com.nwh.dynamicwaterphysics/Samples~/CrestIntegration/CrestWaterDataProvider.cs
2026-02-27 17:44:21 +08:00

152 lines
5.0 KiB
C#

// // ╔════════════════════════════════════════════════════════════════╗
// // ║ Copyright © 2025 NWH Coding d.o.o. All rights reserved. ║
// // ║ Licensed under Unity Asset Store Terms of Service: ║
// // ║ https://unity.com/legal/as-terms ║
// // ║ Use permitted only in compliance with the License. ║
// // ║ Distributed "AS IS", without warranty of any kind. ║
// // ╚════════════════════════════════════════════════════════════════╝
using System.Collections.Generic;
using UnityEngine;
using NWH.DWP2.WaterObjects;
#if DWP_CREST_LEGACY
using Crest;
#else
using WaveHarmonic.Crest;
using OceanRenderer = WaveHarmonic.Crest.WaterRenderer;
#endif
namespace NWH.DWP2.WaterData
{
[DefaultExecutionOrder(-50)]
public class CrestWaterDataProvider : WaterDataProvider
{
private OceanRenderer _oceanRenderer;
public override bool SupportsWaterHeightQueries()
{
return true;
}
public override bool SupportsWaterNormalQueries()
{
return true;
}
public override bool SupportsWaterFlowQueries()
{
return true;
}
public override void Awake()
{
base.Awake();
_oceanRenderer = FindAnyObjectByType<OceanRenderer>();
if (_oceanRenderer == null)
{
Debug.LogError($"{typeof(OceanRenderer)} not found in scene. " +
$"{GetType()} requires a {typeof(OceanRenderer)} to be present in the scene.");
}
}
public override void GetWaterHeights(WaterObject waterObject, ref Vector3[] points, ref float[] waterHeights)
{
if (_oceanRenderer == null) return;
var provider = _oceanRenderer.CollisionProvider;
int status = provider.Query(waterObject.instanceID, 0, points, waterHeights, null, null);
// If retrieval failed, Crest did not modify waterHeights - fill with SeaLevel as fallback
if (!provider.RetrieveSucceeded(status))
{
float seaLevel = _oceanRenderer.SeaLevel;
for (int i = 0; i < waterHeights.Length; i++)
{
waterHeights[i] = seaLevel;
}
}
}
public override void GetWaterNormals(WaterObject waterObject, ref Vector3[] points, ref Vector3[] waterNormals)
{
if (_oceanRenderer == null) return;
var provider = _oceanRenderer.CollisionProvider;
// Flip the instance sign to not get overlapping queries for same provider. InstanceID is always negative so
// no duplicates should ever happen.
int status = provider.Query(-waterObject.instanceID, 0, points, (float[])null, waterNormals, null);
// If retrieval failed, fill with up vector as fallback
if (!provider.RetrieveSucceeded(status))
{
for (int i = 0; i < waterNormals.Length; i++)
{
waterNormals[i] = Vector3.up;
}
}
}
public override void GetWaterFlows(WaterObject waterObject, ref Vector3[] points, ref Vector3[] waterFlows)
{
if (_oceanRenderer == null) return;
var provider = _oceanRenderer.FlowProvider;
int status = provider.Query(waterObject.instanceID, 0, points, waterFlows);
// If retrieval failed, fill with zero flow as fallback
if (!provider.RetrieveSucceeded(status))
{
for (int i = 0; i < waterFlows.Length; i++)
{
waterFlows[i] = Vector3.zero;
}
}
}
}
}
#if UNITY_EDITOR
namespace NWH.DWP2.WaterData
{
using UnityEditor;
[CustomEditor(typeof(CrestWaterDataProvider))]
[CanEditMultipleObjects]
public class CrestWaterDataProviderEditor : WaterDataProviderEditor
{
protected override void DrawStatus(WaterDataProvider provider)
{
drawer.BeginSubsection("Status");
#if DWP_CREST_LEGACY
drawer.Info("Using Legacy Crest (DWP_CREST_LEGACY defined)");
#else
drawer.Info("Using Crest 5+ (WaveHarmonic.Crest)");
#endif
var oceanRenderer = FindAnyObjectByType<OceanRenderer>();
if (oceanRenderer != null)
{
drawer.Info($"Crest Water Renderer found in scene: {oceanRenderer.name}");
}
else
{
drawer.Info("Crest Water Renderer (OceanRenderer) not found in scene.", MessageType.Error);
}
drawer.EndSubsection();
}
}
}
#endif