Smoother particle display; store particle states. Forward integration remains.
This commit is contained in:
parent
64ffc31229
commit
5a24ffcd42
13
main.lua
13
main.lua
|
@ -126,7 +126,7 @@ local function OnVictory()
|
||||||
end
|
end
|
||||||
|
|
||||||
local function OnImpact( impact )
|
local function OnImpact( impact )
|
||||||
|
if not impact then return end
|
||||||
local score = BeatScore( impact.t )
|
local score = BeatScore( impact.t )
|
||||||
--DEBUG
|
--DEBUG
|
||||||
state.lastBeatScore = score
|
state.lastBeatScore = score
|
||||||
|
@ -150,6 +150,9 @@ local function OnImpact( impact )
|
||||||
end
|
end
|
||||||
|
|
||||||
love.audio.play( sound )
|
love.audio.play( sound )
|
||||||
|
|
||||||
|
marble.OnImpact( impact )
|
||||||
|
wave.OnImpact( impact )
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
|
@ -185,6 +188,14 @@ function love.update( dt )
|
||||||
marble.Integrate( step )
|
marble.Integrate( step )
|
||||||
wave.Integrate( step )
|
wave.Integrate( step )
|
||||||
|
|
||||||
|
OnImpact(
|
||||||
|
DetectCollision(
|
||||||
|
marble.Current(), marble.Next(),
|
||||||
|
wave.Current(), wave.Next() ))
|
||||||
|
|
||||||
|
marble.Update()
|
||||||
|
wave.Update()
|
||||||
|
|
||||||
dt = dt - step
|
dt = dt - step
|
||||||
end
|
end
|
||||||
state.timeToSimulate = dt
|
state.timeToSimulate = dt
|
||||||
|
|
77
marble.lua
77
marble.lua
|
@ -3,31 +3,41 @@ local love = love
|
||||||
--local wave = assert( require "wave" )
|
--local wave = assert( require "wave" )
|
||||||
local oldBuffer = love.graphics.newCanvas()
|
local oldBuffer = love.graphics.newCanvas()
|
||||||
local newBuffer = love.graphics.newCanvas()
|
local newBuffer = love.graphics.newCanvas()
|
||||||
local state
|
local oldState, curState, newState
|
||||||
|
|
||||||
local FRICTION = 0.01
|
local FRICTION = 0.01
|
||||||
local MAXSPEED = 5.0
|
local MAXSPEED = 5.0
|
||||||
|
local ddx, ddy = 0.0, 0.0
|
||||||
|
|
||||||
local t, x, y, dx, dy, ddx, ddy
|
local function State( )
|
||||||
|
return { t = 0, x = 0, y = 0, dx = 0, dy = 0 }
|
||||||
|
end
|
||||||
|
|
||||||
|
local function Current() return curState end
|
||||||
|
local function Next() return newState end
|
||||||
|
|
||||||
|
local function Integrate( step )
|
||||||
|
newState.t = love.timer.getTime()
|
||||||
|
newState.dx = (1.0 - FRICTION) * curState.dx + FRICTION * ddx
|
||||||
|
newState.dy = (1.0 - FRICTION) * curState.dy + FRICTION * ddy
|
||||||
|
newState.x = curState.x + newState.dx * step * MAXSPEED
|
||||||
|
newState.y = curState.y + newState.dy * step * MAXSPEED
|
||||||
|
end
|
||||||
|
|
||||||
local function OnImpact( impact )
|
local function OnImpact( impact )
|
||||||
|
--Adjust current trajectory according to collision.
|
||||||
|
return Integrate( impact.tNext - impact.t ) --Hmm! Maybe this should be a fixed step instead for stability's sake.
|
||||||
end
|
end
|
||||||
|
|
||||||
local function Update()
|
local function Update()
|
||||||
|
--Roll the log.
|
||||||
|
for k, v in pairs( oldState ) do
|
||||||
|
oldState[k] = curState[k]
|
||||||
|
curState[k] = newState[k]
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
local function Integrate( step )
|
|
||||||
t = love.timer.getTime()
|
|
||||||
|
|
||||||
dx = (1.0 - FRICTION) * dx + FRICTION * ddx
|
|
||||||
dy = (1.0 - FRICTION) * dy + FRICTION * ddy
|
|
||||||
local xf = x + dx * step * MAXSPEED
|
|
||||||
local yf = y + dy * step * MAXSPEED
|
|
||||||
|
|
||||||
x = xf
|
|
||||||
y = yf
|
|
||||||
end
|
|
||||||
|
|
||||||
local function OnKey()
|
local function OnKey()
|
||||||
ddx = (love.keyboard.isScancodeDown( "d" ) and 1.0 or 0.0) - (love.keyboard.isScancodeDown( "a" ) and 1.0 or 0.0)
|
ddx = (love.keyboard.isScancodeDown( "d" ) and 1.0 or 0.0) - (love.keyboard.isScancodeDown( "a" ) and 1.0 or 0.0)
|
||||||
|
@ -39,17 +49,18 @@ local function OnKey()
|
||||||
end
|
end
|
||||||
|
|
||||||
local function Draw()
|
local function Draw()
|
||||||
local dt = love.timer.getTime() - t
|
|
||||||
local xf, yf = x + dt * dx, y + dt * dy
|
|
||||||
|
|
||||||
local w, h = love.graphics.getDimensions()
|
love.graphics.print( ddx, 0, 100 )
|
||||||
local xi, yi = transform:transformPoint( x, y )
|
love.graphics.print( ddy, 0, 110 )
|
||||||
xf, yf = transform:transformPoint( xf, yf )
|
|
||||||
|
|
||||||
love.graphics.setColor( 0, 0, 0, 1 )
|
local xp, yp = transform:transformPoint( oldState.x, oldState.y )
|
||||||
love.graphics.print( x, 0, 60 )
|
local xc, yc = transform:transformPoint( curState.x, curState.y )
|
||||||
love.graphics.print( y, 0, 80 )
|
local xn, yn = transform:transformPoint( newState.x, newState.y )
|
||||||
|
|
||||||
|
local dt = love.timer.getTime() - newState.t --Integrate forward for slightly smoother rendering.
|
||||||
|
local xf, yf = transform:transformPoint(
|
||||||
|
newState.x + dt * newState.dx,
|
||||||
|
newState.y + dt * newState.dy )
|
||||||
|
|
||||||
love.graphics.setCanvas( newBuffer )
|
love.graphics.setCanvas( newBuffer )
|
||||||
love.graphics.setColor( 1.0, 1.0, 1.0 , 0.99 ) -- White.
|
love.graphics.setColor( 1.0, 1.0, 1.0 , 0.99 ) -- White.
|
||||||
|
@ -57,8 +68,13 @@ local function Draw()
|
||||||
|
|
||||||
--Render latest segment in trail.
|
--Render latest segment in trail.
|
||||||
love.graphics.setColor( 245 / 255, 169 / 255, 184 / 255, 1.0 ) --Trans pink.
|
love.graphics.setColor( 245 / 255, 169 / 255, 184 / 255, 1.0 ) --Trans pink.
|
||||||
love.graphics.circle( "fill", xf, yf, 4.0 ) --TODO: replace with segments.
|
|
||||||
--love.graphics.line( xi, yi, xf, yf )
|
--love.graphics.line( xi, yi, xf, yf )
|
||||||
|
--Segment stuff:
|
||||||
|
love.graphics.setLineJoin( "bevel" )
|
||||||
|
love.graphics.setLineStyle( "smooth" )
|
||||||
|
love.graphics.setLineWidth( 8.0 )
|
||||||
|
love.graphics.line( xp, yp, xc, yc, xn, yn, xf, yf )
|
||||||
|
love.graphics.circle( "fill", xf, yf, 4.0 )
|
||||||
|
|
||||||
love.graphics.setCanvas( oldBuffer )
|
love.graphics.setCanvas( oldBuffer )
|
||||||
love.graphics.clear( 1.0, 1.0, 1.0, 0.0 )
|
love.graphics.clear( 1.0, 1.0, 1.0, 0.0 )
|
||||||
|
@ -66,9 +82,9 @@ local function Draw()
|
||||||
--Render circle directly to screen.
|
--Render circle directly to screen.
|
||||||
love.graphics.setCanvas()
|
love.graphics.setCanvas()
|
||||||
love.graphics.draw( newBuffer )
|
love.graphics.draw( newBuffer )
|
||||||
love.graphics.circle( "fill", xf, yf, 5.0 )
|
--love.graphics.circle( "fill", xf, yf, 5.0 )
|
||||||
love.graphics.setColor( 1, 1, 1, 1.0 ) --White.
|
love.graphics.setColor( 1, 1, 1, 1.0 ) --White.
|
||||||
love.graphics.circle( "line", xf, yf, 5.0 )
|
--love.graphics.circle( "line", xf, yf, 5.0 )
|
||||||
|
|
||||||
oldBuffer, newBuffer = newBuffer, oldBuffer
|
oldBuffer, newBuffer = newBuffer, oldBuffer
|
||||||
|
|
||||||
|
@ -88,13 +104,8 @@ local function Resize()
|
||||||
end
|
end
|
||||||
|
|
||||||
local function Reset()
|
local function Reset()
|
||||||
t = love.timer.getTime()
|
oldState, curState, newState = State(), State(), State()
|
||||||
x = 0
|
Resize()
|
||||||
y = 0
|
|
||||||
dx = 0
|
|
||||||
dy = 0
|
|
||||||
ddx = 0
|
|
||||||
ddy = 0
|
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
|
@ -110,4 +121,6 @@ return {
|
||||||
Impact = Impact,
|
Impact = Impact,
|
||||||
Reset = Reset,
|
Reset = Reset,
|
||||||
Resize = Resize,
|
Resize = Resize,
|
||||||
|
Current = Current,
|
||||||
|
Next = Next,
|
||||||
}
|
}
|
44
wave.lua
44
wave.lua
|
@ -1,7 +1,11 @@
|
||||||
--Render and simulate 1D wave equation.
|
--Render and simulate 1D wave equation.
|
||||||
local love = love
|
local love = love
|
||||||
|
local old, cur, new --States add beginning of last tick, current tick, and next tick respectively.
|
||||||
|
|
||||||
local N = 11
|
local N = 13
|
||||||
|
|
||||||
|
local function Current() return cur end
|
||||||
|
local function Next() return new end
|
||||||
|
|
||||||
--Calculate discrete fourier transform of radius function.
|
--Calculate discrete fourier transform of radius function.
|
||||||
local DFT
|
local DFT
|
||||||
|
@ -137,11 +141,6 @@ local function Wave( )
|
||||||
return setmetatable(t, mt)
|
return setmetatable(t, mt)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
local old = Wave() --State at beginning of tick.
|
|
||||||
local cur = Wave() --State at end of tick.
|
|
||||||
|
|
||||||
|
|
||||||
local function Draw()
|
local function Draw()
|
||||||
|
|
||||||
-- Blue circle.
|
-- Blue circle.
|
||||||
|
@ -159,6 +158,7 @@ local function Draw()
|
||||||
love.graphics.circle( "fill", cx, cy, 0.02 )
|
love.graphics.circle( "fill", cx, cy, 0.02 )
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
for k = 0.1, 1.0, 0.1 do
|
for k = 0.1, 1.0, 0.1 do
|
||||||
--Interpolant.
|
--Interpolant.
|
||||||
love.graphics.setColor( 1.0, 0, 0, 0.7 )
|
love.graphics.setColor( 1.0, 0, 0, 0.7 )
|
||||||
|
@ -182,6 +182,9 @@ local function Draw()
|
||||||
--love.graphics.circle( "fill", x, y, 0.01 )
|
--love.graphics.circle( "fill", x, y, 0.01 )
|
||||||
love.graphics.circle( "fill", th / math.pi - 1.0, r, 0.01)
|
love.graphics.circle( "fill", th / math.pi - 1.0, r, 0.01)
|
||||||
|
|
||||||
|
love.graphics.setColor( 1.0, 1.0, 1.0, 0.2 )
|
||||||
|
love.graphics.circle( "fill", 2.0 * ( i + k ) / N - 1.2, 0, 0.02 )
|
||||||
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -197,16 +200,6 @@ end
|
||||||
|
|
||||||
local function Update()
|
local function Update()
|
||||||
|
|
||||||
end
|
|
||||||
|
|
||||||
local function Integrate( step )
|
|
||||||
local t = love.timer.getTime()
|
|
||||||
for i = 1, N do
|
|
||||||
cur.radii[i] = old.radii[i]
|
|
||||||
end
|
|
||||||
|
|
||||||
cur:DFT( )
|
|
||||||
|
|
||||||
--Deep copy of current state to old state.
|
--Deep copy of current state to old state.
|
||||||
for name, t in pairs( cur ) do
|
for name, t in pairs( cur ) do
|
||||||
for i = 1, N do
|
for i = 1, N do
|
||||||
|
@ -214,6 +207,22 @@ local function Integrate( step )
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
--Deep copy of new state to current state.
|
||||||
|
for name, t in pairs( new ) do
|
||||||
|
for i = 1, N do
|
||||||
|
cur[name][i] = t[i]
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
local function Integrate( step )
|
||||||
|
local t = love.timer.getTime()
|
||||||
|
for i = 1, N do
|
||||||
|
new.radii[i] = 0.05 * math.cos( math.sin( t * 0.05 + i ) )
|
||||||
|
end
|
||||||
|
|
||||||
|
cur:DFT( )
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
local function DetectCollision( px, py, vpx, vpy )
|
local function DetectCollision( px, py, vpx, vpy )
|
||||||
|
@ -223,6 +232,7 @@ end
|
||||||
local function Reset()
|
local function Reset()
|
||||||
old = Wave()
|
old = Wave()
|
||||||
cur = Wave()
|
cur = Wave()
|
||||||
|
new = Wave()
|
||||||
end
|
end
|
||||||
|
|
||||||
Reset()
|
Reset()
|
||||||
|
@ -234,4 +244,6 @@ return {
|
||||||
OnImpact = OnImpact,
|
OnImpact = OnImpact,
|
||||||
DetectCollision = DetectCollision,
|
DetectCollision = DetectCollision,
|
||||||
Draw = Draw,
|
Draw = Draw,
|
||||||
|
Current = Current,
|
||||||
|
Next = Next,
|
||||||
}
|
}
|
Loading…
Reference in New Issue