Created
November 24, 2018 07:34
-
-
Save sketchpunk/ea72ffd10dbf7036477136d81d1fb01d to your computer and use it in GitHub Desktop.
Physics / Spring Joint
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
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