Skip to content

Instantly share code, notes, and snippets.

@sketchpunk
Created November 24, 2018 07:34
Show Gist options
  • Save sketchpunk/ea72ffd10dbf7036477136d81d1fb01d to your computer and use it in GitHub Desktop.
Save sketchpunk/ea72ffd10dbf7036477136d81d1fb01d to your computer and use it in GitHub Desktop.
Physics / Spring Joint
/*
The main idea is to prototype a way to apply a bit of spring physics to an object. Many examples online tend to follow the
JiggyBone concept of having an "invisible" point follow along which is then used as a LookAt Vector that can be used to apply
rotation. Follows similar ideas to FABIK style algorithm.
In this example, I wanted for a more Under damping style instead of critical damping. Give it a bit of springyness when movement stops.
So far the class is bare bones and does not include LookAt being applyed to some object. So far It just creates the invisible point
that tries to keep up when the transform changes position and rotates.
*/
class PhysicsJoint{
constructor(e){
this.transform = e.com.Transform; // Reference to Object Transform
this.velocity = new Vec3(); // Current speed moving from position to target.
this.target = new Vec3(); // Position to reach
this.offset = new Vec3( Vec3.UP ); // Distance from position target should be.
this.position = new Vec3( this.transform.position ).add( this.offset ); // Current position for Look At.
//this.mass = 1.0; // Decided not to add mass into it, maybe down the line
this.stiffness = 20; // How Fast the Joint points to the target
this.damping = 3.5; // Delay in movement, creates the springyness
}
update(){
// Create target, use offset and rotation to move point to position.
Vec3.transformQuat( this.offset, this.transform.rotation, this.target)
.add( this.transform.position );
//.........................................
// Apply Spring force and dampening to create acceleration for the velocity
// f = -kx :: spring_force = -stiffness * displacement
// a = f - dv :: acceleration = spring_force - damping * velocity
let a = this.target,
b = this.position,
v = this.velocity;
// v += -kx - dv :: calc acceleration then add it to current velocity
v[0] += (-this.stiffness * ( b[0] - a[0] ) - this.damping * v[0]) * Fungi.deltaTime;
v[1] += (-this.stiffness * ( b[1] - a[1] ) - this.damping * v[1]) * Fungi.deltaTime;
v[2] += (-this.stiffness * ( b[2] - a[2] ) - this.damping * v[2]) * Fungi.deltaTime;
v[3] += (-this.stiffness * ( b[3] - a[3] ) - this.damping * v[3]) * Fungi.deltaTime;
//.........................................
// Move position closer to target. This will be the position for the LookAt Function
b[0] += v[0] * Fungi.deltaTime;
b[1] += v[1] * Fungi.deltaTime;
b[2] += v[2] * Fungi.deltaTime;
b[3] += v[3] * Fungi.deltaTime;
}
}
/////////////////////////////////////////////////////////////////
// NOTES
/////////////////////////////////////////////////////////////////
/*
https://www.khanacademy.org/science/ap-physics-1/simple-harmonic-motion-ap/spring-mass-systems-ap/v/period-dependance-for-mass-on-spring
Force = Mass * Accel :: f = ma
Accel = Force / Mass :: a = f/m
Displacement = Current - Target
Force = -SpringConstant * Displacement :: f = -kx
SpringConstant == Stiffness
optional : Force += Gravity
Accel = (-SpringConstant * Displacement - Damper * Velocity ) / Mass :: a = (-km - dv) / m
Accel = Force * deltaTime // Acceleration per second, but for a frame, needs fraction of a second.
Velocity += Accel
Position += Velocity * DeltaTime
Period = 2 * Pi * sqrt( Mass / SpringConstant ) :: t = 2PI * sqrt( m / k )
----------------------
https://gamedev.stackexchange.com/questions/105728/how-to-program-a-fully-controllable-spring-damped-motion
Sniffness = ( DecareTime^2 * Friction^2 + 4 * pi^2 * CycleNum ^2) / (4 * DecayTime^2)
Friction = csc( pi * CycleNum ) * ( Stiffness - ( 2*pi*CycleNum * e^(-(decayTime*Friction) / 2) * pull ) / ( DecayTime * Stopped ) )
CycleNum = 4 :: How many times to cross zero line
DecayTune = 5 :: how many seconds to reach zero or minimum value
Stopped = 0.01 :: Ending T
Pull = 1 :: starting T.
Velocity -= dt * ( StiffNess * displacement + friction * velocity );
pos += dt * velocity
----------------------
JiggyBone
x = target - current (normally current - target)
f = kx (Only works without -k because X is in reverse)
f += g
a = f / m
v += ad
pos += v + f;
*/
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment