Guest User

vibrator's raymarching code [b/w cube]

a guest
Feb 5th, 2011
2,350
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Java 5 3.90 KB | None | 0 0
  1. package raymarching.rm01;
  2.  
  3. import prophecy.common.image.ImageSurface;
  4. import prophecy.common.image.RGB;
  5. import prophecy.common.image.RGBImage;
  6.  
  7. import javax.swing.*;
  8. import java.awt.*;
  9. import java.awt.event.ActionEvent;
  10. import java.awt.event.ActionListener;
  11.  
  12. public class RM01 {
  13.   public static void main(String[] args) {
  14.     new RM01();
  15.   }
  16.  
  17.   int swidth = 320, sheight = swidth*5/8;
  18.   RGBImage simage;
  19.   final double infinite = 1e10;
  20.   final double minDist = 1e-4;
  21.   final int maxIter = 100;
  22.   final double overstep = 1.0;
  23.   final double perspective = 0.75;
  24.   final V cameraLocation = new V(0, 0, -0.4);
  25.   final double zoom = 2.0;
  26.   double time = 0;
  27.  
  28.   RM01() {
  29.     simage = new RGBImage(swidth, sheight, Color.black);
  30.     paint();
  31.     final ImageSurface surface = new ImageSurface(simage);
  32.  
  33.     JButton button = new JButton("Next frame");
  34.     button.addActionListener(new ActionListener() {
  35.       public void actionPerformed(ActionEvent e) {
  36.         step();
  37.         paint();
  38.         simage.flush();
  39.         surface.setImage(simage);
  40.       }
  41.     });
  42.  
  43.     JFrame frame = new JFrame("Raymarching");
  44.     frame.getContentPane().setLayout(new BorderLayout());
  45.     frame.getContentPane().add(BorderLayout.CENTER, surface);
  46.     frame.getContentPane().add(BorderLayout.SOUTH, button);
  47.     frame.pack();
  48.     frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
  49.     frame.setVisible(true);
  50.   }
  51.  
  52.   private void step() {
  53.     ++time;
  54.   }
  55.  
  56.   void paint() {
  57.     for (int sy = 0; sy < sheight; sy++)
  58.       for (int sx = 0; sx < swidth; sx++) {
  59.         RGB color = renderPoint(sx, sy);
  60.         simage.setPixel(sx, sy, color);
  61.       }
  62.   }
  63.  
  64.   private RGB renderPoint(int sx, int sy) {
  65.     double x = (double) (sx - swidth / 2) / (swidth / 2);
  66.     double y = (double) (sy - sheight / 2) / (swidth / 2);
  67.     x /= zoom; y /= zoom;
  68.     V v = new V(x, y, 0).plus(cameraLocation);
  69.     V direction = new V(x*perspective, y*perspective, 1).normalize();
  70.     RGB color = null;
  71.  
  72.     for (int iter = 0; iter < maxIter; iter++) {
  73.       Dist dist = lookupDistance(v);
  74.       if (dist.color != null) color = dist.color;
  75.       if (dist.d == infinite)
  76.         return new RGB(Color.white);
  77.       else if (dist.d < minDist) {
  78.         //System.out.println(iter);
  79.         return color != null ? color : new RGB(Color.black);
  80.       } else {
  81.         //System.out.println(dist);
  82.         v = v.plus(direction.times(dist.d*overstep));
  83.       }
  84.     }
  85.     return new RGB(Color.gray);
  86.   }
  87.  
  88.   private Dist lookupDistance(V v) {
  89.     //return square(v);
  90.     //return cube(v, 0.5);
  91.     //return cube(rotateZ(Math.PI*0.125, v), 0.5);
  92.     //return cube(rotateX(Math.PI*0.125, v), 0.25);
  93.     return blackToWhiteCube(rotateY(Math.PI * 0.125 * time, v), 0.25);
  94.   }
  95.  
  96.   private V rotateX(double angle, V v) {
  97.     double sin = Math.sin(angle), cos = Math.cos(angle);
  98.     return new V(v.x, v.y*cos-v.z*sin, v.y*sin+v.z*cos);
  99.   }
  100.  
  101.   private V rotateY(double angle, V v) {
  102.     double sin = Math.sin(angle), cos = Math.cos(angle);
  103.     return new V(v.x*cos-v.z*sin, v.y, v.x*sin+v.z*cos);
  104.   }
  105.  
  106.   private V rotateZ(double angle, V v) {
  107.     double sin = Math.sin(angle), cos = Math.cos(angle);
  108.     return new V(v.x*cos-v.y*sin, v.x*sin+v.y*cos, v.z);
  109.   }
  110.  
  111.   private double square(V v) {
  112.     if (Math.abs(v.x) < 0.5 && Math.abs(v.y) < 0.5) return 0.0; else return infinite;
  113.   }
  114.  
  115.   private Dist blackCube(V v, double size) {
  116.     return new Dist(new RGB(Color.black), cube(v, size));
  117.   }
  118.  
  119.   private Dist blackToWhiteCube(V v, double size) {
  120.     double c = ((Math.max(-size, Math.min(size, v.y))/size)+1)/2;
  121.     return new Dist(new RGB(c), cube(v, size));
  122.   }
  123.  
  124.   /* a cube centered at 0,0,0 with a length of size*2 in all 3 dimensions */
  125.   private double cube(V v, double size) {
  126.     double x = Math.abs(v.x)-size, y = Math.abs(v.y)-size, z = Math.abs(v.z)-size;
  127.     return new V(Math.max(x, 0), Math.max(y, 0), Math.max(z, 0)).len();
  128.   }
  129. }
Advertisement
Add Comment
Please, Sign In to add comment