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…

yes .
http://twolivesleft.com/Codea/Talk/discussion/2266/meta-balls-shader/p1

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
   local radian = math.atan2(y,x)
   local angle = radian*180/math.pi
   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 = {}
    whitecirc = readImage("Documents:whitecircle")
    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

Add:

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 :wink:

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.

http://www.youtube.com/watch?v=qjGgmdqc1fk&feature=share&list=UUTq1JODMHxQar5OeFGBakpg

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.

https://www.youtube.com/watch?v=ThmMEZIzdIo

Maybe not

Hi all, thanks for your answers.

I was just playing around with the posibilities of Codea’s (my favorite toy :smiley: ) physics engine.
I wanted to simulate (from the engineering point of view, instead of from the “video-game” point of view) a 2-D flow around a solid (e. g. a cylinder). I take for granted that even a simplificaction of the Navier- Stokes equations (the equations governing any kind of flow) is impossible to resolve with Codea (yes, I’m a bit naive :stuck_out_tongue: ), but just for fun I wanted to give a try.
I’ll post in a moment a video and my code… :-B

Thank you anyway…

My favorite App…

…is…

Codea!