I am trying to get this working with Codea:
https://github.com/vincent23/love2d-experiments/blob/master/metaball/main.lua
I have recorded a video but the image is flipped, dont know why exactly xD
Here is the Main.lua for Codea
balls = {}
v = {}
x = 0
y = 0
radius = 66
width = WIDTH-radius
height = HEIGHT-radius
paused = false
time = 0
strobo = false
m = nil
--[[
original source code , love2d version:
https://github.com/vincent23/love2d-experiments/blob/master/metaball/main.lua
]]--
displayMode(STANDARD)
function setup()
parameter.number("schwelle",0.002, 2.0, 0.002)
parameter.boolean("drawMesh",false)
local i = 0
for i=1,40 do
balls[i] = {math.random(0,width), math.random(0,height)}
local v_ges = math.random(200,400)
local v_x = math.random(0,v_ges)
local v_y = math.sqrt(math.pow(v_ges,2) - math.pow(v_x,2))
v[i] = {v_x, v_y}
end
m = mesh()
m.texture = "Cargo Bot:Codea Icon"
m.shader = shader("Documents:MetaBall")
rIdx = m:addRect(0, 0, 0, 0)
m:setRectColor(i, 127,0,0)
m:setRect(rIdx, WIDTH/2, HEIGHT/2, WIDTH, HEIGHT)
m.shader.width = width
m.shader.height = height
m.shader.time = time
m.shader.schwelle = schwelle
end
function draw()
background(0)
strokeWidth(2)
fill(17, 120, 223, 255)
stroke(17, 120, 223, 255)
local dt = DeltaTime
time = time + dt
if paused then
return
end
for i=1,#balls do
for j=1,#balls do
if i ~= j then
local left, right
local bottom, top
if balls[i][1] < balls[j][1] then
left = i
right = j
else
left = j
right = i
end
if balls[i][2] < balls[j][2] then
bottom = i
top = j
else
bottom = j
top = i
end
local x = balls[right][1]-balls[left][1]
local y = balls[right][2]-balls[left][2]
local r = math.sqrt(math.pow(x,2) + math.pow(y,2))
local f = 200000/math.pow(r,2) * dt
local fx = x/r*f
local fy = y/r*f
balls[left][1] = balls[left][1] - fx
balls[right][1] = balls[right][1] + fx
balls[left][2] = balls[left][2] - fy
balls[right][2] = balls[right][2] + fy
end
end
end
for i=1,#balls do
balls[i][1] = balls[i][1] + v[i][1] * dt
if (balls[i][1] < 10 and v[i][1] < 0) or (balls[i][1] >= width -10 and v[i][1] > 0) then
v[i][1] = v[i][1] * (-1)
end
balls[i][2] = balls[i][2] + v[i][2] * dt
if (balls[i][2] < 10 and v[i][2] < 0) or (balls[i][2] >= height-10 and v[i][2] > 0) then
v[i][2] = v[i][2] * (-1)
end
if not drawMesh then
ellipse(balls[i][1],balls[i][2],radius)
end
end
if drawMesh then
--local cw,ch = spriteSize(m.texture)
--m:setRect(rIdx, WIDTH/2, HEIGHT/2, cw, ch) -- uncomment if texture size changes
-- Configure out custom uniforms for the shader
if strobo then
m.shader.time = time --ElapsedTime
end
--m.shader.schwelle = schwelle
--m.shader.width = cw
--m.shader.height = ch
m.shader.balls = balls
-- Draw the mesh
m:draw()
end
end
function touched(touch)
if touch.state == BEGAN then
paused = not paused
print("paused:",paused)
end
end
This is the vertex program for the metaballs shader:
//
// A metaballs shader
//
//This is the current model * view * projection matrix
// Codea sets it automatically
uniform mat4 modelViewProjection;
uniform float width;
uniform float height;
uniform float schwelle;
uniform vec2 balls[40];
uniform float time;
//This is the current mesh vertex position, color and tex coord
// Set automatically
attribute vec4 position;
attribute vec4 color;
attribute vec2 texCoord;
//This is an output variable that will be passed to the fragment shader
varying lowp vec4 vColor;
varying highp vec2 vTexCoord;
varying highp vec4 bColor;
float metaball(vec2 center, vec2 point) {
vec2 v = point-center;
return 1.0/dot(v, v);
}
vec4 effect(
vec4 color, vec2 tex_c,vec2 coord
) {
float val = 0.0;
for (int i =0; i<40; i++) {
val = val + metaball(balls[i],coord);
}
vec4 bar;
if (val < schwelle) {
val = val / schwelle;
bar = vec4(
0.8*(1.0-coord.x/width),
0.8*(1.0-coord.y/height),
0.3*val,
1.0
);
}
else {
bar = vec4(
0.8*coord.x/width,
0.8*coord.y/height,
0.0,1.0
);
}
float foo = mod(time,1.0);
if (foo < 0.1) {
return bar + vec4(vec3(foo*3.14*50.0), 1.0);
}
return bar;
}
void main()
{
//Pass the mesh color to the fragment shader
vColor = color;
vTexCoord = vec2(texCoord.x, 1.0 - texCoord.y);
//Pass the balls effect color to the fragment
bColor = effect(color, texCoord, vTexCoord);
//Multiply the vertex position by our combined transform
gl_Position = modelViewProjection * position;
}
and here it is the fragment program:
//
// A metaballs fragment shader
//
//This represents the current texture on the mesh
uniform lowp sampler2D texture;
//The interpolated vertex color for this fragment
varying lowp vec4 vColor;
//The interpolated texture coordinate for this fragment
varying highp vec2 vTexCoord;
//balls effect
varying highp vec4 bColor;
void main()
{
//Sample the texture at the interpolated coordinate
lowp vec4 col = texture2D( texture, vTexCoord );
//Set the output color to the texture color
gl_FragColor = bColor+col;
}
Hope you smart people know How to fix this