From b7599655d925890afe65175727abce0339b81a72 Mon Sep 17 00:00:00 2001 From: Tom Maenan Read Cutting Date: Tue, 28 Jan 2020 23:24:20 +0000 Subject: [PATCH 1/3] Experiment with using Native Containers in query API --- .../Collision/OceanSampleDisplacementDemo.cs | 52 +++++--- .../Crest/Scripts/Collision/CollProvider.cs | 5 +- .../Scripts/Collision/CollProviderNull.cs | 5 +- .../Crest/Scripts/Collision/QueryBase.cs | 76 +++++++----- .../Scripts/Collision/QueryDisplacements.cs | 9 +- .../Crest/Scripts/Collision/QueryFlow.cs | 5 +- .../Crest/Scripts/Collision/RayTraceHelper.cs | 22 ++-- .../Scripts/Collision/SamplingHelpers.cs | 117 ++++++++++++------ .../Collision/VisualiseCollisionArea.cs | 28 +++-- .../Scripts/Collision/VisualiseRayTrace.cs | 14 ++- .../Crest/Scripts/Interaction/BoatProbes.cs | 24 ++-- .../ObjectWaterInteractionAdaptor.cs | 22 ++-- .../Scripts/Shapes/ShapeGerstnerBatched.cs | 35 ++++-- 13 files changed, 271 insertions(+), 143 deletions(-) diff --git a/crest/Assets/Crest/Crest-Examples/Shared/Scripts/Collision/OceanSampleDisplacementDemo.cs b/crest/Assets/Crest/Crest-Examples/Shared/Scripts/Collision/OceanSampleDisplacementDemo.cs index 7b2357c68..5d90d28b6 100644 --- a/crest/Assets/Crest/Crest-Examples/Shared/Scripts/Collision/OceanSampleDisplacementDemo.cs +++ b/crest/Assets/Crest/Crest-Examples/Shared/Scripts/Collision/OceanSampleDisplacementDemo.cs @@ -1,6 +1,7 @@ // This file is subject to the MIT License as seen in the root of this folder structure (LICENSE) using Crest; +using Unity.Collections; using UnityEngine; /// @@ -14,37 +15,42 @@ public class OceanSampleDisplacementDemo : MonoBehaviour public float _minGridSize = 0f; GameObject[] _markerObjects = new GameObject[3]; - Vector3[] _markerPos = new Vector3[3]; - Vector3[] _resultDisps = new Vector3[3]; - Vector3[] _resultNorms = new Vector3[3]; - Vector3[] _resultVels = new Vector3[3]; + + float _samplesRadius = 5f; void Update() { + + if (OceanRenderer.Instance == null) + { + return; + } + + NativeArray markerPos = new NativeArray(3, Allocator.Temp); + NativeArray resultDisps = new NativeArray(3, Allocator.Temp); + NativeArray resultNorms = new NativeArray(3, Allocator.Temp); + NativeArray resultVels = new NativeArray(3, Allocator.Temp); + if (_trackCamera) { var height = Mathf.Abs(Camera.main.transform.position.y - OceanRenderer.Instance.SeaLevel); var lookAngle = Mathf.Max(Mathf.Abs(Camera.main.transform.forward.y), 0.001f); var offset = height / lookAngle; - _markerPos[0] = Camera.main.transform.position + Camera.main.transform.forward * offset; - _markerPos[1] = Camera.main.transform.position + Camera.main.transform.forward * offset + _samplesRadius * Vector3.right; - _markerPos[2] = Camera.main.transform.position + Camera.main.transform.forward * offset + _samplesRadius * Vector3.forward; + markerPos[0] = Camera.main.transform.position + Camera.main.transform.forward * offset; + markerPos[1] = Camera.main.transform.position + Camera.main.transform.forward * offset + _samplesRadius * Vector3.right; + markerPos[2] = Camera.main.transform.position + Camera.main.transform.forward * offset + _samplesRadius * Vector3.forward; } - if (OceanRenderer.Instance == null) - { - return; - } var collProvider = OceanRenderer.Instance.CollisionProvider; - var status = collProvider.Query(GetHashCode(), _minGridSize, _markerPos, _resultDisps, _resultNorms, _resultVels); + var status = collProvider.Query(GetHashCode(), _minGridSize, markerPos, resultDisps, resultNorms, resultVels); if (collProvider.RetrieveSucceeded(status)) { - for (int i = 0; i < _resultDisps.Length; i++) + for (int i = 0; i < resultDisps.Length; i++) { if (_markerObjects[i] == null) { @@ -53,28 +59,34 @@ void Update() _markerObjects[i].transform.localScale = Vector3.one * 0.5f; } - var query = _markerPos[i]; + var query = markerPos[i]; query.y = OceanRenderer.Instance.SeaLevel; - var disp = _resultDisps[i]; + var disp = resultDisps[i]; var pos = query; pos.y = disp.y; Debug.DrawLine(pos, pos - disp); _markerObjects[i].transform.position = pos; - _markerObjects[i].transform.rotation = Quaternion.FromToRotation(Vector3.up, _resultNorms[i]); + _markerObjects[i].transform.rotation = Quaternion.FromToRotation(Vector3.up, resultNorms[i]); } - for (var i = 0; i < _resultNorms.Length; i++) + for (var i = 0; i < resultNorms.Length; i++) { - Debug.DrawLine(_markerObjects[i].transform.position, _markerObjects[i].transform.position + _resultNorms[i], Color.blue); + Debug.DrawLine(_markerObjects[i].transform.position, _markerObjects[i].transform.position + resultNorms[i], Color.blue); } - for (var i = 0; i < _resultVels.Length; i++) + for (var i = 0; i < resultVels.Length; i++) { - Debug.DrawLine(_markerObjects[i].transform.position, _markerObjects[i].transform.position + _resultVels[i], Color.green); + Debug.DrawLine(_markerObjects[i].transform.position, _markerObjects[i].transform.position + resultVels[i], Color.green); } } + + + resultVels.Dispose(); + resultNorms.Dispose(); + resultDisps.Dispose(); + markerPos.Dispose(); } } diff --git a/crest/Assets/Crest/Crest/Scripts/Collision/CollProvider.cs b/crest/Assets/Crest/Crest/Scripts/Collision/CollProvider.cs index 3680f6b24..6f5f8ef91 100644 --- a/crest/Assets/Crest/Crest/Scripts/Collision/CollProvider.cs +++ b/crest/Assets/Crest/Crest/Scripts/Collision/CollProvider.cs @@ -2,6 +2,7 @@ // This file is subject to the MIT License as seen in the root of this folder structure (LICENSE) +using Unity.Collections; using UnityEngine; namespace Crest @@ -20,7 +21,7 @@ public interface ICollProvider /// Float array of water heights at the query positions. Pass null if this information is not required. /// Water normals at the query positions. Pass null if this information is not required. /// Water surface velocities at the query positions. Pass null if this information is not required. - int Query(int i_ownerHash, float i_minSpatialLength, Vector3[] i_queryPoints, float[] o_resultHeights, Vector3[] o_resultNorms, Vector3[] o_resultVels); + int Query(int i_ownerHash, float i_minSpatialLength, NativeSlice i_queryPoints, NativeSlice o_resultHeights, NativeSlice o_resultNorms, NativeSlice o_resultVels); /// /// Query water physical data at a set of points. Pass in null to any out parameters that are not required. @@ -31,7 +32,7 @@ public interface ICollProvider /// Displacement vectors for water surface points that will displace to the XZ coordinates of the query points. Water heights are given by sea level plus the y component of the displacement. /// Water normals at the query positions. Pass null if this information is not required. /// Water surface velocities at the query positions. Pass null if this information is not required. - int Query(int i_ownerHash, float i_minSpatialLength, Vector3[] i_queryPoints, Vector3[] o_resultDisps, Vector3[] o_resultNorms, Vector3[] o_resultVels); + int Query(int i_ownerHash, float i_minSpatialLength, NativeSlice i_queryPoints, NativeSlice o_resultDisps, NativeSlice o_resultNorms, NativeSlice o_resultVels); /// /// Check if query results could be retrieved successfully using return code from Query() function diff --git a/crest/Assets/Crest/Crest/Scripts/Collision/CollProviderNull.cs b/crest/Assets/Crest/Crest/Scripts/Collision/CollProviderNull.cs index 0ced54e60..f07ac5dd9 100644 --- a/crest/Assets/Crest/Crest/Scripts/Collision/CollProviderNull.cs +++ b/crest/Assets/Crest/Crest/Scripts/Collision/CollProviderNull.cs @@ -2,6 +2,7 @@ // This file is subject to the MIT License as seen in the root of this folder structure (LICENSE) +using Unity.Collections; using UnityEngine; namespace Crest @@ -11,7 +12,7 @@ namespace Crest /// public class CollProviderNull : ICollProvider { - public int Query(int i_ownerHash, float i_minSpatialLength, Vector3[] i_queryPoints, Vector3[] o_resultDisps, Vector3[] o_resultNorms, Vector3[] o_resultVels) + public int Query(int i_ownerHash, float i_minSpatialLength, NativeSlice i_queryPoints, NativeSlice o_resultDisps, NativeSlice o_resultNorms, NativeSlice o_resultVels) { if (o_resultDisps != null) { @@ -40,7 +41,7 @@ public int Query(int i_ownerHash, float i_minSpatialLength, Vector3[] i_queryPoi return 0; } - public int Query(int i_ownerHash, float i_minSpatialLength, Vector3[] i_queryPoints, float[] o_resultHeights, Vector3[] o_resultNorms, Vector3[] o_resultVels) + public int Query(int i_ownerHash, float i_minSpatialLength, NativeSlice i_queryPoints, NativeSlice o_resultHeights, NativeSlice o_resultNorms, NativeSlice o_resultVels) { if (o_resultHeights != null) { diff --git a/crest/Assets/Crest/Crest/Scripts/Collision/QueryBase.cs b/crest/Assets/Crest/Crest/Scripts/Collision/QueryBase.cs index d1acba95f..5f414a3e1 100644 --- a/crest/Assets/Crest/Crest/Scripts/Collision/QueryBase.cs +++ b/crest/Assets/Crest/Crest/Scripts/Collision/QueryBase.cs @@ -172,7 +172,7 @@ struct ReadbackRequest List _requests = new List(); - public enum QueryStatus + public enum QueryStatus : int { OK = 0, RetrieveFailed = 1, @@ -188,14 +188,14 @@ public enum QueryStatus /// Takes a unique request ID and some world space XZ positions, and computes the displacement vector that lands at this position, /// to a good approximation. The world space height of the water at that position is then SeaLevel + displacement.y. /// - protected bool UpdateQueryPoints(int i_ownerHash, float i_minSpatialLength, Vector3[] queryPoints, Vector3[] queryNormals) + protected bool UpdateQueryPoints(int i_ownerHash, float i_minSpatialLength, NativeSlice queryPoints, NativeSlice queryNormals) { var segmentRetrieved = false; Vector2Int segment; // We'll send in 3 points to get normals - var countPts = (queryPoints != null ? queryPoints.Length : 0); - var countNorms = (queryNormals != null ? queryNormals.Length : 0); + var countPts = (queryPoints.Length != 0 ? queryPoints.Length : 0); + var countNorms = (queryNormals.Length != 0 ? queryNormals.Length : 0); var countTotal = countPts + countNorms * 3; if (_segmentRegistrarRingBuffer.Current._segments.TryGetValue(i_ownerHash, out segment)) @@ -241,9 +241,11 @@ protected bool UpdateQueryPoints(int i_ownerHash, float i_minSpatialLength, Vect for (int pointi = 0; pointi < countPts; pointi++) { - _queryPosXZ_minGridSize[pointi + segment.x].x = queryPoints[pointi].x; - _queryPosXZ_minGridSize[pointi + segment.x].y = queryPoints[pointi].z; - _queryPosXZ_minGridSize[pointi + segment.x].z = minGridSize; + Vector3 queryPosXZ_minGridSizVal = _queryPosXZ_minGridSize[pointi + segment.x]; + queryPosXZ_minGridSizVal.x = queryPoints[pointi].x; + queryPosXZ_minGridSizVal.y = queryPoints[pointi].z; + queryPosXZ_minGridSizVal.z = minGridSize; + _queryPosXZ_minGridSize[pointi + segment.x] = queryPosXZ_minGridSizVal; } // To compute each normal, post 3 query points @@ -251,17 +253,28 @@ protected bool UpdateQueryPoints(int i_ownerHash, float i_minSpatialLength, Vect { var arrIdx = segment.x + countPts + 3 * normi; - _queryPosXZ_minGridSize[arrIdx + 0].x = queryNormals[normi].x; - _queryPosXZ_minGridSize[arrIdx + 0].y = queryNormals[normi].z; - _queryPosXZ_minGridSize[arrIdx + 0].z = minGridSize; - - _queryPosXZ_minGridSize[arrIdx + 1].x = queryNormals[normi].x + s_finiteDiffDx; - _queryPosXZ_minGridSize[arrIdx + 1].y = queryNormals[normi].z; - _queryPosXZ_minGridSize[arrIdx + 1].z = minGridSize; + { + Vector3 queryPosXZ_minGridSizVal = _queryPosXZ_minGridSize[arrIdx + 0]; + queryPosXZ_minGridSizVal.x = queryNormals[normi].x; + queryPosXZ_minGridSizVal.y = queryNormals[normi].z; + queryPosXZ_minGridSizVal.z = minGridSize; + _queryPosXZ_minGridSize[arrIdx + 0] = queryPosXZ_minGridSizVal; + } - _queryPosXZ_minGridSize[arrIdx + 2].x = queryNormals[normi].x; - _queryPosXZ_minGridSize[arrIdx + 2].y = queryNormals[normi].z + s_finiteDiffDx; - _queryPosXZ_minGridSize[arrIdx + 2].z = minGridSize; + { + Vector3 queryPosXZ_minGridSizVal = _queryPosXZ_minGridSize[arrIdx + 1]; + queryPosXZ_minGridSizVal.x = queryNormals[normi].x + s_finiteDiffDx; + queryPosXZ_minGridSizVal.y = queryNormals[normi].z; + queryPosXZ_minGridSizVal.z = minGridSize; + _queryPosXZ_minGridSize[arrIdx + 1] = queryPosXZ_minGridSizVal; + } + { + Vector3 queryPosXZ_minGridSizVal = _queryPosXZ_minGridSize[arrIdx + 2]; + queryPosXZ_minGridSizVal.x = queryNormals[normi].x; + queryPosXZ_minGridSizVal.y = queryNormals[normi].z + s_finiteDiffDx; + queryPosXZ_minGridSizVal.z = minGridSize; + _queryPosXZ_minGridSize[arrIdx + 2] = queryPosXZ_minGridSizVal; + } } return true; @@ -287,7 +300,7 @@ public void CompactQueryStorage() /// /// Copy out displacements, heights, normals. Pass null if info is not required. /// - protected bool RetrieveResults(int guid, Vector3[] displacements, float[] heights, Vector3[] normals) + protected bool RetrieveResults(int guid, NativeSlice displacements, NativeSlice heights, NativeSlice normals) { if (_resultSegments == null) { @@ -303,19 +316,19 @@ protected bool RetrieveResults(int guid, Vector3[] displacements, float[] height } var countPoints = 0; - if (displacements != null) countPoints = displacements.Length; - if (heights != null) countPoints = heights.Length; - if (displacements != null && heights != null) Debug.Assert(displacements.Length == heights.Length); - var countNorms = (normals != null ? normals.Length : 0); + if (displacements.Length != 0) countPoints = displacements.Length; + if (heights.Length != 0) countPoints = heights.Length; + if (displacements.Length != 0 && heights.Length != 0) Debug.Assert(displacements.Length == heights.Length); + var countNorms = (normals.Length != 0 ? normals.Length : 0); var countTotal = countPoints + countNorms * 3; if (countPoints > 0) { // Retrieve Results - if (displacements != null) _queryResults.Slice(segment.x, countPoints).CopyTo(displacements); + if (displacements.Length != 0) displacements.CopyFrom(_queryResults.Slice(segment.x, countPoints)); // Retrieve Result heights - if (heights != null) + if (heights.Length != 0) { var seaLevel = OceanRenderer.Instance.SeaLevel; for (int i = 0; i < countPoints; i++) @@ -337,8 +350,9 @@ protected bool RetrieveResults(int guid, Vector3[] displacements, float[] height var px = dx + _queryResults[firstNorm + 3 * i + 1]; var pz = dz + _queryResults[firstNorm + 3 * i + 2]; - normals[i] = Vector3.Cross(p - px, p - pz).normalized; - normals[i].y *= -1f; + Vector3 normal = Vector3.Cross(p - px, p - pz).normalized; + normal.y *= -1f; + normals[i] = normal; } } @@ -349,7 +363,7 @@ protected bool RetrieveResults(int guid, Vector3[] displacements, float[] height /// Compute time derivative of the displacements by calculating difference from last query. More complicated than it would seem - results /// may not be available in one or both of the results, or the query locations in the array may change. /// - protected int CalculateVelocities(int i_ownerHash, float i_minSpatialLength, Vector3[] i_queryPositions, Vector3[] results) + protected int CalculateVelocities(int i_ownerHash, float i_minSpatialLength, NativeSlice i_queryPositions, NativeSlice results) { // Need at least 2 returned results to do finite difference if (_queryResultsTime < 0f || _queryResultsTimeLast < 0f) @@ -504,21 +518,21 @@ protected virtual void OnDisable() _segmentRegistrarRingBuffer.ClearAll(); } - public int Query(int i_ownerHash, float i_minSpatialLength, Vector3[] i_queryPoints, Vector3[] o_resultDisps, Vector3[] o_resultNorms, Vector3[] o_resultVels) + public int Query(int i_ownerHash, float i_minSpatialLength, NativeSlice i_queryPoints, NativeSlice o_resultDisps, NativeSlice o_resultNorms, NativeSlice o_resultVels) { var result = (int)QueryStatus.OK; - if (!UpdateQueryPoints(i_ownerHash, i_minSpatialLength, i_queryPoints, o_resultNorms != null ? i_queryPoints : null)) + if (!UpdateQueryPoints(i_ownerHash, i_minSpatialLength, i_queryPoints, o_resultNorms.Length != 0 ? i_queryPoints : default)) { result |= (int)QueryStatus.PostFailed; } - if (!RetrieveResults(i_ownerHash, o_resultDisps, null, o_resultNorms)) + if (!RetrieveResults(i_ownerHash, o_resultDisps, default, o_resultNorms)) { result |= (int)QueryStatus.RetrieveFailed; } - if (o_resultVels != null) + if (o_resultVels.Length != 0) { result |= CalculateVelocities(i_ownerHash, i_minSpatialLength, i_queryPoints, o_resultVels); } diff --git a/crest/Assets/Crest/Crest/Scripts/Collision/QueryDisplacements.cs b/crest/Assets/Crest/Crest/Scripts/Collision/QueryDisplacements.cs index c39a41fe8..aa91a2581 100644 --- a/crest/Assets/Crest/Crest/Scripts/Collision/QueryDisplacements.cs +++ b/crest/Assets/Crest/Crest/Scripts/Collision/QueryDisplacements.cs @@ -2,6 +2,7 @@ // This file is subject to the MIT License as seen in the root of this folder structure (LICENSE) +using Unity.Collections; using UnityEngine; namespace Crest @@ -41,21 +42,21 @@ protected override void BindInputsAndOutputs(PropertyWrapperComputeStandalone wr ShaderProcessQueries.SetBuffer(_kernelHandle, sp_ResultDisplacements, resultsBuffer); } - public int Query(int i_ownerHash, float i_minSpatialLength, Vector3[] i_queryPoints, float[] o_resultHeights, Vector3[] o_resultNorms, Vector3[] o_resultVels) + public int Query(int i_ownerHash, float i_minSpatialLength, NativeSlice i_queryPoints, NativeSlice o_resultHeights, NativeSlice o_resultNorms, NativeSlice o_resultVels) { var result = (int)QueryStatus.OK; - if (!UpdateQueryPoints(i_ownerHash, i_minSpatialLength, i_queryPoints, o_resultNorms != null ? i_queryPoints : null)) + if (!UpdateQueryPoints(i_ownerHash, i_minSpatialLength, i_queryPoints, o_resultNorms.Length != 0 ? i_queryPoints : o_resultNorms)) { result |= (int)QueryStatus.PostFailed; } - if (!RetrieveResults(i_ownerHash, null, o_resultHeights, o_resultNorms)) + if (!RetrieveResults(i_ownerHash, default, o_resultHeights, o_resultNorms)) { result |= (int)QueryStatus.RetrieveFailed; } - if (o_resultVels != null) + if (o_resultVels.Length != 0) { result |= CalculateVelocities(i_ownerHash, i_minSpatialLength, i_queryPoints, o_resultVels); } diff --git a/crest/Assets/Crest/Crest/Scripts/Collision/QueryFlow.cs b/crest/Assets/Crest/Crest/Scripts/Collision/QueryFlow.cs index 92fbd2024..2e5194877 100644 --- a/crest/Assets/Crest/Crest/Scripts/Collision/QueryFlow.cs +++ b/crest/Assets/Crest/Crest/Scripts/Collision/QueryFlow.cs @@ -2,6 +2,7 @@ // This file is subject to the MIT License as seen in the root of this folder structure (LICENSE) +using Unity.Collections; using UnityEngine; namespace Crest @@ -41,9 +42,9 @@ protected override void BindInputsAndOutputs(PropertyWrapperComputeStandalone wr ShaderProcessQueries.SetBuffer(_kernelHandle, sp_ResultFlows, resultsBuffer); } - public int Query(int i_ownerHash, float i_minSpatialLength, Vector3[] i_queryPoints, Vector3[] o_resultFlows) + public int Query(int i_ownerHash, float i_minSpatialLength, NativeSlice i_queryPoints, NativeSlice o_resultFlows) { - return Query(i_ownerHash, i_minSpatialLength, i_queryPoints, o_resultFlows, null, null); + return Query(i_ownerHash, i_minSpatialLength, i_queryPoints, o_resultFlows, default, default); } } } diff --git a/crest/Assets/Crest/Crest/Scripts/Collision/RayTraceHelper.cs b/crest/Assets/Crest/Crest/Scripts/Collision/RayTraceHelper.cs index 0c149e101..48ecfccc5 100644 --- a/crest/Assets/Crest/Crest/Scripts/Collision/RayTraceHelper.cs +++ b/crest/Assets/Crest/Crest/Scripts/Collision/RayTraceHelper.cs @@ -1,4 +1,6 @@ -using UnityEngine; +using System; +using Unity.Collections; +using UnityEngine; namespace Crest { @@ -6,10 +8,10 @@ namespace Crest /// Helper to trace a ray against the ocean surface, by sampling at a set of points along the ray and interpolating the /// intersection location. /// - public class RayTraceHelper + public class RayTraceHelper : IDisposable { - Vector3[] _queryPos; - Vector3[] _queryResult; + NativeArray _queryPos; + NativeArray _queryResult; float _rayLength; float _rayStepSize; @@ -38,8 +40,14 @@ public RayTraceHelper(float rayLength, float rayStepSize = 2f) Debug.LogWarning($"RayTraceHelper: ray steps exceed maximum ({maxStepCount}), step size increased to {_rayStepSize} to reduce step count."); } - _queryPos = new Vector3[stepCount]; - _queryResult = new Vector3[stepCount]; + _queryPos = new NativeArray(stepCount, Allocator.Persistent); + _queryResult = new NativeArray(stepCount, Allocator.Persistent); + } + + public void Dispose() + { + _queryPos.Dispose(); + _queryResult.Dispose(); } /// @@ -78,7 +86,7 @@ public bool Trace(out float o_distance) return false; } - var status = OceanRenderer.Instance.CollisionProvider.Query(GetHashCode(), _minLength, _queryPos, _queryResult, null, null); + var status = OceanRenderer.Instance.CollisionProvider.Query(GetHashCode(), _minLength, _queryPos, _queryResult, default, default); if (!OceanRenderer.Instance.CollisionProvider.RetrieveSucceeded(status)) { diff --git a/crest/Assets/Crest/Crest/Scripts/Collision/SamplingHelpers.cs b/crest/Assets/Crest/Crest/Scripts/Collision/SamplingHelpers.cs index 4b6de9393..6b9b57d25 100644 --- a/crest/Assets/Crest/Crest/Scripts/Collision/SamplingHelpers.cs +++ b/crest/Assets/Crest/Crest/Scripts/Collision/SamplingHelpers.cs @@ -1,4 +1,5 @@ -using UnityEngine; +using Unity.Collections; +using UnityEngine; namespace Crest { @@ -8,10 +9,7 @@ namespace Crest /// public class SampleHeightHelper { - Vector3[] _queryPos = new Vector3[1]; - Vector3[] _queryResult = new Vector3[1]; - Vector3[] _queryResultNormal = new Vector3[1]; - Vector3[] _queryResultVel = new Vector3[1]; + Vector3 _queryPosition; float _minLength = 0f; @@ -23,7 +21,7 @@ public class SampleHeightHelper /// pass in the boats width. Larger objects will ignore small wavelengths. public void Init(Vector3 i_queryPos, float i_minLength) { - _queryPos[0] = i_queryPos; + _queryPosition = i_queryPos; _minLength = i_minLength; } @@ -32,63 +30,95 @@ public void Init(Vector3 i_queryPos, float i_minLength) /// public bool Sample(ref float o_height) { - var status = OceanRenderer.Instance.CollisionProvider.Query(GetHashCode(), _minLength, _queryPos, _queryResult, null, null); + NativeArray queryPositions = new NativeArray(1, Allocator.Temp); + queryPositions[0] = _queryPosition; + NativeArray queryResults = new NativeArray(1, Allocator.Temp); + var status = OceanRenderer.Instance.CollisionProvider.Query(GetHashCode(), _minLength, queryPositions, queryResults, default, default); - if (!OceanRenderer.Instance.CollisionProvider.RetrieveSucceeded(status)) + if (OceanRenderer.Instance.CollisionProvider.RetrieveSucceeded(status)) { - return false; + o_height = queryResults[0] + OceanRenderer.Instance.SeaLevel; } - o_height = _queryResult[0].y + OceanRenderer.Instance.SeaLevel; + queryResults.Dispose(); + queryPositions.Dispose(); - return true; + return OceanRenderer.Instance.CollisionProvider.RetrieveSucceeded(status); } public bool Sample(ref float o_height, ref Vector3 o_normal) { - var status = OceanRenderer.Instance.CollisionProvider.Query(GetHashCode(), _minLength, _queryPos, _queryResult, _queryResultNormal, null); + NativeArray queryPositions = new NativeArray(1, Allocator.Temp); + queryPositions[0] = _queryPosition; + NativeArray queryResults = new NativeArray(1, Allocator.Temp); + NativeArray queryResultNormals = new NativeArray(1, Allocator.Temp); - if (!OceanRenderer.Instance.CollisionProvider.RetrieveSucceeded(status)) + var status = OceanRenderer.Instance.CollisionProvider.Query(GetHashCode(), _minLength, queryPositions, queryResults, queryResultNormals, default); + + if (OceanRenderer.Instance.CollisionProvider.RetrieveSucceeded(status)) { - return false; + o_height = queryResults[0] + OceanRenderer.Instance.SeaLevel; + o_normal = queryResultNormals[0]; } - o_height = _queryResult[0].y + OceanRenderer.Instance.SeaLevel; - o_normal = _queryResultNormal[0]; - return true; + queryResultNormals.Dispose(); + queryResults.Dispose(); + queryPositions.Dispose(); + + return OceanRenderer.Instance.CollisionProvider.RetrieveSucceeded(status); } public bool Sample(ref float o_height, ref Vector3 o_normal, ref Vector3 o_surfaceVel) { - var status = OceanRenderer.Instance.CollisionProvider.Query(GetHashCode(), _minLength, _queryPos, _queryResult, _queryResultNormal, _queryResultVel); + NativeArray queryPositions = new NativeArray(1, Allocator.Temp); + queryPositions[0] = _queryPosition; - if (!OceanRenderer.Instance.CollisionProvider.RetrieveSucceeded(status)) + NativeArray queryResults = new NativeArray(1, Allocator.Temp); + NativeArray queryResultNormals = new NativeArray(1, Allocator.Temp); + NativeArray queryResultVels = new NativeArray(1, Allocator.Temp); + var status = OceanRenderer.Instance.CollisionProvider.Query(GetHashCode(), _minLength, queryPositions, queryResults, queryResultNormals, queryResultVels); + + if (OceanRenderer.Instance.CollisionProvider.RetrieveSucceeded(status)) { - return false; + o_height = queryResults[0] + OceanRenderer.Instance.SeaLevel; + o_normal = queryResultNormals[0]; + o_surfaceVel = queryResultVels[0]; } - o_height = _queryResult[0].y + OceanRenderer.Instance.SeaLevel; - o_normal = _queryResultNormal[0]; - o_surfaceVel = _queryResultVel[0]; - return true; + queryResultVels.Dispose(); + queryResultNormals.Dispose(); + queryResults.Dispose(); + queryPositions.Dispose(); + + return OceanRenderer.Instance.CollisionProvider.RetrieveSucceeded(status); } public bool Sample(ref Vector3 o_displacementToPoint, ref Vector3 o_normal, ref Vector3 o_surfaceVel) { - var status = OceanRenderer.Instance.CollisionProvider.Query(GetHashCode(), _minLength, _queryPos, _queryResult, _queryResultNormal, _queryResultVel); + NativeArray queryPositions = new NativeArray(1, Allocator.Temp); + queryPositions[0] = _queryPosition; - if (!OceanRenderer.Instance.CollisionProvider.RetrieveSucceeded(status)) + NativeArray queryResults = new NativeArray(1, Allocator.Temp); + NativeArray queryResultNormals = new NativeArray(1, Allocator.Temp); + NativeArray queryResultVels = new NativeArray(1, Allocator.Temp); + var status = OceanRenderer.Instance.CollisionProvider.Query(GetHashCode(), _minLength, queryPositions, queryResults, queryResultNormals, queryResultVels); + + if (OceanRenderer.Instance.CollisionProvider.RetrieveSucceeded(status)) { - return false; + o_displacementToPoint = queryResults[0]; + o_normal = queryResultNormals[0]; + o_surfaceVel = queryResultVels[0]; } - o_displacementToPoint = _queryResult[0]; - o_normal = _queryResultNormal[0]; - o_surfaceVel = _queryResultVel[0]; - return true; + queryResultVels.Dispose(); + queryResultNormals.Dispose(); + queryResults.Dispose(); + queryPositions.Dispose(); + + return OceanRenderer.Instance.CollisionProvider.RetrieveSucceeded(status); } } @@ -98,8 +128,7 @@ public bool Sample(ref Vector3 o_displacementToPoint, ref Vector3 o_normal, ref /// public class SampleFlowHelper { - Vector3[] _queryPos = new Vector3[1]; - Vector3[] _queryResult = new Vector3[1]; + Vector3 _queryPosition; float _minLength = 0f; @@ -111,7 +140,7 @@ public class SampleFlowHelper /// pass in the boats width. Larger objects will filter out detailed flow information. public void Init(Vector3 i_queryPos, float i_minLength) { - _queryPos[0] = i_queryPos; + _queryPosition = i_queryPos; _minLength = i_minLength; } @@ -120,18 +149,24 @@ public void Init(Vector3 i_queryPos, float i_minLength) /// public bool Sample(ref Vector2 o_flow) { - var status = QueryFlow.Instance.Query(GetHashCode(), _minLength, _queryPos, _queryResult); - if (!QueryFlow.Instance.RetrieveSucceeded(status)) + NativeArray queryPositions = new NativeArray(1, Allocator.Temp); + queryPositions[0] = _queryPosition; + NativeArray queryResults = new NativeArray(1, Allocator.Temp); + var status = QueryFlow.Instance.Query(GetHashCode(), _minLength, queryPositions, queryResults); + + if (QueryFlow.Instance.RetrieveSucceeded(status)) { - return false; + // We don't support float2 queries unfortunately, so unpack from float3 + o_flow.x = queryResults[0].x; + o_flow.y = queryResults[0].z; } - // We don't support float2 queries unfortunately, so unpack from float3 - o_flow.x = _queryResult[0].x; - o_flow.y = _queryResult[0].z; + queryResults.Dispose(); + queryPositions.Dispose(); + - return true; + return QueryFlow.Instance.RetrieveSucceeded(status); } } } diff --git a/crest/Assets/Crest/Crest/Scripts/Collision/VisualiseCollisionArea.cs b/crest/Assets/Crest/Crest/Scripts/Collision/VisualiseCollisionArea.cs index e83654904..597395bdd 100644 --- a/crest/Assets/Crest/Crest/Scripts/Collision/VisualiseCollisionArea.cs +++ b/crest/Assets/Crest/Crest/Scripts/Collision/VisualiseCollisionArea.cs @@ -1,4 +1,5 @@ -using UnityEngine; +using Unity.Collections; +using UnityEngine; namespace Crest { @@ -10,12 +11,24 @@ public class VisualiseCollisionArea : MonoBehaviour [SerializeField] float _objectWidth = 0f; - float[] _resultHeights = new float[s_steps * s_steps]; + NativeArray _resultHeights; static float s_radius = 5f; static readonly int s_steps = 10; - Vector3[] _samplePositions = new Vector3[s_steps * s_steps]; + NativeArray _samplePositions; + + void Awake() + { + _resultHeights = new NativeArray(s_steps * s_steps, Allocator.Persistent); + _samplePositions = new NativeArray(s_steps * s_steps, Allocator.Persistent); + } + + void OnDestroy() + { + _resultHeights.Dispose(); + _samplePositions.Dispose(); + } void Update() { @@ -30,13 +43,14 @@ void Update() { for (int j = 0; j < s_steps; j++) { - _samplePositions[j * s_steps + i] = new Vector3(((i + 0.5f) - s_steps / 2f) * s_radius, 0f, ((j + 0.5f) - s_steps / 2f) * s_radius); - _samplePositions[j * s_steps + i].x += transform.position.x; - _samplePositions[j * s_steps + i].z += transform.position.z; + Vector3 samplePosition = new Vector3(((i + 0.5f) - s_steps / 2f) * s_radius, 0f, ((j + 0.5f) - s_steps / 2f) * s_radius); + samplePosition.x += transform.position.x; + samplePosition.z += transform.position.z; + _samplePositions[j * s_steps + i] = samplePosition; } } - if (collProvider.RetrieveSucceeded(collProvider.Query(GetHashCode(), _objectWidth, _samplePositions, _resultHeights, null, null))) + if (collProvider.RetrieveSucceeded(collProvider.Query(GetHashCode(), _objectWidth, _samplePositions, _resultHeights, default, default))) { for (int i = 0; i < s_steps; i++) { diff --git a/crest/Assets/Crest/Crest/Scripts/Collision/VisualiseRayTrace.cs b/crest/Assets/Crest/Crest/Scripts/Collision/VisualiseRayTrace.cs index b307256ae..5c76a3f2d 100644 --- a/crest/Assets/Crest/Crest/Scripts/Collision/VisualiseRayTrace.cs +++ b/crest/Assets/Crest/Crest/Scripts/Collision/VisualiseRayTrace.cs @@ -7,7 +7,17 @@ namespace Crest /// public class VisualiseRayTrace : MonoBehaviour { - RayTraceHelper _rayTrace = new RayTraceHelper(50f, 2f); + RayTraceHelper _rayTrace; + + void Awake() + { + _rayTrace = new RayTraceHelper(50f, 2f); + } + + void OnDestroy() + { + _rayTrace.Dispose(); + } void Update() { @@ -29,5 +39,7 @@ void Update() Debug.DrawLine(transform.position, transform.position + transform.forward * 50f, Color.red); } } + + } } diff --git a/crest/Assets/Crest/Crest/Scripts/Interaction/BoatProbes.cs b/crest/Assets/Crest/Crest/Scripts/Interaction/BoatProbes.cs index a0aee2638..9d352d839 100644 --- a/crest/Assets/Crest/Crest/Scripts/Interaction/BoatProbes.cs +++ b/crest/Assets/Crest/Crest/Scripts/Interaction/BoatProbes.cs @@ -3,6 +3,7 @@ // Shout out to @holdingjason who posted a first version of this script here: https://github.com/huwb/crest-oceanrender/pull/100 using System; +using Unity.Collections; using UnityEngine; using UnityEngine.Serialization; @@ -63,9 +64,9 @@ public class BoatProbes : FloatingObjectBase float _totalWeight; - Vector3[] _queryPoints; - Vector3[] _queryResultDisps; - Vector3[] _queryResultVels; + NativeArray _queryPoints; + NativeArray _queryResultDisps; + NativeArray _queryResultVels; SampleFlowHelper _sampleFlowHelper = new SampleFlowHelper(); @@ -82,9 +83,16 @@ private void Start() CalcTotalWeight(); - _queryPoints = new Vector3[_forcePoints.Length + 1]; - _queryResultDisps = new Vector3[_forcePoints.Length + 1]; - _queryResultVels = new Vector3[_forcePoints.Length + 1]; + _queryPoints = new NativeArray(_forcePoints.Length + 1, Allocator.Persistent); + _queryResultDisps = new NativeArray(_forcePoints.Length + 1, Allocator.Persistent); + _queryResultVels = new NativeArray(_forcePoints.Length + 1, Allocator.Persistent); + } + + private void OnDestroy() + { + _queryPoints.Dispose(); + _queryResultDisps.Dispose(); + _queryResultVels.Dispose(); } void CalcTotalWeight() @@ -114,7 +122,7 @@ private void FixedUpdate() var waterSurfaceVel = _queryResultVels[_forcePoints.Length]; - if(QueryFlow.Instance) + if (QueryFlow.Instance) { _sampleFlowHelper.Init(transform.position, _minSpatialLength); Vector2 surfaceFlow = Vector2.zero; @@ -137,7 +145,7 @@ void UpdateWaterQueries(ICollProvider collProvider) } _queryPoints[_forcePoints.Length] = transform.position; - collProvider.Query(GetHashCode(), ObjectWidth, _queryPoints, _queryResultDisps, null, _queryResultVels); + collProvider.Query(GetHashCode(), ObjectWidth, _queryPoints, _queryResultDisps, default, _queryResultVels); } void FixedUpdateEngine() diff --git a/crest/Assets/Crest/Crest/Scripts/Interaction/ObjectWaterInteractionAdaptor.cs b/crest/Assets/Crest/Crest/Scripts/Interaction/ObjectWaterInteractionAdaptor.cs index 565913ca5..aae9b7e71 100644 --- a/crest/Assets/Crest/Crest/Scripts/Interaction/ObjectWaterInteractionAdaptor.cs +++ b/crest/Assets/Crest/Crest/Scripts/Interaction/ObjectWaterInteractionAdaptor.cs @@ -2,6 +2,7 @@ // This file is subject to the MIT License as seen in the root of this folder structure (LICENSE) +using Unity.Collections; using UnityEngine; namespace Crest @@ -16,29 +17,36 @@ public class ObjectWaterInteractionAdaptor : FloatingObjectBase public override Vector3 CalculateDisplacementToObject() { - return _hasWaterData ? _resultDisps[0] : Vector3.zero; + return _hasWaterData ? _resultDisp : Vector3.zero; } - Vector3[] _queryPoints = new Vector3[1]; - Vector3[] _resultDisps = new Vector3[1]; - float _height = -float.MaxValue; Vector3 _velocity; Vector3 _lastPos; + Vector3 _resultDisp; bool _hasWaterData = false; bool _hasVelocity = false; private void Update() { - _queryPoints[0] = transform.position; - var result = OceanRenderer.Instance.CollisionProvider.Query(GetHashCode(), ObjectWidth, _queryPoints, _resultDisps, null, null); + int result; + { + NativeArray queryPoints = new NativeArray(1, Allocator.Temp); + NativeArray resultDisps = new NativeArray(1, Allocator.Temp); + queryPoints[0] = transform.position; + result = OceanRenderer.Instance.CollisionProvider.Query(GetHashCode(), ObjectWidth, queryPoints, resultDisps, default, default); + _resultDisp = resultDisps[0]; + resultDisps.Dispose(); + queryPoints.Dispose(); + } + if (OceanRenderer.Instance.CollisionProvider.RetrieveSucceeded(result)) { _hasWaterData = true; - _height = OceanRenderer.Instance.SeaLevel + _resultDisps[0].y; + _height = OceanRenderer.Instance.SeaLevel + _resultDisp.y; } if (Time.deltaTime > 0.00001f) diff --git a/crest/Assets/Crest/Crest/Scripts/Shapes/ShapeGerstnerBatched.cs b/crest/Assets/Crest/Crest/Scripts/Shapes/ShapeGerstnerBatched.cs index d455e7bf1..052df9d42 100644 --- a/crest/Assets/Crest/Crest/Scripts/Shapes/ShapeGerstnerBatched.cs +++ b/crest/Assets/Crest/Crest/Scripts/Shapes/ShapeGerstnerBatched.cs @@ -2,6 +2,7 @@ // This file is subject to the MIT License as seen in the root of this folder structure (LICENSE) +using Unity.Collections; using UnityEditor; using UnityEngine; using UnityEngine.Rendering; @@ -659,13 +660,15 @@ public bool SampleDisplacement(ref Vector3 i_worldPos, float i_minSpatialLength, return true; } - public int Query(int i_ownerHash, float i_minSpatialLength, Vector3[] i_queryPoints, Vector3[] o_resultDisps, Vector3[] o_resultNorms, Vector3[] o_resultVels) + public int Query(int i_ownerHash, float i_minSpatialLength, NativeSlice i_queryPoints, NativeSlice o_resultDisps, NativeSlice o_resultNorms, NativeSlice o_resultVels) { if (o_resultDisps != null) { for (int i = 0; i < o_resultDisps.Length; i++) { - SampleDisplacement(ref i_queryPoints[i], i_minSpatialLength, out o_resultDisps[i]); + Vector3 queryPoint = i_queryPoints[i]; + SampleDisplacement(ref queryPoint, i_minSpatialLength, out Vector3 resultDisplacement); + o_resultDisps[i] = resultDisplacement; } } @@ -673,10 +676,11 @@ public int Query(int i_ownerHash, float i_minSpatialLength, Vector3[] i_queryPoi { for (int i = 0; i < o_resultNorms.Length; i++) { - Vector3 undispPos; - if (ComputeUndisplacedPosition(ref i_queryPoints[i], i_minSpatialLength, out undispPos)) + Vector3 queryPoint = i_queryPoints[i]; + if (ComputeUndisplacedPosition(ref queryPoint, i_minSpatialLength, out Vector3 undispPos)) { - SampleNormal(ref undispPos, i_minSpatialLength, out o_resultNorms[i]); + SampleNormal(ref undispPos, i_minSpatialLength, out Vector3 resultNorm); + o_resultNorms[i] = resultNorm; } else { @@ -688,13 +692,17 @@ public int Query(int i_ownerHash, float i_minSpatialLength, Vector3[] i_queryPoi return 0; } - public int Query(int i_ownerHash, float i_minSpatialLength, Vector3[] i_queryPoints, float[] o_resultHeights, Vector3[] o_resultNorms, Vector3[] o_resultVels) + public int Query(int i_ownerHash, float i_minSpatialLength, NativeSlice i_queryPoints, NativeSlice o_resultHeights, NativeSlice o_resultNorms, NativeSlice o_resultVels) { if (o_resultHeights != null) { for (int i = 0; i < o_resultHeights.Length; i++) { - SampleHeight(ref i_queryPoints[i], i_minSpatialLength, out o_resultHeights[i]); + Vector3 queryPoint = i_queryPoints[i]; + SampleHeight(ref queryPoint, i_minSpatialLength, out float resultHeight); + i_queryPoints[i] = queryPoint; + o_resultHeights[i] = resultHeight; + } } @@ -702,15 +710,17 @@ public int Query(int i_ownerHash, float i_minSpatialLength, Vector3[] i_queryPoi { for (int i = 0; i < o_resultNorms.Length; i++) { - Vector3 undispPos; - if (ComputeUndisplacedPosition(ref i_queryPoints[i], i_minSpatialLength, out undispPos)) + Vector3 queryPoint = i_queryPoints[i]; + if (ComputeUndisplacedPosition(ref queryPoint, i_minSpatialLength, out Vector3 undispPos)) { - SampleNormal(ref undispPos, i_minSpatialLength, out o_resultNorms[i]); + SampleNormal(ref undispPos, i_minSpatialLength, out Vector3 normal); + o_resultNorms[i] = normal; } else { o_resultNorms[i] = Vector3.up; } + i_queryPoints[i] = queryPoint; } } @@ -718,7 +728,10 @@ public int Query(int i_ownerHash, float i_minSpatialLength, Vector3[] i_queryPoi { for (int i = 0; i < o_resultVels.Length; i++) { - GetSurfaceVelocity(ref i_queryPoints[i], i_minSpatialLength, out o_resultVels[i]); + Vector3 queryPoint = i_queryPoints[i]; + GetSurfaceVelocity(ref queryPoint, i_minSpatialLength, out Vector3 resultVel); + i_queryPoints[i] = queryPoint; + o_resultVels[i] = resultVel; } } From 85654c618c421a9083a95eeb701bf998bf2f5c1d Mon Sep 17 00:00:00 2001 From: Tom Maenan Read Cutting Date: Tue, 28 Jan 2020 23:32:52 +0000 Subject: [PATCH 2/3] Add fix that wasn't saved --- .../Crest/Scripts/Collision/CollProviderNull.cs | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/crest/Assets/Crest/Crest/Scripts/Collision/CollProviderNull.cs b/crest/Assets/Crest/Crest/Scripts/Collision/CollProviderNull.cs index f07ac5dd9..231617724 100644 --- a/crest/Assets/Crest/Crest/Scripts/Collision/CollProviderNull.cs +++ b/crest/Assets/Crest/Crest/Scripts/Collision/CollProviderNull.cs @@ -14,7 +14,7 @@ public class CollProviderNull : ICollProvider { public int Query(int i_ownerHash, float i_minSpatialLength, NativeSlice i_queryPoints, NativeSlice o_resultDisps, NativeSlice o_resultNorms, NativeSlice o_resultVels) { - if (o_resultDisps != null) + if (o_resultDisps.Length != 0) { for (int i = 0; i < o_resultDisps.Length; i++) { @@ -22,7 +22,7 @@ public int Query(int i_ownerHash, float i_minSpatialLength, NativeSlice } } - if (o_resultNorms != null) + if (o_resultNorms.Length != 0) { for (int i = 0; i < o_resultNorms.Length; i++) { @@ -30,7 +30,7 @@ public int Query(int i_ownerHash, float i_minSpatialLength, NativeSlice } } - if (o_resultVels != null) + if (o_resultVels.Length != 0) { for (int i = 0; i < o_resultVels.Length; i++) { @@ -43,7 +43,7 @@ public int Query(int i_ownerHash, float i_minSpatialLength, NativeSlice public int Query(int i_ownerHash, float i_minSpatialLength, NativeSlice i_queryPoints, NativeSlice o_resultHeights, NativeSlice o_resultNorms, NativeSlice o_resultVels) { - if (o_resultHeights != null) + if (o_resultHeights.Length != 0) { for (int i = 0; i < o_resultHeights.Length; i++) { @@ -51,7 +51,7 @@ public int Query(int i_ownerHash, float i_minSpatialLength, NativeSlice } } - if (o_resultNorms != null) + if (o_resultNorms.Length != 0) { for (int i = 0; i < o_resultNorms.Length; i++) { @@ -59,7 +59,7 @@ public int Query(int i_ownerHash, float i_minSpatialLength, NativeSlice } } - if (o_resultVels != null) + if (o_resultVels.Length != 0) { for (int i = 0; i < o_resultVels.Length; i++) { From 46ce3e672e1538379bc2857b189372104ed64afb Mon Sep 17 00:00:00 2001 From: Tom Maenan Read Cutting Date: Tue, 28 Jan 2020 23:34:13 +0000 Subject: [PATCH 3/3] Remove more dangling null checks --- .../Crest/Crest/Scripts/Shapes/ShapeGerstnerBatched.cs | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/crest/Assets/Crest/Crest/Scripts/Shapes/ShapeGerstnerBatched.cs b/crest/Assets/Crest/Crest/Scripts/Shapes/ShapeGerstnerBatched.cs index 052df9d42..7039ac9f9 100644 --- a/crest/Assets/Crest/Crest/Scripts/Shapes/ShapeGerstnerBatched.cs +++ b/crest/Assets/Crest/Crest/Scripts/Shapes/ShapeGerstnerBatched.cs @@ -662,7 +662,7 @@ public bool SampleDisplacement(ref Vector3 i_worldPos, float i_minSpatialLength, public int Query(int i_ownerHash, float i_minSpatialLength, NativeSlice i_queryPoints, NativeSlice o_resultDisps, NativeSlice o_resultNorms, NativeSlice o_resultVels) { - if (o_resultDisps != null) + if (o_resultDisps.Length != 0) { for (int i = 0; i < o_resultDisps.Length; i++) { @@ -672,7 +672,7 @@ public int Query(int i_ownerHash, float i_minSpatialLength, NativeSlice } } - if (o_resultNorms != null) + if (o_resultNorms.Length != 0) { for (int i = 0; i < o_resultNorms.Length; i++) { @@ -694,7 +694,7 @@ public int Query(int i_ownerHash, float i_minSpatialLength, NativeSlice public int Query(int i_ownerHash, float i_minSpatialLength, NativeSlice i_queryPoints, NativeSlice o_resultHeights, NativeSlice o_resultNorms, NativeSlice o_resultVels) { - if (o_resultHeights != null) + if (o_resultHeights.Length != 0) { for (int i = 0; i < o_resultHeights.Length; i++) { @@ -706,7 +706,7 @@ public int Query(int i_ownerHash, float i_minSpatialLength, NativeSlice } } - if (o_resultNorms != null) + if (o_resultNorms.Length != 0) { for (int i = 0; i < o_resultNorms.Length; i++) { @@ -724,7 +724,7 @@ public int Query(int i_ownerHash, float i_minSpatialLength, NativeSlice } } - if (o_resultVels != null) + if (o_resultVels.Length != 0) { for (int i = 0; i < o_resultVels.Length; i++) {