Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- local function _W(f) local e=setmetatable({}, {__index = _ENV or getfenv()}) if setfenv then setfenv(f, e) end return f(e) or e end
- local colors=_W(function(_ENV, ...)
- local pairs = pairs
- local colors = colors or setmetatable({}, {__index = function() return 1 end})
- local termSets = {
- [colors.white] = {240, 240, 240},
- [colors.orange] = {242, 178, 51},
- [colors.magenta] = {229, 127, 216},
- [colors.lightBlue] = {153, 178, 242},
- [colors.yellow] = {222, 222, 108},
- [colors.lime] = {127, 204, 25},
- [colors.pink] = {242, 178, 204},
- [colors.gray] = {76, 76, 76},
- [colors.lightGray] = {153, 153, 153},
- [colors.cyan] = {76, 153, 178},
- [colors.purple] = {178, 102, 229},
- [colors.blue] = {37, 49, 146},
- [colors.brown] = {127, 102, 76},
- [colors.green] = {5, 122, 100},
- [colors.red] = {204, 76, 76},
- [colors.black] = {0, 0, 0},
- }
- local strSets = {
- ["0"] = {240, 240, 240},
- ["1"] = {242, 178, 51},
- ["2"] = {229, 127, 216},
- ["3"] = {153, 178, 242},
- ["4"] = {222, 222, 108},
- ["5"] = {127, 204, 25},
- ["6"] = {242, 178, 204},
- ["7"] = {76, 76, 76},
- ["8"] = {153, 153, 153},
- ["9"] = {76, 153, 178},
- ["a"] = {178, 102, 229},
- ["b"] = {37, 49, 146},
- ["c"] = {127, 102, 76},
- ["d"] = {5, 122, 100},
- ["e"] = {204, 76, 76},
- ["f"] = {0, 0, 0},
- }
- local function findClosestColor(colors, r, g, b)
- local smallestDifference = nil
- local smallestColor = nil
- for id, rgb in pairs(colors) do
- local diff = (r - rgb[1])^2 + (g - rgb[2])^2 + (b - rgb[3])^2
- if not smallestDifference or diff < smallestDifference then
- smallestColor = id
- smallestDifference = diff
- end
- end
- return smallestColor
- end
- local closestCache = {}
- --- Find the closest colour using a cache to store the results.
- -- This is because findClosestColor is not the fastest code.
- -- However, this could grow to be 256 ^ 3 bytes large (over 14MiB) which isn't great.
- local function findClosestCached(colors, r, g, b)
- local cache = closestCache[colors]
- if not cache then
- cache = {}
- closestCache[colors] = cache
- end
- local index = r * 65536 + g * 256 + b
- local result = cache[index]
- if not result then
- result = findClosestColor(colors, r, g, b)
- cache[index] = result
- end
- return result
- end
- return {
- findClosestColor = findClosestColor,
- findClosestCached = findClosestCached,
- termSets = termSets,
- strSets = strSets,
- }
- end)
- local graphics=_W(function(_ENV, ...)
- local width, height if term then width, height = term.getSize() else width, height = 400, 300 end
- local buffer = (function(...)
- local width, height = ...
- local colours, export = {}, {}
- local function clearColour(colour) colour = colour or {0, 0, 0, 255} for i = 1, width * height do colours[i] = colour end end
- export.clearColour = clearColour
- clearColour({0, 0, 0, 255})
- local depth, testDepth, inf = {}, true, math.huge
- local function clearDepth(colour) for i = 1, width * height do depth[i] = inf end end
- export.clearColour = clearColour
- clearDepth()
- export.clear = function(colour)
- clearColour(colour)
- clearDepth()
- end
- local function pixel(x, y, z, colour)
- if x < 1 or x > width or y < 1 or y > height or (z > 1 or z < -1) then return end
- local index = width * (y - 1) + x
- if z < depth[index] then
- depth[index] = z
- colours[index] = colour
- end
- end
- export.pixel = pixel
- export.love = function(love, oX, oY)
- local setPoint, setColour = love.graphics.point, love.graphics.setColor
- oX = oX or 0
- oY = oY or 0
- for y = 1, height do
- local offset = (y - 1) * width
- for x = 1, width do
- local colour = colours[offset + x]
- setColour(colour[1], colour[2], colour[3], colour[4])
- setPoint(oX + x, oY + y)
- end
- end
- end
- local blit_fore = ("0"):rep(width)
- local blit_text = (" "):rep(width)
- local closest, cols = colors.findClosestCached, colors.strSets
- local insert, concat = table.insert, table.concat
- export.cc = function(term, x, y)
- local blit, set = term.blit, term.setCursorPos
- for y = 1, height do
- local offset = (y - 1) * width
- local back = {}
- for x = 1 , width do
- local colour = colours[offset + x]
- insert(back, closest(cols, colour[1], colour[2], colour[3]))
- end
- set(1, y)
- blit(blit_text, blit_fore, concat(back))
- end
- end
- export.silica = function(term, x, y)
- local blit, set = term.blit, term.setCursorPos
- for y = 1, height do
- local offset = (y - 1) * width
- local back = {}
- for x = 1 , width do
- local colour = colours[offset + x]
- insert(back, closest(cols, colour[1], colour[2], colour[3]))
- end
- set(1, y)
- blit(concat(back))
- end
- end
- export.loveDepth = function(love, oX, oY)
- local setPoint, setColour = love.graphics.point, love.graphics.setColor
- oX = oX or 0
- oY = oY or 0
- for y = 1, height do
- local offset = (y - 1) * width
- for x = 1, width do
- if depth[offset + x] ~= inf then
- local color = 255 - ((depth[offset + x] + 1) / 2 * 255)
- setColour(color, color, color, 255)
- setPoint(oX + x + width, oY + y)
- end
- end
- end
- end
- export.size = function() return width, height end
- return export
- end)(width, height)
- buffer.line = (function(...)
- local pixel, width, height = ...
- local floor, abs = math.floor, math.abs
- return function(x1, y1, var1_1, x2, y2, var2_1, uniform_1)
- if (x1 < 1 and x2 < 1) or (x1 > width and x2 > width) or (y1 < 1 and y2 < 1) or (y1 > height and y2 > height) or (var1_1<-1 and var2_1<-1) or (var1_1>1 and var2_1>1) then return end
- x1, x2 = floor(x1), floor(x2)
- y1, y2 = floor(y1), floor(y2)
- local ndx, ndy = x2 - x1, y2 - y1
- local dx, dy = abs(ndx), abs(ndy)
- local steep = dy > dx
- if steep then
- dy, dx = dx, dy
- end
- local e = 2 * dy - dx
- local x, y = x1, y1
- local signy, signx = 1, 1
- if ndx < 0 then signx = -1 end
- if ndy < 0 then signy = -1 end
- local var_1, dvar_1 = var1_1, (var2_1 - var11) / dx
- for i = 1, dx do
- pixel(x, y, var, uniform_1)
- while e >= 0 do
- if steep then
- x = x + signx
- else
- y = y + signy
- end
- e = e - 2 * dx
- end
- if steep then
- y = y + signy
- else
- x = x + signx
- end
- e = e + 2 * dy
- var_1 = var_1 + dvar_1
- end
- pixel(x2, y2, var2_1, uniform_1)
- end
- end)(buffer.pixel, width, height)
- buffer.lineBlended = (function(...)
- local pixel, width, height = ...
- local floor, abs = math.floor, math.abs
- return function(x1, y1, var1_1, var1_2, x2, y2, var2_1, var2_2)
- if (x1 < 1 and x2 < 1) or (x1 > width and x2 > width) or (y1 < 1 and y2 < 1) or (y1 > height and y2 > height) or (var1_1<-1 and var2_1<-1) or (var1_1>1 and var2_1>1) then return end
- x1, x2 = floor(x1), floor(x2)
- y1, y2 = floor(y1), floor(y2)
- local ndx, ndy = x2 - x1, y2 - y1
- local dx, dy = abs(ndx), abs(ndy)
- local steep = dy > dx
- if steep then
- dy, dx = dx, dy
- end
- local e = 2 * dy - dx
- local x, y = x1, y1
- local signy, signx = 1, 1
- if ndx < 0 then signx = -1 end
- if ndy < 0 then signy = -1 end
- local var_1, dvar_1 = var1_1, (var2_1 - var11) / dx
- local var_2_1 = var1_2[1] local dvar_2_1 = (var2_2[1] - var_2_1) / dx
- local var_2_2 = var1_2[2] local dvar_2_2 = (var2_2[2] - var_2_2) / dx
- local var_2_3 = var1_2[3] local dvar_2_3 = (var2_2[3] - var_2_3) / dx
- local var_2_4 = var1_2[4] local dvar_2_4 = (var2_2[4] - var_2_4) / dx
- for i = 1, dx do
- pixel(x, y, var, {var, var, var, var, })
- while e >= 0 do
- if steep then
- x = x + signx
- else
- y = y + signy
- end
- e = e - 2 * dx
- end
- if steep then
- y = y + signy
- else
- x = x + signx
- end
- e = e + 2 * dy
- var_1 = var_1 + dvar_1
- var_2_1 = var_2_1 + dvar_2_1
- var_2_2 = var_2_2 + dvar_2_2
- var_2_3 = var_2_3 + dvar_2_3
- var_2_4 = var_2_4 + dvar_2_4
- end
- pixel(x2, y2, var2_1, var2_2)
- end
- end)(buffer.pixel, width, height)
- buffer.triangle = (function(...)
- local pixel, width, height = ...
- local floor, ceil, abs = math.floor, math.ceil, math.abs
- local bottom = function(x1, y1, var1_1, x2, y2, var2_1, x3, y3, var3_1, uniform_1)
- local xStart, xEnd = x1, x1 + 0.5
- local dy2, dy3 = y2 - y1, y3 - y1
- local dx2, dx3 = (x2 - x1) / dy2, (x3 - x1) / dy3
- local varStart_1, varEnd_1 = var1_1, var1_1
- local dVar2_1, dVar3_1 = (var2_1 - var1_1) / dy2, (var3_1 - var1_1) / dy3
- if dx3 < dx2 then
- dx2, dx3 = dx3, dx2
- dVar2_1, dVar3_1 = dVar3_1, dVar2_1
- end
- for y = y1, y2 do
- if y >= 1 and y <= height then
- for x = ceil(xStart), xEnd do
- local t = (x - xStart) / (xEnd - xStart)
- local tInv = 1 - t
- pixel(x, y, tInv * varStart_1 + t * varEnd_1, uniform_1)
- end
- end
- xStart, xEnd = xStart + dx2, xEnd + dx3
- varStart_1, varEnd_1 = varStart_1 + dVar2_1, varEnd_1 + dVar3_1
- end
- end
- local top = function(x1, y1, var1_1, x2, y2, var2_1, x3, y3, var3_1, uniform_1)
- local xStart, xEnd = x3, x3 + 0.5
- local dy1, dy2 = y3 - y1, y3 - y2
- local dx1, dx2 = (x3 - x1) / dy1, (x3 - x2) / dy2
- local varStart_1, varEnd_1 = var3_1, var3_1
- local dVar1_1, dVar2_1 = (var3_1 - var1_1) / dy1, (var3_1 - var2_1) / dy2
- if dx1 < dx2 then
- dx1, dx2 = dx2, dx1
- dVar1_1, dVar2_1 = dVar2_1, dVar1_1
- end
- for y = y3, y1, -1 do
- xStart, xEnd = xStart - dx1, xEnd - dx2
- varStart_1, varEnd_1 = varStart_1 - dVar1_1, varEnd_1 - dVar2_1
- if y >= 1 and y <= height then
- for x = ceil(xStart), xEnd do
- local t = (x - xStart) / (xEnd - xStart)
- local tInv = 1 - t
- pixel(x, y, tInv * varStart_1 + t * varEnd_1, uniform_1)
- end
- end
- end
- end
- return function(x1, y1, var1_1, x2, y2, var2_1, x3, y3, var3_1, uniform_1)
- if (x1 < 1 and x2 < 1) or (x1 > width and x2 > width) or (y1 < 1 and y2 < 1) or (y1 > height and y2 > height) or (var1_1<-1 and var2_1<-1 and var3_1<-1) or (var1_1>1 and var2_1>1 and var3_1>1) then return end
- x1, x2, x3 = floor(x1), floor(x2), floor(x3)
- y1, y2, y3 = floor(y1), floor(y2), floor(y3)
- if y1 > y2 then
- x1, x2 = x2, x1
- y1, y2 = y2, y1
- var1_1, var2_1 = var2_1, var1_1
- end
- if y1 > y3 then
- x1, x3 = x3, x1
- y1, y3 = y3, y1
- var1_1, var3_1 = var3_1, var1_1
- end
- if y2 > y3 then
- x2, x3 = x3, x2
- y2, y3 = y3, y2
- var2_1, var3_1 = var3_1, var2_1
- end
- if y2 == y3 then
- return bottom(x1, y1, var1_1, x2, y2, var2_1, x3, y3, var3_1, uniform_1)
- elseif y1 == y2 then
- return top(x1, y1, var1_1, x2, y2, var2_1, x3, y3, var3_1, uniform_1)
- else local delta = (y2 - y1) / (y3 - y1)
- local x = floor(x1 + delta * (x3 - x1))
- local var_1 = var1_1 + delta * (var3_1 - var1_1)
- bottom(x1, y1, var1_1, x2, y2, var2_1, x, y2, var_1, uniform_1)
- top(x2, y2, var2_1, x, y2, var_1, x3, y3, var3_1, uniform_1)
- end
- end
- end)(buffer.pixel, width, height)
- buffer.triangleBlended = (function(...)
- local pixel, width, height = ...
- local floor, ceil, abs = math.floor, math.ceil, math.abs
- local bottom = function(x1, y1, var1_1, var1_2, x2, y2, var2_1, var2_2, x3, y3, var3_1, var3_2)
- local xStart, xEnd = x1, x1 + 0.5
- local dy2, dy3 = y2 - y1, y3 - y1
- local dx2, dx3 = (x2 - x1) / dy2, (x3 - x1) / dy3
- local varStart_1, varEnd_1 = var1_1, var1_1
- local dVar2_1, dVar3_1 = (var2_1 - var1_1) / dy2, (var3_1 - var1_1) / dy3
- local varStart_2_1 = var1_2[1] local varEnd_2_1 = varStart_2_1
- local dVar2_2_1, dVar3_2_1 = (var2_2[1] - varStart_2_1) / dy2, (var3_2[1] - varStart_2_1) / dy3
- local varStart_2_2 = var1_2[2] local varEnd_2_2 = varStart_2_2
- local dVar2_2_2, dVar3_2_2 = (var2_2[2] - varStart_2_2) / dy2, (var3_2[2] - varStart_2_2) / dy3
- local varStart_2_3 = var1_2[3] local varEnd_2_3 = varStart_2_3
- local dVar2_2_3, dVar3_2_3 = (var2_2[3] - varStart_2_3) / dy2, (var3_2[3] - varStart_2_3) / dy3
- local varStart_2_4 = var1_2[4] local varEnd_2_4 = varStart_2_4
- local dVar2_2_4, dVar3_2_4 = (var2_2[4] - varStart_2_4) / dy2, (var3_2[4] - varStart_2_4) / dy3
- if dx3 < dx2 then
- dx2, dx3 = dx3, dx2
- dVar2_1, dVar3_1 = dVar3_1, dVar2_1
- dVar2_2_1, dVar3_2_1 = dVar3_2_1, dVar2_2_1
- dVar2_2_2, dVar3_2_2 = dVar3_2_2, dVar2_2_2
- dVar2_2_3, dVar3_2_3 = dVar3_2_3, dVar2_2_3
- dVar2_2_4, dVar3_2_4 = dVar3_2_4, dVar2_2_4
- end
- for y = y1, y2 do
- if y >= 1 and y <= height then
- for x = ceil(xStart), xEnd do
- local t = (x - xStart) / (xEnd - xStart)
- local tInv = 1 - t
- pixel(x, y, tInv * varStart_1 + t * varEnd_1, {tInv * varStart_2_1 + t * varEnd_2_1, tInv * varStart_2_2 + t * varEnd_2_2, tInv * varStart_2_3 + t * varEnd_2_3, tInv * varStart_2_4 + t * varEnd_2_4, })
- end
- end
- xStart, xEnd = xStart + dx2, xEnd + dx3
- varStart_1, varEnd_1 = varStart_1 + dVar2_1, varEnd_1 + dVar3_1
- varStart_2_1, varEnd_2_1 = varStart_2_1 + dVar2_2_1, varEnd_2_1 + dVar3_2_1
- varStart_2_2, varEnd_2_2 = varStart_2_2 + dVar2_2_2, varEnd_2_2 + dVar3_2_2
- varStart_2_3, varEnd_2_3 = varStart_2_3 + dVar2_2_3, varEnd_2_3 + dVar3_2_3
- varStart_2_4, varEnd_2_4 = varStart_2_4 + dVar2_2_4, varEnd_2_4 + dVar3_2_4
- end
- end
- local top = function(x1, y1, var1_1, var1_2, x2, y2, var2_1, var2_2, x3, y3, var3_1, var3_2)
- local xStart, xEnd = x3, x3 + 0.5
- local dy1, dy2 = y3 - y1, y3 - y2
- local dx1, dx2 = (x3 - x1) / dy1, (x3 - x2) / dy2
- local varStart_1, varEnd_1 = var3_1, var3_1
- local dVar1_1, dVar2_1 = (var3_1 - var1_1) / dy1, (var3_1 - var2_1) / dy2
- local varStart_2_1 = var3_2[1] local varEnd_2_1 = varStart_2_1
- local dVar1_2_1, dVar2_2_1 = (varStart_2_1 - var1_2[1]) / dy1, (varStart_2_1 - var2_2[1]) / dy2
- local varStart_2_2 = var3_2[2] local varEnd_2_2 = varStart_2_2
- local dVar1_2_2, dVar2_2_2 = (varStart_2_2 - var1_2[2]) / dy1, (varStart_2_2 - var2_2[2]) / dy2
- local varStart_2_3 = var3_2[3] local varEnd_2_3 = varStart_2_3
- local dVar1_2_3, dVar2_2_3 = (varStart_2_3 - var1_2[3]) / dy1, (varStart_2_3 - var2_2[3]) / dy2
- local varStart_2_4 = var3_2[4] local varEnd_2_4 = varStart_2_4
- local dVar1_2_4, dVar2_2_4 = (varStart_2_4 - var1_2[4]) / dy1, (varStart_2_4 - var2_2[4]) / dy2
- if dx1 < dx2 then
- dx1, dx2 = dx2, dx1
- dVar1_1, dVar2_1 = dVar2_1, dVar1_1
- dVar1_2_1, dVar2_2_1 = dVar2_2_1, dVar1_2_1
- dVar1_2_2, dVar2_2_2 = dVar2_2_2, dVar1_2_2
- dVar1_2_3, dVar2_2_3 = dVar2_2_3, dVar1_2_3
- dVar1_2_4, dVar2_2_4 = dVar2_2_4, dVar1_2_4
- end
- for y = y3, y1, -1 do
- xStart, xEnd = xStart - dx1, xEnd - dx2
- varStart_1, varEnd_1 = varStart_1 - dVar1_1, varEnd_1 - dVar2_1
- varStart_2_1, varEnd_2_1 = varStart_2_1 - dVar1_2_1, varEnd_2_1 - dVar2_2_1
- varStart_2_2, varEnd_2_2 = varStart_2_2 - dVar1_2_2, varEnd_2_2 - dVar2_2_2
- varStart_2_3, varEnd_2_3 = varStart_2_3 - dVar1_2_3, varEnd_2_3 - dVar2_2_3
- varStart_2_4, varEnd_2_4 = varStart_2_4 - dVar1_2_4, varEnd_2_4 - dVar2_2_4
- if y >= 1 and y <= height then
- for x = ceil(xStart), xEnd do
- local t = (x - xStart) / (xEnd - xStart)
- local tInv = 1 - t
- pixel(x, y, tInv * varStart_1 + t * varEnd_1, {tInv * varStart_2_1 + t * varEnd_2_1, tInv * varStart_2_2 + t * varEnd_2_2, tInv * varStart_2_3 + t * varEnd_2_3, tInv * varStart_2_4 + t * varEnd_2_4, })
- end
- end
- end
- end
- return function(x1, y1, var1_1, var1_2, x2, y2, var2_1, var2_2, x3, y3, var3_1, var3_2)
- if (x1 < 1 and x2 < 1) or (x1 > width and x2 > width) or (y1 < 1 and y2 < 1) or (y1 > height and y2 > height) or (var1_1<-1 and var2_1<-1 and var3_1<-1) or (var1_1>1 and var2_1>1 and var3_1>1) then return end
- x1, x2, x3 = floor(x1), floor(x2), floor(x3)
- y1, y2, y3 = floor(y1), floor(y2), floor(y3)
- if y1 > y2 then
- x1, x2 = x2, x1
- y1, y2 = y2, y1
- var1_1, var2_1 = var2_1, var1_1
- var1_2, var2_2 = var2_2, var1_2
- end
- if y1 > y3 then
- x1, x3 = x3, x1
- y1, y3 = y3, y1
- var1_1, var3_1 = var3_1, var1_1
- var1_2, var3_2 = var3_2, var1_2
- end
- if y2 > y3 then
- x2, x3 = x3, x2
- y2, y3 = y3, y2
- var2_1, var3_1 = var3_1, var2_1
- var2_2, var3_2 = var3_2, var2_2
- end
- if y2 == y3 then
- return bottom(x1, y1, var1_1, var1_2, x2, y2, var2_1, var2_2, x3, y3, var3_1, var3_2)
- elseif y1 == y2 then
- return top(x1, y1, var1_1, var1_2, x2, y2, var2_1, var2_2, x3, y3, var3_1, var3_2)
- else local delta = (y2 - y1) / (y3 - y1)
- local x = floor(x1 + delta * (x3 - x1))
- local var_1 = var1_1 + delta * (var3_1 - var1_1)
- local var_2 = {
- var1_2[1] + delta * (var3_2[1] - var1_2[1]),
- var1_2[2] + delta * (var3_2[2] - var1_2[2]),
- var1_2[3] + delta * (var3_2[3] - var1_2[3]),
- var1_2[4] + delta * (var3_2[4] - var1_2[4]),
- }
- bottom(x1, y1, var1_1, var1_2, x2, y2, var2_1, var2_2, x, y2, var_1, var_2)
- top(x2, y2, var2_1, var2_2, x, y2, var_1, var_2, x3, y3, var3_1, var3_2)
- end
- end
- end)(buffer.pixel, width, height)
- return buffer
- end)
- local matrix=_W(function(_ENV, ...)
- return {
- matrix = function(l, r)
- local l_1_1=l[1]
- local l_2_1=l[2]
- local l_3_1=l[3]
- local l_4_1=l[4]
- local l_1_2=l[5]
- local l_2_2=l[6]
- local l_3_2=l[7]
- local l_4_2=l[8]
- local l_1_3=l[9]
- local l_2_3=l[10]
- local l_3_3=l[11]
- local l_4_3=l[12]
- local l_1_4=l[13]
- local l_2_4=l[14]
- local l_3_4=l[15]
- local l_4_4=l[16]
- local r_1_1=r[1]
- local r_2_1=r[2]
- local r_3_1=r[3]
- local r_4_1=r[4]
- local r_1_2=r[5]
- local r_2_2=r[6]
- local r_3_2=r[7]
- local r_4_2=r[8]
- local r_1_3=r[9]
- local r_2_3=r[10]
- local r_3_3=r[11]
- local r_4_3=r[12]
- local r_1_4=r[13]
- local r_2_4=r[14]
- local r_3_4=r[15]
- local r_4_4=r[16]
- return {
- l_1_1*r_1_1 + l_1_2*r_2_1 + l_1_3*r_3_1 + l_1_4*r_4_1,
- l_2_1*r_1_1 + l_2_2*r_2_1 + l_2_3*r_3_1 + l_2_4*r_4_1,
- l_3_1*r_1_1 + l_3_2*r_2_1 + l_3_3*r_3_1 + l_3_4*r_4_1,
- l_4_1*r_1_1 + l_4_2*r_2_1 + l_4_3*r_3_1 + l_4_4*r_4_1,
- l_1_1*r_1_2 + l_1_2*r_2_2 + l_1_3*r_3_2 + l_1_4*r_4_2,
- l_2_1*r_1_2 + l_2_2*r_2_2 + l_2_3*r_3_2 + l_2_4*r_4_2,
- l_3_1*r_1_2 + l_3_2*r_2_2 + l_3_3*r_3_2 + l_3_4*r_4_2,
- l_4_1*r_1_2 + l_4_2*r_2_2 + l_4_3*r_3_2 + l_4_4*r_4_2,
- l_1_1*r_1_3 + l_1_2*r_2_3 + l_1_3*r_3_3 + l_1_4*r_4_3,
- l_2_1*r_1_3 + l_2_2*r_2_3 + l_2_3*r_3_3 + l_2_4*r_4_3,
- l_3_1*r_1_3 + l_3_2*r_2_3 + l_3_3*r_3_3 + l_3_4*r_4_3,
- l_4_1*r_1_3 + l_4_2*r_2_3 + l_4_3*r_3_3 + l_4_4*r_4_3,
- l_1_1*r_1_4 + l_1_2*r_2_4 + l_1_3*r_3_4 + l_1_4*r_4_4,
- l_2_1*r_1_4 + l_2_2*r_2_4 + l_2_3*r_3_4 + l_2_4*r_4_4,
- l_3_1*r_1_4 + l_3_2*r_2_4 + l_3_3*r_3_4 + l_3_4*r_4_4,
- l_4_1*r_1_4 + l_4_2*r_2_4 + l_4_3*r_3_4 + l_4_4*r_4_4,
- }
- end,
- vector = function(l, r)
- local l_1_1=l[1]
- local l_2_1=l[2]
- local l_3_1=l[3]
- local l_4_1=l[4]
- local l_1_2=l[5]
- local l_2_2=l[6]
- local l_3_2=l[7]
- local l_4_2=l[8]
- local l_1_3=l[9]
- local l_2_3=l[10]
- local l_3_3=l[11]
- local l_4_3=l[12]
- local l_1_4=l[13]
- local l_2_4=l[14]
- local l_3_4=l[15]
- local l_4_4=l[16]
- local r_1_1=r[1]
- local r_2_1=r[2]
- local r_3_1=r[3]
- local r_4_1=r[4]
- return {
- l_1_1*r_1_1 + l_1_2*r_2_1 + l_1_3*r_3_1 + l_1_4*r_4_1,
- l_2_1*r_1_1 + l_2_2*r_2_1 + l_2_3*r_3_1 + l_2_4*r_4_1,
- l_3_1*r_1_1 + l_3_2*r_2_1 + l_3_3*r_3_1 + l_3_4*r_4_1,
- l_4_1*r_1_1 + l_4_2*r_2_1 + l_4_3*r_3_1 + l_4_4*r_4_1,
- }
- end,
- }
- end)
- local transform=_W(function(_ENV, ...)
- --[[
- Handles matrix transformations
- Several references:
- - https://open.gl/transformations
- - http://www.songho.ca/opengl/gl_transform.html
- - https://github.com/g-truc/glm/blob/master/glm/gtc/matrix_transform.inl
- - http://www.codinglabs.net/article_world_view_projection_matrix.aspx
- ]]
- local sin, cos, tan = math.sin, math.cos, math.tan
- local function translate(x, y, z)
- return {
- 1, 0, 0, 0,
- 0, 1, 0, 0,
- 0, 0, 1, 0,
- x, y, z, 1,
- }
- end
- local function scale(x, y, z)
- return {
- x, 0, 0, 0,
- 0, y, 0, 0,
- 0, 0, z, 0,
- 0, 0, 0, 1,
- }
- end
- local function rotateX(a)
- local c, s = cos(a), sin(a)
- return {
- 1, 0, 0, 0,
- 0, c, s, 0,
- 0, -s, c, 0,
- 0, 0, 0, 1
- }
- end
- local function rotateY(a)
- local c, s = cos(a), sin(a)
- return {
- c, 0, s, 0,
- 0, 1, 0, 0,
- -s, 0, c, 0,
- 0, 0, 0, 1
- }
- end
- local function rotateZ(a)
- local c, s = cos(a), sin(a)
- return {
- c, -s, 0, 0,
- s, c, 0, 0,
- 0, 0, 1, 0,
- 0, 0, 0, 1,
- }
- end
- local function orthographic(left, right, bottom, top, zNear, zFar)
- local invRL, invTB, invFN = 1 / (right - left), 1 / (top - bottom), 1 / (zNear - zFar)
- return {
- 2 * invRL, 0, 0, 0,
- 0, 2 * invTB, 0, 0,
- 0, 0, -2 * invFN, 0,
- -- Translate
- (-right + left) * invRL, -(top + bottom) * invTB, -(zFar + zNear) * invFN, 1,
- }
- end
- local function perspective(fovy, aspect, zNear, zFar)
- local tanHalfFovy = tan(fovy / 2)
- -- Diagonals
- return {
- 1 / (aspect * tanHalfFovy), 0, 0, 0,
- 0, 1 / tanHalfFovy, 0, 0,
- 0, 0, -(zFar + zNear) / (zFar - zNear), -1,
- 0, 0, -(2 * zNear * zFar) / (zFar - zNear), 0,
- }
- end
- return {
- translate = translate,
- scale = scale,
- rotateX = rotateX,
- rotateY = rotateY,
- rotateZ = rotateZ,
- orthographic = orthographic,
- perspective = perspective,
- }
- end)
- local verticies = {
- { 3, 3, -3, 1 },
- { 3, -3, -3, 1 },
- { -3, -3, -3, 1 },
- { -3, 3, -3, 1 },
- { 3, 3, 3, 1 },
- { 3, -3, 3, 1 },
- { -3, -3, 3, 1 },
- { -3, 3, 3, 1 },
- }
- local colours = {
- { 255, 0, 0, 100 },
- { 0, 255, 0, 100 },
- { 0, 0, 255, 100 },
- { 0, 255, 255, 100 },
- { 255, 255, 0, 100 },
- { 255, 0, 255, 100 },
- { 255, 128, 0, 100 },
- { 128, 255, 0, 100 },
- }
- local indexes = {
- {1,2,3, 1},
- {1,3,4, 1},
- {7,6,8, 2},
- {8,6,5, 2},
- {3,7,4, 3}, -- Left
- {4,7,8, 3},
- {5,6,2, 4},
- {2,1,5, 4},
- {5,1,4, 5}, -- Top
- {4,8,5, 5},
- {2,6,3, 6},
- {6,7,3, 6},
- }
- local g = graphics
- local debug = cclite and cclite.log or print
- local clock, format = os.clock, string.format
- local function profile(section, time) debug(format("[%.2f] %s: %.5f", clock(), section, time)) end
- local dispWidth, dispHeight = g.size()
- local projection = transform.perspective(math.pi / 2, 1, 0.1, 6.0)
- local function compose(...)
- local result, items = ..., {select(2, ...)}
- for _, item in pairs(items) do
- result = matrix.matrix(result, item)
- end
- return result
- end
- local function normalise(coord)
- coord[1] = (coord[1] + 1) * dispWidth / 2
- coord[2] = (coord[2] + 1) * dispHeight / 2
- coord[3] = (coord[3] + 1) / 2
- return coord
- end
- local function draw(g, v, group)
- local a, b, c = v[group[1]], v[group[2]], v[group[3]]
- g.triangle(
- a[1], a[2], a[3], -- colours[group[1]],
- b[1], b[2], b[3], -- colours[group[2]],
- c[1], c[2], c[3], colours[group[4]]
- )
- end
- local rotX, rotY = 0, 0
- local x, y, z = 0, 0, 8
- local function refreshMatrix()
- local start
- start = clock()
- local view = compose(unpack {
- transform.scale(1/20, 1/20, 1/20),
- transform.translate(-x, -y, -z),
- transform.rotateX(rotX),
- transform.rotateY(rotY),
- })
- local mvp = compose(projection, view)
- profile("Preparing MVP", clock() - start)
- g.clear()
- start = clock()
- local p = {}
- for k, v in pairs(verticies) do
- local coord = matrix.vector(mvp, v)
- if coord[4] == 0 then coord[4] = 1 print("SOMETHING IS 0", coord[3]) end
- coord[1] = coord[1] / coord[4]
- coord[2] = coord[2] / coord[4]
- p[k] = normalise(coord)
- end
- profile("Preparing Verticies", clock() - start)
- start = clock()
- for _, group in pairs(indexes) do
- draw(g, p, group)
- end
- profile("Drawing", clock() - start)
- end
- refreshMatrix()
- local rotSpeed, speed = 0.01, 0.1
- local changed = false
- local function pressed(key)
- if key == "a" then
- rotY = (rotY + rotSpeed) % (2 * math.pi)
- elseif key == "d" then
- rotY = (rotY - rotSpeed) % (2 * math.pi)
- elseif key == "w" then
- rotX = (rotX + rotSpeed) % (2 * math.pi)
- elseif key == "s" then
- rotX = (rotX - rotSpeed) % (2 * math.pi)
- elseif key == "u" then
- z = z + speed
- elseif key == "p" then
- z = z - speed
- elseif key == "j" then
- x = x + speed
- elseif key == "l" then
- x = x - speed
- elseif key == "i" then
- y = y + speed
- elseif key == "k" then
- y = y - speed
- elseif key == "r" then
- rotY = 0
- rotX = 0
- end
- changed = true
- end
- if term then
- g.silica(term.native())
- local fps = 30
- local id = os.startTimer(1 / fps)
- while true do
- local e, arg = os.pullEvent()
- if e == "char" then
- pressed(arg)
- elseif e == "timer" and arg == id then
- id = os.startTimer(1 / fps)
- if not changed then
- rotY = rotY + 0.05
- changed = true
- end
- if changed then
- local vStart = clock()
- refreshMatrix()
- changed = false
- local start = clock()
- g.silica(term.native())
- profile("Blitting", clock() - start)
- profile("TOTAL", clock() - vStart)
- debug("FPS: " .. (1 / (clock() - vStart)))
- end
- end
- end
- elseif love then
- love.keypressed = pressed
- function love.draw()
- if changed then
- refreshMatrix()
- changed = false
- end
- g.love(love)
- g.loveDepth(love, dispWidth)
- end
- else
- error("Requires running in silica of Love")
- end
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement