修改mesh
This commit is contained in:
206
Assets/Scripts/ThirdParty/Rope/Core/PointsExtensions.cs
vendored
Normal file
206
Assets/Scripts/ThirdParty/Rope/Core/PointsExtensions.cs
vendored
Normal file
@@ -0,0 +1,206 @@
|
||||
using UnityEngine;
|
||||
using Unity.Mathematics;
|
||||
using Unity.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
|
||||
namespace NBF
|
||||
{
|
||||
public static class PointsExtensions
|
||||
{
|
||||
// Curve length
|
||||
public static float GetLengthOfCurve(this NativeArray<float3> curve, ref float4x4 transform, bool isLoop = false)
|
||||
{
|
||||
if (curve == null || curve.Length == 0)
|
||||
{
|
||||
return 0.0f;
|
||||
}
|
||||
var sum = 0.0f;
|
||||
var firstPoint = math.mul(transform, new float4(curve[0], 1.0f)).xyz;
|
||||
var lastPoint = firstPoint;
|
||||
for (int i = 1; i < curve.Length; i++)
|
||||
{
|
||||
var point = math.mul(transform, new float4(curve[i], 1.0f)).xyz;
|
||||
sum += math.distance(lastPoint, point);
|
||||
lastPoint = point;
|
||||
}
|
||||
if (isLoop)
|
||||
{
|
||||
sum += math.distance(lastPoint, firstPoint);
|
||||
}
|
||||
return sum;
|
||||
}
|
||||
|
||||
public static float GetLengthOfCurve(this NativeArray<float3> curve, bool isLoop = false)
|
||||
{
|
||||
var transform = float4x4.identity;
|
||||
return curve.GetLengthOfCurve(ref transform, isLoop);
|
||||
}
|
||||
|
||||
public static float GetLengthOfCurve(this IEnumerable<float3> curve, ref float4x4 transform, bool isLoop = false)
|
||||
{
|
||||
var array = new NativeArray<float3>(curve.ToArray(), Allocator.Temp);
|
||||
var sum = array.GetLengthOfCurve(ref transform, isLoop);
|
||||
array.Dispose();
|
||||
return sum;
|
||||
}
|
||||
|
||||
public static float GetLengthOfCurve(this IEnumerable<float3> curve, bool isLoop = false)
|
||||
{
|
||||
var transform = float4x4.identity;
|
||||
return curve.GetLengthOfCurve(ref transform, isLoop);
|
||||
}
|
||||
|
||||
// Curve points
|
||||
private static void GetPointAlongCurve(this NativeArray<float3> curve, ref float4x4 transform, float distance, out float3 point, ref int currentTargetIndex, ref float accumulatedLength)
|
||||
{
|
||||
if (curve.Length < 2)
|
||||
{
|
||||
throw new System.ArgumentException(nameof(curve));
|
||||
}
|
||||
if (currentTargetIndex < 1 || currentTargetIndex >= curve.Length)
|
||||
{
|
||||
throw new System.ArgumentOutOfRangeException(nameof(currentTargetIndex));
|
||||
}
|
||||
|
||||
var previousTarget = curve[currentTargetIndex - 1];
|
||||
while (currentTargetIndex < curve.Length)
|
||||
{
|
||||
var target = curve[currentTargetIndex];
|
||||
var segmentLength = math.distance(previousTarget, target);
|
||||
|
||||
if (distance <= accumulatedLength + segmentLength)
|
||||
{
|
||||
var interpolated = math.lerp(previousTarget, target, (distance - accumulatedLength) / segmentLength);
|
||||
point = math.mul(transform, new float4(interpolated, 1.0f)).xyz;
|
||||
return;
|
||||
}
|
||||
|
||||
currentTargetIndex++;
|
||||
accumulatedLength += segmentLength;
|
||||
previousTarget = target;
|
||||
}
|
||||
|
||||
// numerical precision made this happen, just return last point
|
||||
currentTargetIndex = curve.Length - 1;
|
||||
point = math.mul(transform, new float4(previousTarget, 1.0f)).xyz;
|
||||
}
|
||||
|
||||
public static void GetPointAlongCurve(this NativeArray<float3> curve, ref float4x4 transform, float distance, out float3 point)
|
||||
{
|
||||
var currentTargetIndex = 1;
|
||||
var accumulatedLength = 0.0f;
|
||||
curve.GetPointAlongCurve(ref transform, distance, out point, ref currentTargetIndex, ref accumulatedLength);
|
||||
}
|
||||
|
||||
public static void GetPointAlongCurve(this NativeArray<float3> curve, float distance, out float3 point)
|
||||
{
|
||||
var transform = float4x4.identity;
|
||||
curve.GetPointAlongCurve(ref transform, distance, out point);
|
||||
}
|
||||
|
||||
public static void GetPointAlongCurve(this IEnumerable<float3> curve, ref float4x4 transform, float distance, out float3 point)
|
||||
{
|
||||
var array = new NativeArray<float3>(curve.ToArray(), Allocator.Temp);
|
||||
array.GetPointAlongCurve(ref transform, distance, out point);
|
||||
array.Dispose();
|
||||
}
|
||||
|
||||
public static void GetPointAlongCurve(this IEnumerable<float3> curve, float distance, out float3 point)
|
||||
{
|
||||
var transform = float4x4.identity;
|
||||
curve.GetPointAlongCurve(ref transform, distance, out point);
|
||||
}
|
||||
|
||||
public static void GetPointsAlongCurve(this NativeArray<float3> curve, ref float4x4 transform, float desiredPointDistance, NativeArray<float3> result)
|
||||
{
|
||||
var currentTargetIndex = 1;
|
||||
var accumulatedLength = 0.0f;
|
||||
for (int i = 0; i < result.Length; i++)
|
||||
{
|
||||
curve.GetPointAlongCurve(ref transform, desiredPointDistance * i, out float3 point, ref currentTargetIndex, ref accumulatedLength);
|
||||
|
||||
result[i] = point;
|
||||
}
|
||||
}
|
||||
|
||||
public static void GetPointsAlongCurve(this NativeArray<float3> curve, float desiredPointDistance, NativeArray<float3> result)
|
||||
{
|
||||
var transform = float4x4.identity;
|
||||
curve.GetPointsAlongCurve(ref transform, desiredPointDistance, result);
|
||||
}
|
||||
|
||||
public static void GetPointsAlongCurve(this IEnumerable<float3> curve, ref float4x4 transform, float desiredPointDistance, NativeArray<float3> result)
|
||||
{
|
||||
var array = new NativeArray<float3>(curve.ToArray(), Allocator.Temp);
|
||||
array.GetPointsAlongCurve(ref transform, desiredPointDistance, result);
|
||||
array.Dispose();
|
||||
}
|
||||
|
||||
public static void GetPointsAlongCurve(this IEnumerable<float3> curve, float desiredPointDistance, NativeArray<float3> result)
|
||||
{
|
||||
var transform = float4x4.identity;
|
||||
curve.GetPointsAlongCurve(ref transform, desiredPointDistance, result);
|
||||
}
|
||||
|
||||
// Closest point
|
||||
public static void GetClosestPoint(this NativeArray<float3> curve, float3 point, out int index, out float distance)
|
||||
{
|
||||
index = 0;
|
||||
var closestDistanceSq = math.distancesq(curve[0], point);
|
||||
for (int i = 1; i < curve.Length; i++)
|
||||
{
|
||||
var distSq = math.distancesq(curve[i], point);
|
||||
if (distSq < closestDistanceSq)
|
||||
{
|
||||
index = i;
|
||||
closestDistanceSq = distSq;
|
||||
}
|
||||
}
|
||||
distance = math.sqrt(closestDistanceSq);
|
||||
}
|
||||
|
||||
public static void GetClosestPoint(this NativeArray<float3> curve, Ray ray, out int index, out float distance, out float distanceAlongRay)
|
||||
{
|
||||
index = 0;
|
||||
var origin = (float3)ray.origin;
|
||||
var dir = math.normalizesafe(ray.direction);
|
||||
var closestDistanceAlongRay = math.dot(curve[0] - origin, dir);
|
||||
var closestDistanceSq = math.distancesq(origin + closestDistanceAlongRay * dir, curve[0]);
|
||||
for (int i = 1; i < curve.Length; i++)
|
||||
{
|
||||
var position = curve[i];
|
||||
var rayDist = math.dot(position - origin, dir);
|
||||
var distSq = math.distancesq(origin + rayDist * dir, position);
|
||||
if (distSq < closestDistanceSq)
|
||||
{
|
||||
index = i;
|
||||
closestDistanceAlongRay = rayDist;
|
||||
closestDistanceSq = distSq;
|
||||
}
|
||||
}
|
||||
distance = math.sqrt(closestDistanceSq);
|
||||
distanceAlongRay = closestDistanceAlongRay;
|
||||
}
|
||||
|
||||
// Distance
|
||||
public static void KeepAtDistance(this ref float3 point, ref float3 otherPoint, float distance, float stiffness = 1.0f)
|
||||
{
|
||||
var delta = otherPoint - point;
|
||||
|
||||
var currentDistance = math.length(delta);
|
||||
if (currentDistance > 0.0f)
|
||||
{
|
||||
delta /= currentDistance;
|
||||
}
|
||||
else
|
||||
{
|
||||
delta = float3.zero;
|
||||
}
|
||||
delta *= (currentDistance - distance) * stiffness;
|
||||
|
||||
point += delta;
|
||||
otherPoint -= delta;
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user