Advertisement
Tag365

voxelPolygonizer.lua

Feb 22nd, 2016
154
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Lua 21.12 KB | None | 0 0
  1. local bit32 = require("bit32"--[[
  2.    Linearly interpolate the position where an isosurface cuts
  3.    an edge between two vertices, each with their own scalar value
  4. ]]
  5. local VertexInterp = function(isolevel,p1,p2,valp1,valp2)
  6.     --double isolevel;
  7.     --XYZ p1,p2;
  8.     --double valp1,valp2;
  9.     local mu --double mu;
  10.     local p = {x = 0, y = 0, z = 0}--XYZ p;
  11.  
  12.     if (abs(isolevel-valp1) < 0.00001) then
  13.         return p1
  14.     end
  15.     if (abs(isolevel-valp2) < 0.00001) then
  16.         return p2
  17.     end
  18.     if (abs(valp1-valp2) < 0.00001) then
  19.         return p1
  20.     end
  21.     mu = (isolevel - valp1) / (valp2 - valp1);
  22.     p.x = p1.x + mu * (p2.x - p1.x);
  23.     p.y = p1.y + mu * (p2.y - p1.y);
  24.     p.z = p1.z + mu * (p2.z - p1.z);
  25.  
  26.     return p
  27. end
  28.  
  29. --[[
  30.     Given a grid cell and an isolevel, calculate the triangular
  31.     facets required to represent the isosurface through the cell.
  32.     Return the number of triangular facets, the array "triangles"
  33.     will be loaded up with the vertices at most 5 triangular facets.
  34.     0 will be returned if the grid cell is either totally above
  35.     of totally below the isolevel.
  36. ]]
  37. -- Gridcell, number, triangle
  38. function voxelPolygonizer.Polygonise(grid, isolevel, triangles)
  39.     local i, ntriang
  40.     local cubeindex = 0
  41.     local vertlist = {}
  42.  
  43.     --[[
  44.         Determine the index into the edge table which
  45.         tells us which vertices are inside of the surface
  46.     ]]
  47.     if (grid.val[0] < isolevel) then cubeindex = bor(cubeindex, 1) end
  48.     if (grid.val[1] < isolevel) then cubeindex = bor(cubeindex, 2) end
  49.     if (grid.val[2] < isolevel) then cubeindex = bor(cubeindex, 4) end
  50.     if (grid.val[3] < isolevel) then cubeindex = bor(cubeindex, 8) end
  51.     if (grid.val[4] < isolevel) then cubeindex = bor(cubeindex, 16) end
  52.     if (grid.val[5] < isolevel) then cubeindex = bor(cubeindex, 32) end
  53.     if (grid.val[6] < isolevel) then cubeindex = bor(cubeindex, 64) end
  54.     if (grid.val[7] < isolevel) then cubeindex = bor(cubeindex, 128) end
  55.    
  56.     cubeindex = cubeindex + 1
  57.    
  58.     -- Cube is entirely in/out of the surface
  59.     if (edgeTable[cubeindex] == 0) then
  60.         return 0
  61.     end
  62.  
  63.     -- Find the vertices where the surface intersects the cube
  64.     if (band(edgeTable[cubeindex], 1) > 0) then
  65.         vertlist[0] = VertexInterp(isolevel,grid.p[0],grid.p[1],grid.val[0],grid.val[1]);
  66.     end
  67.     if (band(edgeTable[cubeindex],  2) > 0) then
  68.         vertlist[1] = VertexInterp(isolevel,grid.p[1],grid.p[2],grid.val[1],grid.val[2]);
  69.     end
  70.     if (band(edgeTable[cubeindex],  4) > 0) then
  71.         vertlist[2] = VertexInterp(isolevel,grid.p[2],grid.p[3],grid.val[2],grid.val[3]);
  72.     end
  73.     if (band(edgeTable[cubeindex],  8) > 0) then
  74.         vertlist[3] = VertexInterp(isolevel,grid.p[3],grid.p[0],grid.val[3],grid.val[0]);
  75.     end
  76.     if (band(edgeTable[cubeindex],  16) > 0) then
  77.         vertlist[4] = VertexInterp(isolevel,grid.p[4],grid.p[5],grid.val[4],grid.val[5]);
  78.     end
  79.     if (band(edgeTable[cubeindex],  32) > 0) then
  80.         vertlist[5] = VertexInterp(isolevel,grid.p[5],grid.p[6],grid.val[5],grid.val[6]);
  81.     end
  82.     if (band(edgeTable[cubeindex],  64) > 0) then
  83.         vertlist[6] = VertexInterp(isolevel,grid.p[6],grid.p[7],grid.val[6],grid.val[7]);
  84.     end
  85.     if (band(edgeTable[cubeindex],  128) > 0) then
  86.         vertlist[7] = VertexInterp(isolevel,grid.p[7],grid.p[4],grid.val[7],grid.val[4]);
  87.     end
  88.     if (band(edgeTable[cubeindex],  256) > 0) then
  89.         vertlist[8] = VertexInterp(isolevel,grid.p[0],grid.p[4],grid.val[0],grid.val[4]);
  90.     end
  91.     if (band(edgeTable[cubeindex],  512) > 0) then
  92.         vertlist[9] = VertexInterp(isolevel,grid.p[1],grid.p[5],grid.val[1],grid.val[5]);
  93.     end
  94.     if (band(edgeTable[cubeindex],  1024) > 0) then
  95.         vertlist[10] = VertexInterp(isolevel,grid.p[2],grid.p[6],grid.val[2],grid.val[6]);
  96.     end
  97.     if (band(edgeTable[cubeindex],  2048) > 0) then
  98.         vertlist[11] = VertexInterp(isolevel,grid.p[3],grid.p[7],grid.val[3],grid.val[7]);
  99.     end
  100.  
  101.     -- Create the triangle
  102.     ntriang = 0
  103.     i = 0
  104.     --for (i=0, triTable[cubeindex][i]!=-1, i+=3) do
  105.     while triTable[cubeindex][i] ~= -1 do
  106.         triangles[ntriang] = {p = {}}
  107.         triangles[ntriang].p[0] = vertlist[triTable[cubeindex][i+1]];
  108.         triangles[ntriang].p[1] = vertlist[triTable[cubeindex][i+2]];
  109.         triangles[ntriang].p[2] = vertlist[triTable[cubeindex][i+3]];
  110.         ntriang = ntriang + 1;
  111.         i = i + 3
  112.         if i > 90 then break end
  113.     end
  114.    
  115.     return ntriang
  116. end
  117.  
  118. return voxelPolygonizer
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement