Advertisement
Yevano

CC Shadow Demo

May 21st, 2015
396
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Lua 5.34 KB | None | 0 0
  1. local sin   = math.sin
  2. local cos   = math.cos
  3. local tan   = math.tan
  4. local abs   = math.abs
  5. local min   = math.min
  6. local max   = math.max
  7. local floor = math.floor
  8. local sqrt  = math.sqrt
  9. local clock = os.clock
  10. local pi    = math.pi
  11.  
  12. -- Threshold values for RGB to RGBI conversion.
  13. R_THRESHOLD = 0.5
  14. G_THRESHOLD = 0.5
  15. B_THRESHOLD = 0.5
  16. I_THRESHOLD = 0.5
  17.  
  18. -- Conversion of 4-bit RGBI to CC colors.
  19. local palette = {
  20.     colors.black,
  21.     colors.gray,
  22.     colors.blue,
  23.     colors.blue,
  24.     colors.green,
  25.     colors.lime,
  26.     colors.cyan,
  27.     colors.lightBlue,
  28.     colors.red,
  29.     colors.red,
  30.     colors.purple,
  31.     colors.magenta,
  32.     colors.brown,
  33.     colors.yellow,
  34.     colors.lightGray,
  35.     colors.white,
  36. }
  37.  
  38. local function clamp(a, m, n)
  39.     return (a > n) and n or (a < m and m or a)
  40. end
  41.  
  42. -- Convert RGB to 4-bit RGBI index.
  43. local function rgbtorgbi(r, g, b)
  44.     r = clamp(r, 0, 1)
  45.     g = clamp(g, 0, 1)
  46.     b = clamp(b, 0, 1)
  47.     local R = r > R_THRESHOLD and 1 or 0
  48.     local G = g > G_THRESHOLD and 1 or 0
  49.     local B = b > B_THRESHOLD and 1 or 0
  50.     local I = (r + g + b)/3 > I_THRESHOLD and 1 or 0
  51.     return R * 8 + G * 4 + B * 2 + I
  52. end
  53.  
  54. --[[ Vector functions ]]--
  55.  
  56. local function length2(x, y)
  57.     return sqrt(x*x + y*y)
  58. end
  59.  
  60. local function length3(x, y, z)
  61.     return sqrt(x*x + y*y + z*z)
  62. end
  63.  
  64. local function normalize3(x, y, z)
  65.     local len = length3(x, y, z)
  66.     return x/len, y/len, z/len
  67. end
  68.  
  69. local function vec3add(x, y, z, a, b, c)
  70.     return x + a, y + b, z + c
  71. end
  72.  
  73. local function vec3sub(x, y, z, a, b, c)
  74.     return x - a, y - b, z - c
  75. end
  76.  
  77. local function vec3mulscalar(x, y, z, a)
  78.     return x * a, y * a, z * a
  79. end
  80.  
  81. local function vec3abs(x, y, z)
  82.     return abs(x), abs(y), abs(z)
  83. end
  84.  
  85. --[[ Matrix functions ]]
  86.  
  87. local function mat2mulvec2(m, x, y)
  88.     return  m[1] * x + m[2] * y,
  89.             m[3] * x + m[4] * y
  90. end
  91.  
  92. local function mat3mulvec3(m, x, y, z)
  93.     return  m[1] * x + m[2] * y + m[3] * z,
  94.             m[4] * x + m[5] * y + m[6] * z,
  95.             m[7] * x + m[8] * y + m[9] * z
  96. end
  97.  
  98. local function getRotMat2(a)
  99.     return { cos(a), -sin(a), sin(a), cos(a) }
  100. end
  101.  
  102. local function getRotMat3x(a)
  103.     return {    1,          0,          0,
  104.                 0,          cos(a),     -sin(a),
  105.                 0,          sin(a),     cos(a)  }
  106. end
  107.  
  108. local function getRotMat3y(a)
  109.     return {    cos(a),     0,          sin(a),
  110.                 0,          1,          0,
  111.                 -sin(a),    0,          cos(a)  }
  112. end
  113.  
  114. local function getRotMat3z(a)
  115.     return {    cos(a),     -sin(a),    0,
  116.                 sin(a),     cos(a),     0,
  117.                 0,          0,          1       }
  118. end
  119.  
  120. local w, h = term.getSize()
  121.  
  122. --[[ Distance functions ]]--
  123.  
  124. local function sphere(x, y, z, r)
  125.     return length3(x, y, z) - r
  126. end
  127.  
  128. local function box(x, y, z, a, b, c)
  129.     return max(max(abs(x) - a, abs(y) - b), abs(z) - c)
  130. end
  131.  
  132. -- Place all the models.
  133. local function map(x, y, z)
  134.     local d1, r1, g1, b1 = box(x, y + 1.5, z, 5, 1, 5), 1, 0, 0
  135.     local d2, r2, g2, b2 = box(x, y, z, 1, 2, 1), 0, 0, 1
  136.     local d, r, g, b = d1, r1, g1, b1
  137.     if d2 < d then d, r, g, b = d2, r2, g2, b2 end
  138.     return d, r, g, b
  139. end
  140.  
  141. local EPSILON = 0.001
  142. local MAX_DIST = 20
  143. local lx, ly, lz = 0, 0, 0
  144.  
  145. local function pixel(x, y)
  146.     -- Fix stretching.
  147.     local u, v = x/w, y/h
  148.     u = u * w/h*2/3
  149.     u = u - w/h*2/3/2
  150.     v = (1 - v) - 0.5
  151.  
  152.     lx, ly, lz = sin(clock())*4, 4, cos(clock())*4
  153.  
  154.     -- Rotation
  155.     local pitch, yaw, roll = 0.8, pi/4, 0
  156.     local rox, roy, roz = 0, 0, -5
  157.     rox, roy, roz = mat3mulvec3(getRotMat3x(pitch), rox, roy, roz)
  158.     rox, roy, roz = mat3mulvec3(getRotMat3y(yaw  ), rox, roy, roz)
  159.     rox, roy, roz = mat3mulvec3(getRotMat3z(roll ), rox, roy, roz)
  160.    
  161.     local rdx, rdy, rdz = normalize3(u, v, 1)
  162.     rdx, rdy, rdz = mat3mulvec3(getRotMat3x(pitch), rdx, rdy, rdz)
  163.     rdx, rdy, rdz = mat3mulvec3(getRotMat3y(yaw  ), rdx, rdy, rdz)
  164.     rdx, rdy, rdz = mat3mulvec3(getRotMat3z(roll ), rdx, rdy, rdz)
  165.  
  166.     local r, g, b
  167.     local hit = false
  168.  
  169.     -- Raymarching
  170.     local l = 0
  171.     for i = 1, 100 do
  172.         local rx, ry, rz = vec3add(rox, roy, roz, vec3mulscalar(rdx, rdy, rdz, l))
  173.         local d
  174.         d, r, g, b = map(rx, ry, rz)
  175.  
  176.         if d <= EPSILON then
  177.             rox, roy, roz = rx, ry, rz
  178.             hit = true
  179.             break
  180.         end
  181.  
  182.         if l > MAX_DIST then
  183.             return 0, 0, 0
  184.         end
  185.  
  186.         l = l + d
  187.     end
  188.     if not hit then return 0, 0, 0 end
  189.  
  190.     l = 0.1
  191.     rdx, rdy, rdz = normalize3(vec3sub(lx, ly, lz, rox, roy, roz))
  192.     for i = 1, 40 do
  193.         local rx, ry, rz = vec3add(rox, roy, roz, vec3mulscalar(rdx, rdy, rdz, l))
  194.         local d, r, g, b = map(rx, ry, rz)
  195.         local ldist = length3(vec3sub(lx, ly, lz, rx, ry, rz))
  196.  
  197.         if d <= EPSILON then
  198.             return 0, 1, 0
  199.         end
  200.  
  201.         if ldist <= d then
  202.             break
  203.         end
  204.  
  205.         l = l + min(d, ldist)
  206.     end
  207.  
  208.     return r, g, b
  209. end
  210.  
  211. term.clear()
  212.  
  213. local scp = term.setCursorPos
  214. local sbc = term.setBackgroundColor
  215. local tw  = term.write
  216.  
  217. -- Draw the pixels.
  218. while true do
  219.     for j = 1, h do
  220.         for i = 1, w do
  221.             scp(i, j)
  222.             sbc(palette[rgbtorgbi(pixel(i - 1, j - 1)) + 1])
  223.             tw(" ")
  224.         end
  225.     end
  226.     sleep(0)
  227. end
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement