Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- -- AR tools API
- --### Wireframe drawing functions ###
- --Draws a line from x1,y1 to x2,y2 with given color, using name of wrapped AR controller
- local function drawLineAR(arController,x1,y1,x2,y2,color)
- color = 0x000000 --Overriding color to black. Comment out to use custom colors
- local dx = x2 - x1 --Distance between x's
- local dy = y2 - y1 --Distance between y's
- local dh = math.sqrt((dx*dx)+(dy*dy))
- for i = 1, dh do
- local nextY = y1 + dy * (i / dh)
- local nextX = x1 + dx * (i / dh)
- if nextY > 0 and nextX > 0 then
- arController.horizontalLine(nextX, nextX, nextY, color)
- end
- end
- end
- --Draws an object with an indexList which points to a list x/y points, using name of wrapped AR controller
- --Wireframe is currently about 2x slower than drawing solid objects
- local function drawWireObj(arController,vL,cL) --vL == vertice list. cL == color list
- local vList = {}
- for i = 1, #vL, 3 do --Draws a whole triangle per loop
- local i1,i2 = i+1, i+2
- local col = cL[(i+2)/3]
- drawLineAR(arController, vL[i].x, vL[i].y, vL[i1].x, vL[i1].y, col) --vert 1 to 2
- drawLineAR(arController, vL[i1].x, vL[i1].y, vL[i2].x, vL[i2].y, col) --vert 2 to 3
- drawLineAR(arController, vL[i2].x, vL[i2].y, vL[i].x, vL[i].y, col) --vert 3 to 1
- end
- end
- --### Solid object drawing functions ###
- local function drawFlatTriangle(arController,px1,px2,x,y,color)
- local xStart = math.ceil(px1 - 0.5)
- local xEnd = math.ceil(px2 - 0.5)
- --To change to individual pixel plotting instead of whole lines, uncomment this `for` loop and replace `(xStart, xEnd, y, color)` with `( x, x, y, color )` in the horizontalLine() function
- for x = xStart, xEnd do
- if y > 0 and x > 0 then
- arController.horizontalLine(x, x, y, color) --Draws a horizontal line. have xStart and xEnd == to the same x val to plot just one pixel
- --elseif y > 0 and xEnd > 0 then
- -- arController.horizontalLine(1, xEnd, y, color)
- end
- end
- end
- --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.
- local function drawFlatTopTriangle( arController,vec1,vec2,vec3,color )
- --Calculate slopes in screen space
- --Run over rise so we don't get infinite slopes
- local m1 = (vec3.x - vec1.x) / (vec3.y - vec1.y)
- local m2 = (vec3.x - vec2.x) / (vec3.y - vec2.y)
- --Calculate start and end scanlines
- local yStart = math.ceil(vec1.y - 0.5)
- local yEnd = math.ceil(vec3.y - 0.5)-1 --the scanline AFTER the last line drawn
- for y = yStart, yEnd do
- --calculate start and end x's
- --Add 0.5 because we're calculating based on pixel centers
- local px1 = m1 * (y + 0.5 - vec1.y) + vec1.x
- local px2 = m2 * (y + 0.5 - vec2.y) + vec2.x
- drawFlatTriangle(arController,px1,px2,y,color)
- end
- end
- local function drawFlatBottomTriangle( arController,vec1,vec2,vec3,color )
- --Calculate slopes in screen space
- local m1 = (vec2.x - vec1.x) / (vec2.y - vec1.y)
- local m2 = (vec3.x - vec1.x) / (vec3.y - vec1.y)
- --Calculate start and end scanlines
- local yStart = math.ceil(vec1.y-0.5)
- 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
- for y = yStart, yEnd do
- --calculate start and end points (x coords)
- --Add 0.5 because we're calculating based on pixel centers
- local px1 = m1 * (y + 0.5 - vec1.y) + vec1.x
- local px2 = m2 * (y + 0.5 - vec1.y) + vec1.x
- drawFlatTriangle(arController,px1,px2,y,color)
- end
- end
- --Draw an entire object one triangle at a time
- --Converts points from the 1D table to vectors b/c I'm lazy
- local function drawSolidObj( arController,vL,cL ) --iL == index List. vL == vertex list. cL == color list
- --OPTIMIZATION here?. Probably should convert to 1D at least
- for i = 1, #vL, 3 do --Try to draw a triangle
- --using pointers so we can swap (for sorting purposes) probably don't need this b/c lua? idk
- local pv1 = vL[1]
- local pv2 = vL[2]
- local pv3 = vL[3]
- --Sort vertices by y
- if pv2.y < pv1.y then pv1,pv2 = pv2,pv1 end
- if pv3.y < pv2.y then pv2,pv3 = pv3,pv2 end
- if pv2.y < pv1.y then pv1,pv2 = pv2,pv1 end
- if pv1.y == pv2.y then --Natural flat top
- --Sort top vertice by x
- if pv2.x < pv1.x then pv1,pv2 = pv2,pv1 end
- drawFlatTopTriangle(arController,pv1,pv2,pv3)
- elseif pv2.y == pv3.y then --Natural flat bottom
- --Sort bottom vertice by x
- if pv3.x < pv2.x then pv3,pv2 = pv2,pv3 end
- drawFlatBottomTriangle(arController,pv1,pv2,pv3)
- else --General triangle
- local alphaSplit = (pv2.y-pv1.y)/(pv3.y-pv1.y)
- local vi ={
- x = pv1.x + ((pv3.x - pv1.x) * alphaSplit),
- y = pv1.y + ((pv3.y - pv1.y) * alphaSplit), }
- if pv2.x < vi.x then --Major right
- drawFlatBottomTriangle(arController,pv1,pv2,vi)
- drawFlatTopTriangle(arController,pv2,vi,pv3)
- else --Major left
- drawFlatBottomTriangle(arController,pv1,vi,pv2)
- drawFlatTopTriangle(arController,vi,pv2,pv3)
- end
- end
- end
- end
- --### Textured drawing functions ###
- local function drawFlatTopTriangleTex( arController,vec1,vec2,vec3, texture )
- --Calculate slopes in screen space
- --Run over rise so we don't get infinite slopes
- local m1 = (vec3.x - vec1.x) / (vec3.y - vec1.y)
- local m2 = (vec3.x - vec2.x) / (vec3.y - vec2.y)
- --Calculate start and end scanlines
- local yStart = math.ceil(vec1.y - 0.5)
- local yEnd = math.ceil(vec3.y - 0.5)-1 --the scanline AFTER the last line drawn
- local tWidth = texture.size.x
- local tHeight = texture.size.y
- local A = vec3
- local B = vec2
- local C = vec1
- for y = yStart, yEnd do
- --calculate start and end x's
- --Add 0.5 because we're calculating based on pixel centers
- local px1 = m1 * (y + 0.5 - vec1.y) + vec1.x
- local px2 = m2 * (y + 0.5 - vec2.y) + vec2.x
- local xStart = math.ceil(px1 - 0.5)
- local xEnd = math.ceil(px2 - 0.5)
- --To change to individual pixel plotting instead of whole lines, uncomment this `for` loop and replace `(xStart, xEnd, y, color)` with `( x, x, y, color )` in the horizontalLine() function
- for x = xStart, xEnd do
- if y > 0 and x > 0 then
- --find w1,w2,w3
- local w1 =
- (A.x*(C.y - A.y)+(y - A.y)*(C.x - A.x)-x*(C.y - A.y))
- /((B.y - A.y)*(C.x - A.x))-((B.x - A.x)*(C.y - A.y))
- local w2 = (y - A.y - w1 *(B.y - A.y))/(C.y - A.y)
- local w3 = 1-w1-w2
- --find
- local u = (w1*A.u)+(w2*B.u)+(w3*C.u)
- local v = (w1*A.v)+(w2*B.v)+(w3*C.v)
- --final target texture uv coordinates
- local tu = (u * tWidth)
- local tv = (v * tHeight)
- local color = texture[ (tv*tWidth) + tu ] --Look up the pixel color in the image texture
- arController.horizontalLine(xStart, xEnd, y, color) --Draws a horizontal line. have xStart and xEnd == to the same x val to plot just one pixel
- end
- end
- --drawFlatTriangle(arController,px1,px2,y,color)
- end
- end
- local function drawFlatBottomTriangleTex( arController,vec1,vec2,vec3, texture )
- --Calculate slopes in screen space
- local m1 = (vec2.x - vec1.x) / (vec2.y - vec1.y)
- local m2 = (vec3.x - vec1.x) / (vec3.y - vec1.y)
- --Calculate start and end scanlines
- local yStart = math.ceil(vec1.y-0.5)
- 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
- local tWidth = texture.size.x
- local tHeight = texture.size.y
- local A = vec3
- local B = vec2
- local C = vec1
- for y = yStart, yEnd do
- --calculate start and end points (x coords)
- --Add 0.5 because we're calculating based on pixel centers
- local px1 = m1 * (y + 0.5 - vec1.y) + vec1.x
- local px2 = m2 * (y + 0.5 - vec1.y) + vec1.x
- local xStart = math.ceil(px1 - 0.5)
- local xEnd = math.ceil(px2 - 0.5)
- --To change to individual pixel plotting instead of whole lines, uncomment this `for` loop and replace `(xStart, xEnd, y, color)` with `( x, x, y, color )` in the horizontalLine() function
- for x = xStart, xEnd do
- if y > 0 and x > 0 then
- --find w1,w2,w3
- local w1 =
- (A.x*(C.y - A.y)+(y - A.y)*(C.x - A.x)-x*(C.y - A.y))
- /((B.y - A.y)*(C.x - A.x))-((B.x - A.x)*(C.y - A.y))
- local w2 = (y - A.y - w1 *(B.y - A.y))/(C.y - A.y)
- local w3 = 1-w1-w2
- --find
- local u = (w1*A.u)+(w2*B.u)+(w3*C.u)
- local v = (w1*A.v)+(w2*B.v)+(w3*C.v)
- --final texture uv coordinates
- local tu = (u * tWidth)
- local tv = (v * tHeight)
- local color = texture[ (tv*tWidth) + tu ] --Look up the pixel color in the image texture
- arController.horizontalLine(xStart, xEnd, y, color) --Draws a horizontal line. have xStart and xEnd == to the same x val to plot just one pixel
- end
- end
- end
- end
- local function drawSolidObjTex( arController,vL,objData) --iL == index List. vL == vertex list. cL == color list
- --OPTIMIZATION here?. Probably should convert to 1D at least
- for i = 1, #vL, 3 do --Try to draw a trianglelocal vec3 = { x= vL[ iL[i2] ], y= vL[ iL[i2]+1 ], z= vL[ iL[i2]+2 ] } --Target vertex3's x/y and z
- --using pointers so we can swap (for sorting purposes) probably don't need this b/c lua? idk
- local texData = {}
- if objData.useShader then
- texData = objData.texData
- end
- local pv1 = vL[i]
- local pv2 = vL[i+1]
- local pv3 = vL[i+2]
- --Sort vertices by y
- if pv2.y < pv1.y then pv1,pv2 = pv2,pv1 end
- if pv3.y < pv2.y then pv2,pv3 = pv3,pv2 end
- if pv2.y < pv1.y then pv1,pv2 = pv2,pv1 end
- if pv1.y == pv2.y then --Natural flat top
- --Sort top vertice by x
- if pv2.x < pv1.x then pv1,pv2 = pv2,pv1 end
- drawFlatTopTriangle(arController,pv1,pv2,pv3,texData)
- elseif pv2.y == pv3.y then --Natural flat bottom
- --Sort bottom vertice by x
- if pv3.x < pv2.x then pv3,pv2 = pv2,pv3 end
- drawFlatBottomTriangle(arController,pv1,pv2,pv3,texData)
- else --General triangle
- local alphaSplit = (pv2.y-pv1.y)/(pv3.y-pv1.y)
- local vi ={
- x = pv1.x + ((pv3.x - pv1.x) * alphaSplit),
- y = pv1.y + ((pv3.y - pv1.y) * alphaSplit),
- z = pv1.z + ((pv3.z - pv1.z) * alphaSplit),
- u = pv1.u + ((pv3.u - pv1.u) * alphaSplit),
- v = pv1.v + ((pv3.v - pv1.v) * alphaSplit),
- }
- if pv2.x < vi.x then --Major right
- drawFlatBottomTriangle(arController,pv1,pv2,vi,texData)
- drawFlatTopTriangle(arController,pv2,vi,pv3,texData)
- else --Major left
- drawFlatBottomTriangle(arController,pv1,vi,pv2,texData)
- drawFlatTopTriangle(arController,vi,pv2,pv3,texData)
- end
- end
- end
- end
- --Expose functions
- return
- {
- drawWireObj = drawWireObj,
- drawSolidObj = drawSolidObj,
- drawSolidObjTex = drawSolidObjTex,
- }
Add Comment
Please, Sign In to add comment