jig487

JIG3D_AP_API_v1.0

Sep 30th, 2021 (edited)
315
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Lua 6.77 KB | None | 0 0
  1. -- AR tools API
  2.  
  3. local function interpolate(p1x,p1y,p2x,p2y,x)
  4.     return p1y + ( ((p2y-p1y)/(p2x-p1x)) * (x-p1x) )
  5. end
  6.  
  7. --Draws a line from x1,y1 to x2,y2 with given color, using name of wrapped AR controller
  8. --Draws a line from x1,y1 to x2,y2 with given color, using name of wrapped AR controller
  9. local function drawLineAR(arController,x1,y1,x2,y2,color,zBuffer)
  10.     color = 0x000000 --Overriding color to black. Comment out to use custom colors
  11.     local dx = x2 - x1
  12.     local dy = y2 - y1
  13.     --local zBufOffset = y*sx
  14.     local length = math.floor(math.sqrt((dx^2)+(dy^2)))
  15.  
  16.     for i = 1, length do
  17.         local nextY = y1 + dy * (i / length)
  18.         local nextX = x1 + dx * (i / length)
  19.  
  20.         --[[if nextY > 0 and nextX > 0 then
  21.             local zI = zBufOffset + x
  22.             local newZ = interpolate(xStart,zStart,xEnd,zEnd,x)
  23.  
  24.             if newZ < zBuffer[ zI ] then]]
  25.                 --zBuffer[ zI ] = newZ
  26.                 arController.horizontalLine(nextX, nextX, nextY, color)
  27.             --end
  28.         --end
  29.     end
  30. end
  31.  
  32. --Draws an object with an indexList which points to a list x/y points, using name of wrapped AR controller
  33. local function drawWireObj(arController,vL) --vL == vertice list. cL == color list
  34.     local cL = vL.colorList
  35.     for i = 1, #vL, 3 do --Draws a whole triangle per loop
  36.         local i1,i2 = i+1, i+2
  37.         local col = cL[(i+2)/3]
  38.         drawLineAR(arController, vL[i].x,  vL[i].y,  vL[i1].x, vL[i1].y, col) --vert 1 to 2
  39.         drawLineAR(arController, vL[i1].x, vL[i1].y, vL[i2].x, vL[i2].y, col) --vert 2 to 3
  40.         drawLineAR(arController, vL[i2].x, vL[i2].y, vL[i].x,  vL[i].y, col) --vert 3 to 1
  41.     end
  42. end
  43.  
  44. --Basically a line function with cutoffs for anything < 0.
  45. local function drawFlatTriangle(arController,px1,px2,pz1,pz2,y,color,zBuffer)
  46.     local zBufOffset = y*zBuffer.size.x
  47.  
  48.     local xStart = math.ceil(px1 - 0.5)
  49.     local xEnd =   math.ceil(px2 - 0.5)
  50.  
  51.     local zStart = math.ceil(pz1 - 0.5)
  52.     local zEnd = math.ceil(pz2 - 0.5)
  53.  
  54.     if y > 0 and xEnd > 0 then
  55.         if xStart < 0 then
  56.             xStart = 0
  57.         end
  58.  
  59.         for x = xStart, xEnd do
  60.             local zI = zBufOffset + x
  61.             local newZ = interpolate(xStart,zStart,xEnd,zEnd,x)
  62.  
  63.             if newZ < zBuffer[ zI ] then
  64.                 zBuffer[ zI ] = newZ
  65.                 arController.horizontalLine(x, x, y, color)
  66.             end
  67.         end
  68.     end
  69. end
  70.  
  71. --Both draw flat top and bottom draw an entire line at a time instead of each pixel individually b/c performance. Will add individual pixel support later.
  72. local function drawFlatTopTriangle( arController,vec1,vec2,vec3,color,zBuffer )
  73.     --Calculate slopes in screen space
  74.     --Run over rise so we don't get infinite slopes
  75.     local m1 = (vec3.x - vec1.x) / (vec3.y - vec1.y)
  76.     local m2 = (vec3.x - vec2.x) / (vec3.y - vec2.y)
  77.  
  78.     local zm1 = (vec2.z - vec1.z) / (vec2.y - vec1.y) --left line
  79.     local zm2 = (vec3.z - vec1.z) / (vec3.y - vec1.y) --right line
  80.  
  81.     --Calculate start and end scanlines
  82.     local yStart = math.ceil(vec1.y - 0.5)
  83.     local yEnd =   math.ceil(vec3.y - 0.5)-1 --the scanline AFTER the last line drawn, which is why it's offset by -1
  84.  
  85.     for y = yStart, yEnd do
  86.         --calculate start and end x's
  87.         --Add 0.5 because we're calculating based on pixel centers
  88.         local px1 = m1 * (y + 0.5 - vec1.y) + vec1.x
  89.         local px2 = m2 * (y + 0.5 - vec2.y) + vec2.x
  90.  
  91.         local pz1 = zm1 * (y + 0.5 - vec1.y) + vec1.z
  92.         local pz2 = zm2 * (y + 0.5 - vec1.y) + vec1.z
  93.  
  94.         drawFlatTriangle( arController,px1,px2,pz1,pz2,y,color,zBuffer )
  95.     end
  96. end
  97.  
  98. local function drawFlatBottomTriangle( arController,vec1,vec2,vec3,color,zBuffer )
  99.     --Calculate slopes in screen space
  100.     local m1 = (vec2.x - vec1.x) / (vec2.y - vec1.y)
  101.     local m2 = (vec3.x - vec1.x) / (vec3.y - vec1.y)
  102.  
  103.     local zm1 = (vec2.z - vec1.z) / (vec2.y - vec1.y) --left line
  104.     local zm2 = (vec3.z - vec1.z) / (vec3.y - vec1.y) --right line
  105.  
  106.     --Calculate start and end scanlines
  107.     local yStart = math.ceil(vec1.y-0.5)
  108.     local yEnd =   math.ceil(vec3.y-0.5)-1 --the scanline AFTER the last line drawn, which is why we need to subtract 1 otherwise we get visual bugs
  109.  
  110.     for y = yStart, yEnd do
  111.  
  112.         --calculate start and end points (x/z coords)
  113.         --Add 0.5 because we're calculating based on pixel centers
  114.         local px1 = m1 * (y + 0.5 - vec1.y) + vec1.x
  115.         local px2 = m2 * (y + 0.5 - vec1.y) + vec1.x
  116.  
  117.         local pz1 = zm1 * (y + 0.5 - vec1.y) + vec1.z
  118.         local pz2 = zm2 * (y + 0.5 - vec1.y) + vec1.z
  119.  
  120.         drawFlatTriangle( arController,px1,px2,pz1,pz2,y,color,zBuffer )
  121.     end
  122. end
  123.  
  124. --Draws a solid triangle from 3 vectors
  125. local function drawSolidTriangle( arController,vec1,vec2,vec3,color,zBuffer )
  126.    
  127.     --using pointers so we can swap (for sorting purposes) probably don't need this b/c lua? idk
  128.     local pv1 = vec1
  129.     local pv2 = vec2
  130.     local pv3 = vec3
  131.  
  132.     --Sort vertices by y
  133.     if pv2.y < pv1.y then pv1,pv2 = pv2,pv1 end
  134.     if pv3.y < pv2.y then pv2,pv3 = pv3,pv2 end
  135.     if pv2.y < pv1.y then pv1,pv2 = pv2,pv1 end
  136.  
  137.     if pv1.y == pv2.y then --Natural flat top
  138.         --Sort top vertice by x
  139.         if pv2.x < pv1.x then pv1,pv2 = pv2,pv1 end
  140.         drawFlatTopTriangle(arController,pv1,pv2,pv3,color,zBuffer )
  141.  
  142.     elseif pv2.y == pv3.y then --Natural flat bottom
  143.         --Sort bottom vertice by x
  144.         if pv3.x < pv2.x then pv3,pv2 = pv2,pv3 end
  145.         drawFlatBottomTriangle(arController,pv1,pv2,pv3,color,zBuffer )
  146.  
  147.     else --General triangle
  148.         local alphaSplit = (pv2.y-pv1.y)/(pv3.y-pv1.y)
  149.         local vi ={
  150.             x = pv1.x + ((pv3.x - pv1.x) * alphaSplit),      
  151.             y = pv1.y + ((pv3.y - pv1.y) * alphaSplit),
  152.             z = pv1.z + ((pv3.z - pv1.z) * alphaSplit) }
  153.         if pv2.x < vi.x then --Major right
  154.             drawFlatBottomTriangle(arController,pv1,pv2,vi,color,zBuffer)
  155.             drawFlatTopTriangle(arController,pv2,vi,pv3,color,zBuffer)
  156.         else --Major left
  157.             drawFlatBottomTriangle(arController,pv1,vi,pv2,color,zBuffer)
  158.             drawFlatTopTriangle(arController,vi,pv2,pv3,color,zBuffer)
  159.         end
  160.     end
  161. end
  162.  
  163. --Draw an entire object one triangle at a time
  164. --Converts points from the 1D table to vectors b/c I'm lazy
  165. local function drawSolidObj( arController, iL, zBuffer) --iL == index List. vL == vertex list. cL == color list
  166.     local cL = iL.colorList
  167.         --OPTIMIZATION here?. Probably should convert to 1D at least
  168.     for i = 1, #iL, 3 do --Try to draw a triangle
  169.         drawSolidTriangle( arController, iL[i], iL[i+1], iL[i+2], cL[(i+2)/3], zBuffer )
  170.     end
  171. end
  172.  
  173. --Expose functions
  174. return
  175. {
  176.     drawWireObj = drawWireObj,
  177.     drawSolidObj = drawSolidObj,
  178. }
Add Comment
Please, Sign In to add comment