Files
UltimateFishing/Assets/Scripts/Assembly-CSharp/MegaRopeDeform.cs
2026-02-21 16:45:37 +08:00

382 lines
9.2 KiB
C#

using System.Collections.Generic;
using UnityEngine;
[AddComponentMenu("Modifiers/Rope Deform")]
public class MegaRopeDeform : MegaModifier
{
public float floorOff;
public int NumMasses = 8;
public MegaSoft2D soft = new MegaSoft2D();
public float timeStep = 0.01f;
public float Mass = 10f;
public MegaAxis axis = MegaAxis.Z;
public AnimationCurve stiffnessCrv = new AnimationCurve(new Keyframe(0f, 1f), new Keyframe(1f, 1f));
public float stiffspring = 1f;
public float stiffdamp = 0.1f;
public float spring = 1f;
public float damp = 1f;
public float off;
public bool init;
public float SpringCompress = 1f;
public bool BendSprings = true;
public bool Constraints = true;
public float DampingRatio = 0.5f;
public int pconl;
public int pconr;
public bool DisplayDebug = true;
public int drawsteps = 20;
public float boxsize = 0.01f;
public Transform left;
public Transform right;
public float weight;
public float weightPos = 0.5f;
public Vector2[] masspos;
private int ax;
private float minx;
private float width;
public override string ModName()
{
return "RopeDeform";
}
public override string GetHelpURL()
{
return "?page_id=1524";
}
public override Vector3 Map(int i, Vector3 p)
{
p = tm.MultiplyPoint3x4(p);
float t = (p[ax] - minx) / width;
Vector2 vector = Interp1a(t);
p.y += vector.y + off * 0.01f;
p[ax] = vector.x;
return invtm.MultiplyPoint3x4(p);
}
public override bool ModLateUpdate(MegaModContext mc)
{
ax = (int)axis;
minx = bbox.min[ax];
width = bbox.max[ax] - bbox.min[ax];
if (init || NumMasses != soft.masses.Count)
{
init = false;
Init();
}
AddWeight();
UpdateRope();
return Prepare(mc);
}
public override bool Prepare(MegaModContext mc)
{
return true;
}
public void Build(MegaModContext mc)
{
}
public void UpdateRope()
{
if (soft != null)
{
soft.Update();
for (int i = 0; i < soft.masses.Count; i++)
{
masspos[i + 1] = soft.masses[i].pos;
soft.masses[i].forcec = Vector2.zero;
}
masspos[0] = soft.masses[0].pos - (soft.masses[1].pos - soft.masses[0].pos);
masspos[masspos.Length - 1] = soft.masses[soft.masses.Count - 1].pos + (soft.masses[soft.masses.Count - 1].pos - soft.masses[soft.masses.Count - 2].pos);
if (left != null)
{
Vector3 vector = base.transform.worldToLocalMatrix.MultiplyPoint(left.position);
soft.constraints[pconl].pos.x = vector[ax];
soft.constraints[pconl].pos.y = vector.y;
}
if (right != null)
{
Vector3 vector2 = base.transform.worldToLocalMatrix.MultiplyPoint(right.position);
soft.constraints[pconr].pos.x = vector2[ax];
soft.constraints[pconr].pos.y = vector2.y;
}
}
}
public void Init()
{
if (soft.masses == null)
{
soft.masses = new List<Mass2D>();
}
soft.masses.Clear();
float num = Mass / (float)NumMasses;
int index = (int)axis;
Vector2 zero = Vector2.zero;
damp = DampingRatio * 0.45f * (2f * Mathf.Sqrt(num * spring));
for (int i = 0; i < NumMasses; i++)
{
float t = (float)i / (float)(NumMasses - 1);
zero.x = Mathf.Lerp(bbox.min[index], bbox.max[index], t);
Mass2D item = new Mass2D(num, zero);
soft.masses.Add(item);
}
masspos = new Vector2[soft.masses.Count + 2];
for (int j = 0; j < soft.masses.Count; j++)
{
masspos[j + 1] = soft.masses[j].pos;
}
if (soft.springs == null)
{
soft.springs = new List<Spring2D>();
}
soft.springs.Clear();
if (soft.constraints == null)
{
soft.constraints = new List<Constraint2D>();
}
soft.constraints.Clear();
for (int k = 0; k < soft.masses.Count - 1; k++)
{
Spring2D spring2D = new Spring2D(k, k + 1, spring, damp, soft);
spring2D.restLen *= SpringCompress;
soft.springs.Add(spring2D);
if (Constraints)
{
Constraint2D item2 = Constraint2D.CreateLenCon(k, k + 1, spring2D.restLen);
soft.constraints.Add(item2);
}
}
if (BendSprings)
{
int num2 = 2;
for (int l = 0; l < soft.masses.Count - num2; l++)
{
float time = (float)l / (float)soft.masses.Count;
Spring2D spring2D2 = new Spring2D(l, l + num2, stiffspring * stiffnessCrv.Evaluate(time), stiffdamp * stiffnessCrv.Evaluate(time), soft);
soft.springs.Add(spring2D2);
Constraint2D item3 = Constraint2D.CreateLenCon(l, l + num2, spring2D2.restLen);
soft.constraints.Add(item3);
}
}
zero.x = bbox.min[index];
zero.y = 0f;
Constraint2D item4 = Constraint2D.CreatePointCon(0, zero);
pconl = soft.constraints.Count;
soft.constraints.Add(item4);
zero.x = bbox.max[index];
item4 = Constraint2D.CreatePointCon(soft.masses.Count - 1, zero);
pconr = soft.constraints.Count;
soft.constraints.Add(item4);
soft.DoConstraints();
}
private void DrawSpline(int steps)
{
if (soft.masses == null || soft.masses.Count == 0)
{
return;
}
Vector3 vector = Interp1a(0f);
if (ax == 2)
{
float x = vector.x;
vector.x = vector.z;
vector.z = x;
}
for (int i = 1; i <= steps; i++)
{
if ((i & 1) == 1)
{
Gizmos.color = Color.white;
}
else
{
Gizmos.color = Color.black;
}
float t = (float)i / (float)steps;
Vector3 vector2 = Interp1a(t);
if (ax == 2)
{
float x2 = vector2.x;
vector2.x = vector2.z;
vector2.z = x2;
}
Gizmos.DrawLine(vector, vector2);
vector = vector2;
}
}
public void OnDrawGizmos()
{
Display();
}
private void Display()
{
Gizmos.matrix = base.transform.localToWorldMatrix;
if (DisplayDebug && soft != null && soft.masses != null)
{
DrawSpline(drawsteps);
Vector3 zero = Vector3.zero;
Gizmos.color = Color.yellow;
for (int i = 0; i < soft.masses.Count; i++)
{
if (ax == 0)
{
zero.x = soft.masses[i].pos.x;
zero.y = soft.masses[i].pos.y;
zero.z = 0f;
}
else
{
zero.z = soft.masses[i].pos.x;
zero.y = soft.masses[i].pos.y;
zero.x = 0f;
}
Gizmos.DrawCube(zero, Vector3.one * boxsize * 0.1f);
}
if (weightPos >= 0f && weightPos < 100f)
{
Gizmos.color = Color.blue;
Vector2 vector = Interp1a(weightPos * 0.01f);
if (ax == 0)
{
zero.x = vector.x;
zero.y = vector.y;
zero.z = 0f;
}
else
{
zero.z = vector.x;
zero.y = vector.y;
zero.x = 0f;
}
Gizmos.DrawCube(zero, Vector3.one * boxsize * 0.2f);
}
}
Gizmos.matrix = Matrix4x4.identity;
}
public Vector2 Interp1(float t)
{
int num = soft.masses.Count - 3;
int num2 = Mathf.Min(Mathf.FloorToInt(t * (float)num), num - 1);
float num3 = t * (float)num - (float)num2;
Vector2 pos = soft.masses[num2].pos;
Vector2 pos2 = soft.masses[num2 + 1].pos;
Vector2 pos3 = soft.masses[num2 + 2].pos;
Vector2 pos4 = soft.masses[num2 + 3].pos;
return 0.5f * ((-pos + 3f * pos2 - 3f * pos3 + pos4) * (num3 * num3 * num3) + (2f * pos - 5f * pos2 + 4f * pos3 - pos4) * (num3 * num3) + (-pos + pos3) * num3 + 2f * pos2);
}
public Vector2 Interp1a(float t)
{
int num = masspos.Length - 3;
int num2 = Mathf.Min(Mathf.FloorToInt(t * (float)num), num - 1);
float num3 = t * (float)num - (float)num2;
Vector2 vector = masspos[num2];
Vector2 vector2 = masspos[num2 + 1];
Vector2 vector3 = masspos[num2 + 2];
Vector2 vector4 = masspos[num2 + 3];
return 0.5f * ((-vector + 3f * vector2 - 3f * vector3 + vector4) * (num3 * num3 * num3) + (2f * vector - 5f * vector2 + 4f * vector3 - vector4) * (num3 * num3) + (-vector + vector3) * num3 + 2f * vector2);
}
private void AddWeight()
{
if (weightPos >= 0f && weightPos < 100f)
{
float num = soft.masses.Count - 1;
int num2 = (int)(num * weightPos * 0.01f);
int index = num2 + 1;
float num3 = num * weightPos * 0.01f - (float)num2;
Vector3 vector = Vector2.zero;
vector.y = weight * (1f - num3);
soft.masses[num2].forcec = vector;
vector.y = weight * num3;
soft.masses[index].forcec = vector;
}
}
public float GetPos(float alpha)
{
return Interp1a(alpha).y;
}
public Vector2 GetPos2(float alpha)
{
return Interp1a(alpha);
}
public Vector2 GetPos3(float v)
{
for (int i = 1; i < masspos.Length - 1; i++)
{
if (v > masspos[i].x && v < masspos[i + 1].x)
{
float num = (v - masspos[i].x) / (masspos[i + 1].x - masspos[i].x);
Vector2 vector = masspos[i - 1];
Vector2 vector2 = masspos[i];
Vector2 vector3 = masspos[i + 1];
Vector2 vector4 = masspos[i + 2];
return 0.5f * ((-vector + 3f * vector2 - 3f * vector3 + vector4) * (num * num * num) + (2f * vector - 5f * vector2 + 4f * vector3 - vector4) * (num * num) + (-vector + vector3) * num + 2f * vector2);
}
}
return Vector2.zero;
}
public Vector2 SetWeight(float v, float weight)
{
for (int i = 1; i < masspos.Length - 2; i++)
{
if (v > masspos[i].x && v < masspos[i + 1].x)
{
float num = (v - masspos[i].x) / (masspos[i + 1].x - masspos[i].x);
Vector2 vector = masspos[i - 1];
Vector2 vector2 = masspos[i];
Vector2 vector3 = masspos[i + 1];
Vector2 vector4 = masspos[i + 2];
Vector2 zero = Vector2.zero;
zero.y = weight * (1f - num);
soft.masses[i - 1].forcec = zero;
zero.y = weight * num;
soft.masses[i].forcec = zero;
return 0.5f * ((-vector + 3f * vector2 - 3f * vector3 + vector4) * (num * num * num) + (2f * vector - 5f * vector2 + 4f * vector3 - vector4) * (num * num) + (-vector + vector3) * num + 2f * vector2);
}
}
return Vector2.zero;
}
}