# Metaball, viscosity

Hi,
has somebody tried already a metaball simulation with Codea?
What about “simulating” fluid viscosity? Have you done this tricking with restitution, and so on? :-?
Just curious…

Nice!

For a “non-game-application”, it would be interesting if your “fluid simulation” could work for more than 200 tiny drops :-?

But I think, that is too much to ask (for the moment) :((

Greetings and nice work!

I made a comment on that thread showing my method, which can get 10 FPS at 1000 Metaballs. 500-600 gets around 45 FPS, I believe.

Yes, nice work!

But I really meant including “real” physics for every “ball”.

Greetings!

Yeah, that slow the process, you have to try with different parameters for physics cicles and bodies…

Physics will slow it down, not because of the metaball shader, but because it has to calculate all the movements and collisions, and a lot of other stuff.

Yeah, that’s right, unfortunately :((

This is metaballs effect without a shader:

``````

--# specfunc

function angleOfPoint( pt )
local x, y = pt.x, pt.y
if angle < 0 then angle = 360 + angle elseif angle > 360 then angle = 0 + (angle-360) end
return angle
end

--# Main
-- metaballs

-- Use this function to perform your initial setup
function setup()
floorv = {vec2(0,0),vec2(0,HEIGHT),vec2(WIDTH,HEIGHT),vec2(WIDTH,0)}
floor = physics.body(CHAIN,true,unpack(floorv))
btbl = {}
for i=1,20 do
btbl[i] = CreateBall(vec2(math.random(WIDTH),math.random(HEIGHT)),10)
end
end

function touched(t)
for k,v in pairs(btbl) do
v:touched(t)
end
end

-- This function gets called once every frame
function draw()
-- This sets a dark background color
background(40, 40, 50)
physics.gravity(Gravity.x*500,Gravity.y*500)
smooth()
text(1/DeltaTime,100,100)
for k,v in pairs(btbl) do
v:draw()
end
end

--# CreateBall
CreateBall = class()

function CreateBall:init(pos,size)
self.ball = physics.body(CIRCLE,size)
self.ball.position = pos
self.ball.friction = 0.05
self.ball.restitution = 0.25
self.pos = pos
self.size = size
self.id = nil
self.holding = nil
end

function CreateBall:getPos()
return self.ball.position
end

function CreateBall:getBalls(tbl)
local ntbl = {}
local index = 0
local bp = self.ball.position
for k,v in pairs(tbl) do
local vp = v:getPos()
if vp:dist(bp) < self.size*5 and bp ~= vp and index < 7 then
index = index + 1
ntbl[index] = v
end
end
return ntbl
end

function CreateBall:touched(t)

local pos = self.ball.position
local bs = self.ball
local tpos = vec2(t.x,t.y)
if pos:dist(tpos) < 200 then
self.ball:applyForce((tpos-pos)*(bs.mass)*4-bs.linearVelocity/10)
end

end

function CreateBall:draw()
local bs = self.ball
local sz = self.size
sprite(whitecirc,bs.x,bs.y,sz*2,sz*2)
for k,v in pairs(self:getBalls(btbl)) do
local bp = bs.position
local vp = v:getPos()
local pos = (vp-bp)
local mid = (vp+bp)/2
local mlt = ((sz*2)/10)/40
for i=1,3 do
local size = ((sz*2)*(1-(i/6)))
size = size*(((sz*5)-pos:len())/(sz/2))
size = math.min(size,sz*3)
sprite(whitecirc,bp.x+pos.x*(i/6),bp.y
+pos.y*(i/6),size,size)
end
end
if self.holding then
self.ball.linearVelocity = vec2()
end
end
``````

Whitecirc texture - https://www.dropbox.com/s/5nw05r1zrc382wq/whitecircle%402x.png

``````bs:applyForce(pos/20)
``````

In the for loop in CreateBall:draw() for a viscous effect

Hi @Luatee, nice simulation!
I’m just checking the droping of FPS with the rise of the ball’s number and finding that a “quasi real” flow simulation might not be feasible (for the moment) with Codea: for example , for 50 balls, the FPS drops up to 67%. :((

But yes, I’m may be asking too much now

Greetings!

If you use shaders then you can get up to 100 balls quite easily.
Thanks aswell, if you’re trying to create water or a viscous fluid you can do it using juaxix’s metaballs code using the same idea with the applyForce to the closest bodies

@quezadav What are you trying to do? I had a few goes at fluid simulation a while back. I found that implementing the full Navier-Stokes system was too heavy on the FPS (and I couldn’t get it to work perfectly either). But a steady-state irrotational, incompressible flow works well.

If you just want something flowing that looks kind of watery, I found that overlaying a tint on noise gave a nice flowing effect. The video below is the noise demo project with one line added - and different colours for water, cloud, sand… It starts with just the ugly noise, then adds the tint to show the effect. The numbers onscreen are the tint colour.

Maybe not