Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- --Draws a line from x1,y1 to x2,y2 with given color, using name of wrapped AR controller
- local function drawLineAR(wrapper,x1,y1,x2,y2,color)
- color = 0x000000 --Overriding color to black. Comment out to use custom colors
- local dx = x2 - x1
- local dy = y2 - y1
- local length = math.floor(math.sqrt((dx^2)+(dy^2)))
- for i = 1, length do
- local nextY = y1 + dy * (i / length)
- local nextX = x1 + dx * (i / length)
- wrapper.horizontalLine(nextX, nextX, nextY, color)
- end
- end
- --Draws an object with an indexList which points to a list x/y points, using name of wrapped AR controller
- local function drawWireObj(wrapper,vL) --vL == vertice list. cL == color list
- local cL = vL.colorList
- for i = 1, #vL, 12 do --Draws a whole triangle per loop
- local i1,i2 = i+1, i+2
- local col = cL[(i+2)/3]
- drawLineAR(wrapper, vL[i], vL[i+1], vL[i+4], vL[i+5], col) --vert 1 to 2
- drawLineAR(wrapper, vL[i+4], vL[i+5], vL[i+8], vL[i+9], col) --vert 2 to 3
- drawLineAR(wrapper, vL[i+8], vL[i+9], vL[i], vL[i+1], col) --vert 3 to 1
- end
- end
- --Basically a line function with cutoffs for anything < 0.
- local function drawFlatTriangle(wrapper,px1,px2,y,color)
- local xStart = math.ceil(px1 - 0.5)
- local xEnd = math.ceil(px2 - 0.5)
- if xEnd > 0 then
- if xStart < 0 then xStart = 0 end
- for x = xStart, xEnd do
- wrapper.horizontalLine(x, x, y, color)
- end
- end
- end
- --Basically a line function with cutoffs for anything < 0.
- local function drawFlatTriangleTerm(wrapper,px1,px2,y,color)
- local xStart = math.ceil(px1 - 0.5)
- local xEnd = math.ceil(px2 - 0.5)
- if xEnd > 0 then
- if xStart < 0 then xStart = 0 end
- for x = xStart, xEnd do
- term.setCursorPos(x,y)
- term.write(" ")
- 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( wrapper,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, which is why it's offset by -1
- if yEnd > 0 then
- if yStart < 0 then yStart = 0 end
- 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
- drawFlatTriangleTerm( wrapper,px1,px2,y,color )
- end
- end
- term.setBackgroundColour(colors.black)
- end
- local function drawFlatBottomTriangle( wrapper,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
- if yEnd > 0 then
- if yStart < 0 then yStart = 0 end
- for y = yStart, yEnd do
- --calculate start and end points (x/z 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
- drawFlatTriangleTerm( wrapper,px1,px2,y,color )
- end
- end
- end
- --Draws a solid triangle from 3 vectors
- local function drawSolidTriangle( wrapper,pv1,pv2,pv3,color )
- --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(wrapper,pv1,pv2,pv3,color )
- 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(wrapper,pv1,pv2,pv3,color )
- else --General triangle
- local alphaSplit = (pv2.y-pv1.y)/(pv3.y-pv1.y)
- local zAlphaSplit = (pv2.z-pv1.z)/(pv3.z-pv1.z)
- local wAlphaSplit = (pv2.w-pv1.w)/(pv3.w-pv1.w) --maybe redundant
- 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) * zAlphaSplit),
- w = pv1.w + ((pv3.w - pv1.w) * wAlphaSplit)
- }
- if pv2.x < vi.x then --Major right
- drawFlatBottomTriangle(wrapper,pv1,pv2,vi,color)
- drawFlatTopTriangle(wrapper,pv2,vi,pv3,color)
- else --Major left
- drawFlatBottomTriangle(wrapper,pv1,vi,pv2,color)
- drawFlatTopTriangle(wrapper,vi,pv2,pv3,color)
- end
- end
- end
- --Draw an entire object one triangle at a time
- --Converts points from the 1D table to vectors b/c I'm lazy and it's easier to process this way
- local function drawSolidObj( wrapper, vL ) --vL == index List. cL == color list
- term.setBackgroundColour(colors.white)
- local cL = vL.colorList
- --OPTIMIZATION here?. Probably should convert to 1D at least for full optimization
- for i = 1, #vL, 12 do
- local v1 = vector.new( vL[i], vL[i+1], vL[i+2] )
- local v2 = vector.new( vL[i+4], vL[i+5], vL[i+6] )
- local v3 = vector.new( vL[i+8], vL[i+9], vL[i+10] )
- v1.w = vL[i+3]
- v2.w = vL[i+7]
- v3.w = vL[i+11]
- drawSolidTriangle( wrapper, v1, v2, v3, cL[(i+2)/3] )
- end
- term.setBackgroundColour(colors.black)
- end
- -- + || 0, 1, 2, 3, || 4, 5, 6, 7, || 8, 9, 10, 11
- -- = || 1, 2, 3, 4, || 5, 6, 7, 8, || 9, 10, 11, 12
- -- K || x, y, z, w, || x, y, z, w, || x, y, z, w
- --Expose functions
- return
- {
- drawWireObj = drawWireObj,
- drawSolidObj = drawSolidObj,
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement