Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
Code sample for doing wave spring physics
//Note: This does _not_ compile, it's just to demonstrate the relevant physics bits
class Main extends luxe.Game {
var fieldWidth:Int = 60;
var fieldDepth:Int = 60;
var physTimeStep:Float = 1 / 60;
var physTimeCounter:Float = 0;
var springK:Float = 100;
var springDampening:Float = 0.00;
var springSpread:Float = 600;
var startHeight:Float = -1500;
var heightTintRange:Float = 10;
var physStepCounter:Int = 0;
var maxPhysSteps:Int = 20;
var fieldVertices:Array<Vertex>;
var springVelocities:Array<Float>;
override function update(dt:Float) {
if (dt > 1) {
return;
}
physTimeCounter += dt;
physStepCounter = 0;
while (physTimeCounter >= physTimeStep && physStepCounter < maxPhysSteps) {
updateSprings(physTimeStep);
physTimeCounter -= physTimeStep;
physStepCounter++;
}
} //update
function updateSprings(dt:Float):Void {
for (x in 0...fieldWidth) {
for (y in 0...fieldDepth) {
runHooke(x, y, dt);
}
}
var avgHeight:Float = 0;
var heightDiff:Float = 0;
for (x in 0...fieldWidth) {
for (y in 0...fieldDepth) {
avgHeight = getNeighborAverage(x, y);
heightDiff = fieldVertices[x * fieldWidth + y].pos.z - avgHeight;
springVelocities[x * fieldWidth + y] += -springSpread * heightDiff * dt; //Effectively another hooke's law, springSpread is k
//springVelocities[x * fieldWidth + y] -= springDampening * springVelocities[x * fieldWidth + y];
}
}
}
function runHooke(x:Int, y:Int, dt:Float):Void {
//0 represents rest height
springVelocities[x * fieldWidth + y] += -springK * (fieldVertices[x * fieldWidth + y].pos.z - 0) * dt;
springVelocities[x * fieldWidth + y] -= springDampening * springVelocities[x * fieldWidth + y];
fieldVertices[x * fieldWidth + y].pos.z += springVelocities[x * fieldWidth + y] * dt;
}
function getNeighborAverage(x:Int, y:Int):Float {
var sum:Float = 0;
var springCounter:Int = 0;
var xStart:Int = x - 1;
var xEnd:Int = x + 1;
var yStart:Int = y - 1;
var yEnd:Int = y + 1;
if (xStart < 0) {
xStart = 0;
}
if (xEnd > fieldWidth - 1) {
xEnd = fieldWidth - 1;
}
if (yStart < 0) {
yStart = 0;
}
if (yEnd > fieldDepth - 1) {
yEnd = fieldDepth - 1;
}
var springCounter:Int = 0;
for (_x in xStart...xEnd + 1) {
for (_y in yStart...yEnd + 1) {
if (!(_x == x && _y == y)) {
if ((_x == xStart || _x == xEnd) && (_y == yStart || _y == yEnd)) {
sum += fieldVertices[_x * fieldWidth + _y].pos.z * 0.7071067811865475;// 1 / sqrt(2), adjusting distance to neighbour by dividing by sart(1^2 + 1^@)
}
else {
sum += fieldVertices[_x * fieldWidth + _y].pos.z;
}
springCounter++;
}
}
}
if (springCounter != 0) {
sum /= springCounter;
}
return sum;
}
} //Main
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment