Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- -- This program was made while following this video about programming in Apple II BASIC:
- -- https://www.youtube.com/watch?v=PHfKCxjsmos
- -- This program renders a 3D cube being rotating along x, y, and z axes at 60fps.
- -- This code will only work in ComputerCraft.
- local round = function(n)
- return math.floor(n+0.5)
- end
- local wait = (function()
- local ticks = 0
- local startTime = os.clock()
- local frames = {os.clock()}
- local fps = 0
- return setmetatable({
- ticks = function() return ticks end,
- frameTime = function(real)
- local time = os.clock()-frames[1]
- if real then return time / fps
- else return round(time / fps * 20) / 20 end
- end,
- startTime = function() return startTime end,
- programClock = function() return os.clock() - startTime end,
- fps = function() return fps end
- }, {
- __call = function(self, n)
- n = tonumber(n) or 20
- if n <= 0 then error("Value out of range, must be greater than 0", 2) end
- ticks = ticks + 1
- frames[#frames+1] = os.clock()
- if n <= 20 then
- sleep(1/n)
- elseif ticks%round(n/20) == 0 then
- sleep(0.05)
- end
- while os.clock()-frames[1] > 1 and #frames > 1 do
- table.remove(frames, 1)
- end
- fps = #frames / (os.clock() - frames[1]) - (math.floor(n/20)-1)
- return fps
- end
- })
- end)()
- local xSize, ySize = term.getSize()
- local winBuffer = {
- [1] = window.create(term.current(), 1, 1, xSize, ySize),
- [2] = window.create(term.current(), 1, 1, xSize, ySize)
- }
- local cubeSize = ySize*1.4
- local xCenter, yCenter = round(xSize/2), round(ySize/2)
- local win = 1
- local angle = 0
- local points = {}
- for n = 1, 8 do
- local x, y, z = 0, 0, 0
- if n%4 < 2 then x = -1 else x = 1 end
- if (n-1)%4 < 2 then y = -1 else y = 1 end
- if n < 5 then z = -1 else z = 1 end
- points[n] = {
- position = vector.new(x, y, z),
- rotation = {
- x = vector.new(0, 0, 0),
- y = vector.new(0, 0, 0),
- z = vector.new(0, 0, 0)
- },
- projection = vector.new(0, 0, 0)
- }
- end
- local drawLine = function(a, b)
- local x1 = points[a].projection.x * cubeSize + xCenter
- local y1 = points[a].projection.y * cubeSize + yCenter
- local x2 = points[b].projection.x * cubeSize + xCenter
- local y2 = points[b].projection.y * cubeSize + yCenter
- paintutils.drawLine(x1, y1, x2, y2, colors.lime)
- end
- local bufferSwap = function()
- winBuffer[win].setVisible(true)
- if win == 1 then win = 2 else win = 1 end
- winBuffer[win].setVisible(false)
- term.redirect(winBuffer[win])
- end
- local setRotation = function()
- local cs = math.cos(angle)
- local sn = math.sin(angle)
- for n = 1, 8 do
- points[n].rotation.z.x = -cs*points[n].position.x + sn*points[n].position.y
- points[n].rotation.z.y = sn*points[n].position.x + cs*points[n].position.y
- points[n].rotation.z.z = points[n].position.z
- points[n].rotation.y.x = cs*points[n].rotation.z.x + sn*points[n].rotation.z.z
- points[n].rotation.y.y = points[n].rotation.z.y
- points[n].rotation.y.z = -sn*points[n].rotation.z.x + cs*points[n].rotation.z.z
- points[n].rotation.x.x = points[n].rotation.y.x
- points[n].rotation.x.y = cs*points[n].rotation.y.y - sn*points[n].rotation.y.z
- points[n].rotation.x.z = sn*points[n].rotation.y.y + cs*points[n].rotation.y.z
- local z = 1 / (5 - points[n].rotation.x.z)
- points[n].projection.x = points[n].rotation.x.x * z
- points[n].projection.y = points[n].rotation.x.y * z
- end
- end
- local drawCube = function()
- for n = 1, 8 do
- if n%4 > 0 then drawLine(n, n+1)
- else drawLine(n, n-3) end
- if n < 5 then drawLine(n, n+4) end
- end
- end
- while true do
- term.setBackgroundColor(colors.black)
- term.clear()
- term.setCursorPos(1, 1)
- print("FPS: " .. wait.fps())
- print("Start Time: " .. wait.startTime())
- print("Time Since Start: " .. wait.programClock())
- print("Ticks: " .. wait.ticks())
- print("Frametime: " .. wait.frameTime())
- print("Real Frametime: " .. wait.frameTime(true))
- print()
- print("Cube Size: " .. cubeSize)
- print("Angle: " .. round(angle*1000+500)/1000)
- setRotation()
- drawCube()
- angle = angle + 0.005
- bufferSwap()
- wait(60)
- end
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement