Skip to content

Instantly share code, notes, and snippets.

@chuwilliamson
Last active February 3, 2024 15:17
Show Gist options
  • Save chuwilliamson/815e3a7947fe4a7cee27c94c655e4f47 to your computer and use it in GitHub Desktop.
Save chuwilliamson/815e3a7947fe4a7cee27c94c655e4f47 to your computer and use it in GitHub Desktop.
using UnityEngine;
using System;
//cloth simulation
[Serializable]
public class Particle
{
public Vector3 Position
{
get
{
return m_Position;
}
set
{
m_Position = value;
}
}
public Vector3 Velocity
{
get
{
return m_Velocity;
}
set
{
m_Velocity = value;
}
}
public Vector3 Force
{
get
{
return m_Force;
}
set
{
m_Force = value;
}
}
public float Mass
{
get
{
return m_mass;
}
set
{
m_mass = value;
}
}
//Newton Laws: F = mA
Vector3 m_Position;//position...
Vector3 m_Velocity; //(pos1 - pos0) / (newtime - oldtime)
Vector3 m_Acceleration; //(1/m)f
Vector3 m_Force;
float m_mass;
public bool isKinematic;
Particle() { }
public Particle(Vector3 p, Vector3 v, float mass)
{
m_Position = p;
m_Velocity = v;
m_mass = mass;
m_Force = Vector3.zero;
}
public void AddForce(Vector3 force)
{
Force += force;
}
//Euler integration
// Vn+1 = Vn + An * (newtime - oldtime)
// Rn+1 = Rn + Vn+1 (newtime - oldtime)
public void Update()
{
if (isKinematic)
return;
m_Acceleration = (1f / m_mass) * Force;
m_Velocity += m_Acceleration * Time.fixedDeltaTime;
m_Position += m_Velocity * Time.fixedDeltaTime;
}
}
/// <summary>
/// Cloth Simulation
/// 1. Compute Forces
/// For each particle: Apply gravity
/// For each spring-damper: Compute & apply forces
/// For each triangle: Compute & apply aerodynamic forces
/// 2. Integrate Motion
/// For each particle: Apply forward Euler integration
/// </summary>
/// <summary>
/// The basic spring-damper connects
/// two particles and has three
/// constants defining its behavior
/// Spring constant: ks
/// Damping factor: kd
/// Rest length: l0
/// </summary>
public class SpringDamper
{
// The basic linear spring force in one dimension
//Fs = -KsX = -Ks(L0 - L)
//or -SpringConstant * RestLength - Distance(p1,p2)
Particle p1, p2;
public float Ks;
public float Kd;
public float Lo;
public SpringDamper(Particle P1, Particle P2, float SpringK, float SpringD, float SpringR)
{
Ks = SpringK;
Kd = SpringD;
Lo = SpringR;
p1 = P1;
p2 = P2;
}
public void ComputeForce()
{
Vector3 dist = (p2.Position - p1.Position);
Vector3 distDirection = dist.normalized;
float p1Vel1D = Vector3.Dot(distDirection, p1.Velocity);
float p2Vel1D = Vector3.Dot(distDirection, p2.Velocity);
//spring force linear
float Fs = -Ks * (Lo - dist.magnitude);
//damping force linear
float Fd = -Kd * (p1Vel1D - p2Vel1D);
//spring force 3D
Vector3 SpringForce = (Fs + Fd) * distDirection;
//apply forces
p1.AddForce(SpringForce);
p2.AddForce(-SpringForce);
}
public void Draw()
{
Debug.DrawLine(p1.Position, p2.Position);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment