260 lines
7.3 KiB
C#
260 lines
7.3 KiB
C#
using System.Linq;
|
|
using UnityEngine;
|
|
using UnityEngine.Assertions;
|
|
using Unity.Netcode;
|
|
using System.Collections.Generic;
|
|
|
|
[System.Serializable]
|
|
public class Rope
|
|
{
|
|
public Point[] points;
|
|
public Stick[] sticks;
|
|
|
|
public Rope() {}
|
|
|
|
public Rope(Point[] points, Stick[] sticks)
|
|
{
|
|
this.points = points;
|
|
this.sticks = sticks;
|
|
}
|
|
|
|
public float CalculateLengthOvershoot()
|
|
{
|
|
float sum = 0f;
|
|
foreach (Stick stick in sticks)
|
|
{
|
|
Debug.DrawRay(stick.B.position, (stick.A.position - stick.B.position).normalized * stick.desiredLength);
|
|
float dist = Vector3.Distance(stick.A.position, stick.B.position);
|
|
sum += dist - stick.desiredLength;
|
|
}
|
|
return sum;
|
|
}
|
|
|
|
public static float CalcDiff(Rope r1, Rope r2, bool excludeZ = true)
|
|
{
|
|
if (r1.points.Length != r2.points.Length)
|
|
{
|
|
throw new System.ArgumentException("Ropes are not the same length");
|
|
}
|
|
|
|
float diff = 0;
|
|
if (excludeZ)
|
|
{
|
|
for (int i = 0; i < r1.points.Length; i++)
|
|
{
|
|
Vector3 p1, p2;
|
|
p1 = new Vector2(r1.points[i].position.x, r1.points[i].position.y);
|
|
p2 = new Vector2(r2.points[i].position.x, r2.points[i].position.y);
|
|
diff += Vector2.Distance(p1, p2);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
for (int i = 0; i < r1.points.Length; i++)
|
|
{
|
|
diff += Vector3.Distance(r1.points[i].position, r2.points[i].position);
|
|
}
|
|
}
|
|
return diff;
|
|
}
|
|
|
|
public static NetworkRope ToNetworkRope(Rope rope)
|
|
{
|
|
return new NetworkRope
|
|
{
|
|
positions = rope.points.Select(p => p.position).ToArray(),
|
|
prevPositions = rope.points.Select(p => p.prevPosition).ToArray(),
|
|
locked = rope.points.Select(p => p.locked).ToArray(),
|
|
|
|
// sPosA = rope.sticks.Select(s => s.A.position).ToArray(),
|
|
// sPrevPosA = rope.sticks.Select(s => s.A.prevPosition).ToArray(),
|
|
// sPosB = rope.sticks.Select(s => s.B.position).ToArray(),
|
|
// sPrevPosB = rope.sticks.Select(s => s.B.prevPosition).ToArray(),
|
|
// dead = rope.sticks.Select(s => s.dead).ToArray(),
|
|
};
|
|
}
|
|
|
|
public static Rope FromNetworkRope(NetworkRope nrope, float stickLength)
|
|
{
|
|
Assert.IsTrue(nrope.positions.Length == nrope.prevPositions.Length);
|
|
Point[] points = new Point[nrope.positions.Length];
|
|
for (int i = 0; i < nrope.positions.Length; i++)
|
|
{
|
|
points[i] = new Point(nrope.positions[i], nrope.prevPositions[i], nrope.locked[i]);
|
|
}
|
|
|
|
RopeBuilder builder = new RopeBuilder(new List<Point>(points), new List<Stick>());
|
|
|
|
for (int i = 0; i < (points.Length - 1); i++)
|
|
{
|
|
builder.ConnectPointsWithDesiredLength(i, i + 1, desiredLength: stickLength);
|
|
}
|
|
|
|
return builder.Build();
|
|
}
|
|
|
|
public Rope Copy(float stickLength)
|
|
{
|
|
RopeBuilder builder = new();
|
|
|
|
foreach (var point in points)
|
|
{
|
|
builder.AddPoint(new Point(point.position, point.locked));
|
|
}
|
|
for (int i = 0; i < points.Length - 1; i++)
|
|
{
|
|
builder.ConnectPointsWithDesiredLength(i, i + 1, stickLength);
|
|
}
|
|
|
|
return builder.Build();
|
|
}
|
|
|
|
/* public void NetworkSerialize<T>(BufferSerializer<T> serializer) where T : IReaderWriter
|
|
{
|
|
int pLen = 0;
|
|
int sLen = 0;
|
|
|
|
if (serializer.IsWriter)
|
|
{
|
|
pLen = points.Length;
|
|
sLen = sticks.Length;
|
|
}
|
|
|
|
serializer.SerializeValue(ref pLen);
|
|
serializer.SerializeValue(ref sLen);
|
|
|
|
if (serializer.IsReader)
|
|
{
|
|
points = new Point[pLen];
|
|
sticks = new Stick[sLen];
|
|
|
|
for (int i = 0; i < pLen; i++)
|
|
{
|
|
serializer.GetFastBufferReader().ReadValueSafe(out points[i]);
|
|
}
|
|
|
|
for (int i = 0; i < sLen; i++)
|
|
{
|
|
serializer.GetFastBufferReader().ReadValueSafe(out sticks[i]);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
for (int i = 0; i < pLen; i++)
|
|
{
|
|
points[i].NetworkSerialize(serializer);
|
|
}
|
|
|
|
for (int i = 0; i < sLen; i++)
|
|
{
|
|
sticks[i].NetworkSerialize(serializer);
|
|
}
|
|
}
|
|
} */
|
|
}
|
|
|
|
[System.Serializable]
|
|
public struct NetworkRope : INetworkSerializable
|
|
{
|
|
// For rope points
|
|
public Vector3[] positions;
|
|
public Vector3[] prevPositions;
|
|
public bool[] locked;
|
|
|
|
// For rope sticks
|
|
// public Vector3[] sPosA;
|
|
// public Vector3[] sPrevPosA;
|
|
//
|
|
// public Vector3[] sPosB;
|
|
// public Vector3[] sPrevPosB;
|
|
//
|
|
// public bool[] dead;
|
|
|
|
public void NetworkSerialize<T>(BufferSerializer<T> serializer) where T : IReaderWriter
|
|
{
|
|
int positionsLen = 0;
|
|
int prevPositionsLen = 0;
|
|
int lockedLen = 0;
|
|
// int sPosALen = 0;
|
|
// int sPrevPosALen = 0;
|
|
// int sPosBLen = 0;
|
|
// int sPrevPosBLen = 0;
|
|
// int deadLen = 0;
|
|
|
|
if (!serializer.IsReader)
|
|
{
|
|
positionsLen = positions.Length;
|
|
prevPositionsLen = prevPositions.Length;
|
|
lockedLen = locked.Length;
|
|
|
|
// sPosALen = sPosA.Length;
|
|
// sPrevPosALen = sPrevPosA.Length;
|
|
// sPosBLen = sPosB.Length;
|
|
// sPrevPosBLen = sPrevPosB.Length;
|
|
// deadLen = dead.Length;
|
|
}
|
|
|
|
serializer.SerializeValue(ref positionsLen);
|
|
serializer.SerializeValue(ref prevPositionsLen);
|
|
serializer.SerializeValue(ref lockedLen);
|
|
// serializer.SerializeValue(ref sPosALen);
|
|
// serializer.SerializeValue(ref sPrevPosALen);
|
|
// serializer.SerializeValue(ref sPosBLen);
|
|
// serializer.SerializeValue(ref sPrevPosBLen);
|
|
// serializer.SerializeValue(ref deadLen);
|
|
|
|
if (serializer.IsReader)
|
|
{
|
|
positions = new Vector3[positionsLen];
|
|
prevPositions = new Vector3[prevPositionsLen];
|
|
locked = new bool[lockedLen];
|
|
|
|
// sPosA = new Vector3[sPosALen];
|
|
// sPrevPosA = new Vector3[sPrevPosALen];
|
|
// sPosB = new Vector3[sPosBLen];
|
|
// sPrevPosB = new Vector3[sPrevPosBLen];
|
|
// dead = new bool[deadLen];
|
|
}
|
|
|
|
for (int i = 0; i < positionsLen; i++)
|
|
{
|
|
serializer.SerializeValue(ref positions[i]);
|
|
}
|
|
|
|
for (int i = 0; i < prevPositionsLen; i++)
|
|
{
|
|
serializer.SerializeValue(ref prevPositions[i]);
|
|
}
|
|
|
|
for (int i = 0; i < lockedLen; i++)
|
|
{
|
|
serializer.SerializeValue(ref locked[i]);
|
|
}
|
|
|
|
/* for (int i = 0; i < sPosALen; i++)
|
|
{
|
|
serializer.SerializeValue(ref sPosA[i]);
|
|
}
|
|
|
|
for (int i = 0; i < sPrevPosALen; i++)
|
|
{
|
|
serializer.SerializeValue(ref sPrevPosA[i]);
|
|
}
|
|
|
|
for (int i = 0; i < sPosBLen; i++)
|
|
{
|
|
serializer.SerializeValue(ref sPosB[i]);
|
|
}
|
|
|
|
for (int i = 0; i < sPrevPosBLen; i++)
|
|
{
|
|
serializer.SerializeValue(ref sPrevPosB[i]);
|
|
}
|
|
|
|
for (int i = 0; i < deadLen; i++)
|
|
{
|
|
serializer.SerializeValue(ref dead[i]);
|
|
} */
|
|
}
|
|
}
|