Advertisement
Guest User

Untitled

a guest
Mar 17th, 2017
90
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Rust 3.91 KB | None | 0 0
  1.  
  2. // Helper stuff for printing:
  3. #[external] fn print(val: int);
  4. #[external] fn printfl(val: float);
  5. #[external] fn plot(x: int, y: int, val: int);
  6.  
  7. // System stuff:
  8. #[external] fn DebugBreak();
  9.  
  10. // Libc:
  11. #[external] fn malloc(bytes: int) -> void ptr;
  12. #[external] fn memcpy(dest: void ptr, src: void ptr, bytes: int) -> void ptr;
  13.  
  14. // Math:
  15. #[external] fn log(val: float) -> float;
  16. #[external] fn sqrtf(val: float) -> float;
  17.  
  18. // File access:
  19. #[external] fn fopen(name: void ptr, access: void ptr) -> void ptr;
  20. #[external] fn fwrite(ptr: int ptr, size: int, count: int, stream: void ptr);
  21. #[external] fn fclose(stream: void ptr);
  22.  
  23. type option<T> = None | Some(T);
  24.  
  25. type vec3 = {
  26.   x: float;
  27.   y: float;
  28.   z: float;
  29.  
  30.   fn length() -> float;
  31.   fn length_sq() -> float;
  32.  
  33.   fn scale(s: float);
  34.  
  35.   fn cross(rhs: vec3) -> vec3;
  36.   fn dot(rhs: vec3) -> float;
  37.   fn normalized() -> vec3;
  38.   fn diff(rhs: vec3) -> vec3;
  39. }
  40.  
  41. fn mkvec(x: float, y: float, z: float) -> vec3 {
  42.   return { x, y, z } : vec3;
  43. }
  44.  
  45. impl vec3 {
  46.   fn length() -> float {
  47.     return sqrtf(x*x + y*y + z*z);
  48.   }
  49.  
  50.   fn length_sq() -> float {
  51.     return x*x + y*y + z*z;
  52.   }
  53.  
  54.   fn dot(rhs: vec3) -> float {
  55.     return x * rhs.x + y * rhs.y + z * rhs.z;
  56.   }
  57.  
  58.   fn scale(s: float) {
  59.     x = x / s;
  60.     y = y / s;
  61.     z = z / s;
  62.   }
  63.  
  64.   fn cross(rhs: vec3) -> vec3 {
  65.     return mkvec(
  66.       y*rhs.z - z*rhs.y,
  67.       z*rhs.x - x*rhs.z,
  68.       x*rhs.y - y*rhs.x
  69.     );
  70.   }
  71.  
  72.   fn normalized() -> vec3 {
  73.     let ret = {x, y, z} : vec3;
  74.     ret.scale(ret.length());
  75.     return ret;
  76.   }
  77.  
  78.   fn diff(rhs: vec3) -> vec3 {
  79.     return { x - rhs.x, y - rhs.y, z - rhs.z } : vec3;
  80.   }
  81. }
  82.  
  83. fn lerp(left: float, right: float, amount: float) -> float {
  84.   return left + (right - left) * amount;
  85. }
  86.  
  87. type sphere = {
  88.   radius: float;
  89.   center: vec3;
  90.  
  91.   fn ray_cast(from: vec3, dir: vec3) -> float option;
  92. }
  93.  
  94. fn float_min(a: float, b: float) -> float {
  95.   if a > b { return b; }
  96.   return a;
  97. }
  98.  
  99. type two_solution = {
  100.   first: float;
  101.   second: float;
  102. }
  103.  
  104. type quadratic_solution = Zero | One(float) | Two(two_solution);
  105.  
  106. fn solve_quadratic(a: float, b: float, c: float) -> quadratic_solution {
  107.   let discriminant = b*b - 4*a*c;
  108.   if discriminant < 0 { return Zero; }
  109.  
  110.   if discriminant == 0.0 {
  111.     return One(-b  / (2.0 * a));
  112.   }
  113.  
  114.   let s = sqrtf(discriminant);
  115.  
  116.   let sols = {
  117.     (-b + s) / (2 * a),
  118.     (-b - s) / (2 * a)
  119.   } : two_solution;
  120.   return Two(sols);
  121. }
  122.  
  123. impl sphere {
  124.   fn ray_cast(from: vec3, dir: vec3) -> float option {
  125.     let center_to_origin = from.diff(center);
  126.     match solve_quadratic(1.0, 2 * dir.dot(center_to_origin), center_to_origin.length_sq() - radius*radius) {
  127.       One(a) { return Some(a); }
  128.       Two(b) { return Some(float_min(b.first, b.second)); }
  129.       _ {}
  130.     }
  131.  
  132.     return None;
  133.   }
  134. }
  135.  
  136. fn mksphere(radius: float, origin: vec3) -> sphere {
  137.   return { radius, origin } : sphere;
  138. }
  139.  
  140. // This opens a.raw through hardcoded integers that represent the ASCII strings:
  141. fn open_file() -> void ptr {
  142.   let name = 512735981153; // This is 'a.raw':
  143.   let access = 25207; // This is "wb"
  144.   return fopen(&name : void ptr, &access : void ptr);
  145. }
  146.  
  147. fn go() {
  148.   let scanwidth = 1024;
  149.   let scanheight = 1024;
  150.  
  151.   let f = open_file();
  152.  
  153.   let origin = mkvec(0.0, 0.0, 0.0);
  154.  
  155.   let s = mksphere(5.0, mkvec(0.0, 0.0, 50.0));
  156.  
  157.   let xpx = 0;
  158.   while xpx < scanwidth {
  159.     let ypx = 0;
  160.     while ypx < scanheight {
  161.       let x0 = lerp(-1.13446, 1.13446, xpx:float / scanwidth);
  162.       let y0 = lerp(-1.13446, 1.13446, ypx:float / scanheight);
  163.  
  164.       let projection_dir = mkvec(x0, y0, 1.0);
  165.       projection_dir = projection_dir.normalized();
  166.  
  167.       let val = 0;
  168.  
  169.       match s.ray_cast(origin, projection_dir) {
  170.         Some(n) {
  171.           val = 255;
  172.         }
  173.         None {}
  174.       }
  175.  
  176.       fwrite(&val, 1, 1, f);
  177.  
  178.       ypx = ypx + 1;
  179.     }
  180.  
  181.     xpx = xpx + 1;
  182.   }
  183.  
  184.   fclose(f);
  185. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement