Skip to content

Instantly share code, notes, and snippets.

@tnlogy
Created February 18, 2014 15:54
Show Gist options
  • Select an option

  • Save tnlogy/9073640 to your computer and use it in GitHub Desktop.

Select an option

Save tnlogy/9073640 to your computer and use it in GitHub Desktop.
--# Main
-- March
function setup()
local function sp(p)
return p:len() * p:dist(vec3(5,3,0))
end
local st = os.clock()
local vs = volume(sp, 9, .5, 6)
print(os.clock() - st)
m = mesh()
m.vertices = vs
end
function draw()
background(40, 40, 50)
perspective(45)
camera(0,0,50,0,0,0)
rotate(ElapsedTime*50, 1,0,0)
m:draw()
end
--# Marching
-- Marching tetrahedron algorithm based on
-- http://paulbourke.net/geometry/polygonise/
local EPSILON = .00001
local function ip(iso, p1, p2, v1, v2)
if math.abs(iso-v1) < EPSILON then return p1 end
if math.abs(iso-v2) < EPSILON then return p2 end
local mu = (iso-v1) / (v2-v1)
return p1 + (p2-p1) * mu
end
function volume(fn, iso, step, size)
local xd,yd,zd = vec3(step,0,0),vec3(0,step,0),vec3(0,0,step)
local vs = {}
for z=-size,size,step do
for y=-size,size,step do
for x=-size,size,step do
local p = vec3(x,y,z)
local p1, p4 = p+xd, p+yd
local ps = {p, p1, p1+zd, p+zd,
p4, p4+xd, p4+xd+zd, p4+zd}
local fns = {
fn(ps[1]), fn(ps[2]), fn(ps[3]), fn(ps[4]),
fn(ps[5]), fn(ps[6]), fn(ps[7]), fn(ps[8])
}
polygonise(ps, fns, iso, 1,3,4,8, vs)
polygonise(ps, fns, iso, 1,3,7,8, vs)
polygonise(ps, fns, iso, 1,5,7,8, vs)
polygonise(ps, fns, iso, 1,7,2,3, vs)
polygonise(ps, fns, iso, 1,7,2,5, vs)
polygonise(ps, fns, iso, 6,7,2,5, vs)
end
end
end
return vs
end
function polygonise(ps, fns, iso, i0,i1,i2,i3, vs)
local p0,p1,p2,p3 = ps[i0],ps[i1],ps[i2],ps[i3]
local v0,v1,v2,v3 = fns[i0],fns[i1],fns[i2],fns[i3]
local m = 0
if v0 < iso then m = m + 1 end
if v1 < iso then m = m + 2 end
if v2 < iso then m = m + 4 end
if v3 < iso then m = m + 8 end
if m == 0xe or m == 1 then
table.insert(vs, ip(iso,p0,p1,v0,v1))
table.insert(vs, ip(iso,p0,p2,v0,v2))
table.insert(vs, ip(iso,p0,p3,v0,v3))
elseif m == 0xd or m == 2 then
table.insert(vs, ip(iso,p1,p0,v1,v0))
table.insert(vs, ip(iso,p1,p3,v1,v3))
table.insert(vs, ip(iso,p1,p2,v1,v2))
elseif m == 0xc or m == 3 then
local r1,r2 = ip(iso,p0,p2,v0,v2),ip(iso,p1,p3,v1,v3)
table.insert(vs, ip(iso,p0,p3,v0,v3))
table.insert(vs, r1)
table.insert(vs, r2)
table.insert(vs, r2)
table.insert(vs, ip(iso,p1,p2,v1,v2))
table.insert(vs, r1)
elseif m == 0xb or m == 4 then
table.insert(vs, ip(iso,p2,p0,v2,v0))
table.insert(vs, ip(iso,p2,p1,v2,v1))
table.insert(vs, ip(iso,p2,p3,v2,v3))
elseif m == 0xa or m == 5 then
local r0,r1 = ip(iso,p0,p1,v0,v1),ip(iso,p2,p3,v2,v3)
table.insert(vs, r0)
table.insert(vs, r1)
table.insert(vs, ip(iso,p0,p3,v0,v3))
table.insert(vs, r0)
table.insert(vs, ip(iso,p1,p2,v1,v2))
table.insert(vs, r1)
elseif m == 9 or m == 6 then
local r0,r2 = ip(iso,p0,p1,v0,v1),ip(iso,p2,p3,v2,v3)
table.insert(vs, r0)
table.insert(vs, ip(iso,p1,p3,v1,v3))
table.insert(vs, r2)
table.insert(vs, r0)
table.insert(vs, ip(iso,p0,p2,v0,v2))
table.insert(vs, r2)
elseif m == 7 or m == 8 then
table.insert(vs, ip(iso,p3,p0,v3,v0))
table.insert(vs, ip(iso,p3,p2,v3,v2))
table.insert(vs, ip(iso,p3,p1,v3,v1))
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment