Advertisement
nonogamer9

The Compleat Angler (1979 CGI Demo) for OpenComputers

Aug 4th, 2024 (edited)
161
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Lua 5.33 KB | Software | 0 0
  1. local component = require("component")
  2. local gpu = component.gpu
  3. local event = require("event")
  4. local keyboard = require("keyboard")
  5. local math = require("math")
  6.  
  7. -- Set to Tier 3 resolution
  8. local width, height = 160, 50
  9. gpu.setResolution(width, height)
  10.  
  11. -- Set to 32-bit color mode
  12. gpu.setDepth(gpu.maxDepth())
  13.  
  14. -- Create double buffers
  15. local buffers = {gpu.allocateBuffer(width, height), gpu.allocateBuffer(width, height)}
  16. local currentBuffer = 1
  17.  
  18. -- Scene objects
  19. local mirroredSphere = {center = {x = 0, y = 0, z = 0}, radius = 15, color = 0xCCCCCC}
  20. local purpleSphere = {center = {x = 0, y = -10, z = 25}, radius = 7, color = 0x800080}
  21. local background = {color = 0x87CEFA}  -- Light blue background
  22.  
  23. -- Camera properties
  24. local camera = {
  25.     x = 0,
  26.     y = 0,
  27.     z = -50,
  28.     angleX = 0,
  29.     angleY = 0
  30. }
  31.  
  32. -- 3D vector operations
  33. local function vec3(x, y, z) return {x = x, y = y, z = z} end
  34. local function add(v1, v2) return vec3(v1.x + v2.x, v1.y + v2.y, v1.z + v2.z) end
  35. local function sub(v1, v2) return vec3(v1.x - v2.x, v1.y - v2.y, v1.z - v2.z) end
  36. local function mul(v, s) return vec3(v.x * s, v.y * s, v.z * s) end
  37. local function dot(v1, v2) return v1.x * v2.x + v1.y * v2.y + v1.z * v2.z end
  38. local function length(v) return math.sqrt(v.x * v.x + v.y * v.y + v.z * v.z) end
  39. local function normalize(v)
  40.     local len = length(v)
  41.     return vec3(v.x / len, v.y / len, v.z / len)
  42. end
  43.  
  44. -- Ray-sphere intersection
  45. local function intersectSphere(origin, dir, sphere)
  46.     local oc = sub(origin, sphere.center)
  47.     local a = dot(dir, dir)
  48.     local b = 2 * dot(oc, dir)
  49.     local c = dot(oc, oc) - sphere.radius * sphere.radius
  50.     local discriminant = b * b - 4 * a * c
  51.     if discriminant < 0 then return nil end
  52.     local t = (-b - math.sqrt(discriminant)) / (2 * a)
  53.     if t < 0 then return nil end
  54.     return t
  55. end
  56.  
  57. -- 3D to 2D projection
  58. local function project(point)
  59.     local rotX = {
  60.         {1, 0, 0},
  61.         {0, math.cos(camera.angleX), -math.sin(camera.angleX)},
  62.         {0, math.sin(camera.angleX), math.cos(camera.angleX)}
  63.     }
  64.     local rotY = {
  65.         {math.cos(camera.angleY), 0, math.sin(camera.angleY)},
  66.         {0, 1, 0},
  67.         {-math.sin(camera.angleY), 0, math.cos(camera.angleY)}
  68.     }
  69.    
  70.     local function matMul(m, v)
  71.         return vec3(
  72.             m[1][1]*v.x + m[1][2]*v.y + m[1][3]*v.z,
  73.             m[2][1]*v.x + m[2][2]*v.y + m[2][3]*v.z,
  74.             m[3][1]*v.x + m[3][2]*v.y + m[3][3]*v.z
  75.         )
  76.     end
  77.    
  78.     local rotated = matMul(rotY, matMul(rotX, sub(point, camera)))
  79.     local scale = 200 / (rotated.z + 200)
  80.     return width / 2 + rotated.x * scale, height / 2 - rotated.y * scale
  81. end
  82.  
  83. -- Render frame
  84. local function renderFrame(time)
  85.     -- Rotate purple sphere around the mirrored sphere horizontally
  86.     local angle = time * math.pi / 2.5  -- Complete rotation every 5 seconds
  87.     purpleSphere.center.x = math.cos(angle) * 25
  88.     purpleSphere.center.z = math.sin(angle) * 25
  89.  
  90.     gpu.setActiveBuffer(buffers[currentBuffer])
  91.    
  92.     -- Draw background
  93.     gpu.setBackground(background.color)
  94.     gpu.fill(1, 1, width, height, " ")
  95.  
  96.     -- Render scene
  97.     for y = 1, height do
  98.         for x = 1, width do
  99.             local dir = normalize(vec3(x - width/2, height/2 - y, 100))
  100.             local color = background.color
  101.            
  102.             local t1 = intersectSphere(camera, dir, mirroredSphere)
  103.             if t1 then
  104.                 local hitPoint = add(camera, mul(dir, t1))
  105.                 local normal = normalize(sub(hitPoint, mirroredSphere.center))
  106.                 local reflectDir = sub(dir, mul(normal, 2 * dot(dir, normal)))
  107.                
  108.                 local t2 = intersectSphere(hitPoint, reflectDir, purpleSphere)
  109.                 if t2 then
  110.                     color = purpleSphere.color
  111.                 else
  112.                     color = mirroredSphere.color
  113.                 end
  114.             else
  115.                 local t2 = intersectSphere(camera, dir, purpleSphere)
  116.                 if t2 then
  117.                     color = purpleSphere.color
  118.                 end
  119.             end
  120.            
  121.             gpu.setBackground(color)
  122.             gpu.set(x, y, " ")
  123.         end
  124.     end
  125. end
  126.  
  127. -- Draw buffer to screen
  128. local function drawBuffer()
  129.     gpu.bitblt(0, 1, 1, width, height, buffers[currentBuffer], 1, 1)
  130. end
  131.  
  132. -- Handle camera rotation
  133. local function handleInput()
  134.     if keyboard.isKeyDown(keyboard.keys.up) then
  135.         camera.angleX = camera.angleX - 0.05
  136.     elseif keyboard.isKeyDown(keyboard.keys.down) then
  137.         camera.angleX = camera.angleX + 0.05
  138.     elseif keyboard.isKeyDown(keyboard.keys.left) then
  139.         camera.angleY = camera.angleY - 0.05
  140.     elseif keyboard.isKeyDown(keyboard.keys.right) then
  141.         camera.angleY = camera.angleY + 0.05
  142.     end
  143. end
  144.  
  145. -- Animation loop
  146. local startTime = os.clock()
  147. while true do
  148.     local currentTime = os.clock() - startTime
  149.     handleInput()
  150.     renderFrame(currentTime)
  151.     drawBuffer()
  152.     currentBuffer = 3 - currentBuffer  -- Switch buffers
  153.  
  154.     if keyboard.isKeyDown(keyboard.keys.q) then break end
  155.     os.sleep(0.01)  -- Small delay to prevent excessive CPU usage
  156. end
  157.  
  158. -- Clean up
  159. gpu.freeBuffer(buffers[1])
  160. gpu.freeBuffer(buffers[2])
  161. gpu.setActiveBuffer(0)
  162. gpu.setBackground(0x000000)
  163. gpu.setForeground(0xFFFFFF)
  164. print("Animation complete.")
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement