• fullscreen
  • GUI.pde
  • fluid2d_GPU_CPU_guiDemo.pde
  • fluid_impacts.pde
  • //------------------------------------------------------------------------------
    //
    // author: thomas diewald
    // date: 27.07.2011
    //
    // basic fluid examples with gui controlls
    //
    // TAB: GUI
    // 
    //------------------------------------------------------------------------------
    
    
    
    
    
    
    public void initGUI(){
      //override gui-event
     
      my_gui = new GUI_CLASS(this, gui_pos_x, gui_pos_y, gui_size_x, gui_size_y, CPU_GPU);
      my_gui.makeGui();
    
      gui_event_ = new GUI_Event(){
          public void guiEvent(GUI_Element element){
          myGuiEvent(element);
        }
      };
      my_gui.gui.setGuiEvent(gui_event_);
      
      my_gui.cb_emitter1.trigger();
      my_gui.cb_emitter2.trigger();
      my_gui.cb_emitter3.trigger();
      my_gui.cb_emitter4.trigger();
      
    
      my_gui.cb_mouse_emit.trigger();
    }
      
      
      
      
    //------------------------------------------------------------------------------ 
    //gets called automatically
    public void myGuiEvent(GUI_Element element){
      //PApplet.println ("... active control = \"" +  element.Label().getLabel()+"\"");
      
      
    
      if( element == my_gui.cb_mouse_emit && my_gui.cb_mouse_emit.Status().isActive() ){
        my_gui.cb_addObstacles   .Status().setActive(false);
        my_gui.cb_removeObstacles.Status().setActive(false);
      }
      if( element == my_gui.cb_addObstacles && my_gui.cb_addObstacles.Status().isActive() ){
        my_gui.cb_mouse_emit     .Status().setActive(false);
        my_gui.cb_removeObstacles.Status().setActive(false);
      }
      if( element == my_gui.cb_removeObstacles && my_gui.cb_removeObstacles.Status().isActive() ){
        my_gui.cb_mouse_emit  .Status().setActive(false);
        my_gui.cb_addObstacles.Status().setActive(false);
      }
      
      //fluid_tmp.setDensityMap(output_densityMap);
      
      if( element == my_gui.b_reset_fluid){
        fluid.reset();
        fluid.setDensityMap(output_densityMap);
      }
      
    }
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    public class GUI_CLASS {
      // positioning
      public int gpx_, gpy_, gsx_, gsy_;
      public int gap_y_  = 15;
      public int offset_ = 20;
      public int h_def_  = 18;
      
      public PApplet papplet_;
      
      // gui instance
      public GUI             gui;
      
      // gui elements
      public GUI_Button      b_reset_fluid ;
      
      public GUI_Switch      sw1, sw2 ;
      
      public GUI_Tag         tag_caption;
     
    
      public GUI_CheckBox    cb_smooth,
                             cb_pause,
                             cb_emitter1,
                             cb_emitter2,
                             cb_emitter3,
                             cb_emitter4,
                             cb_addObstacles,
                             cb_removeObstacles,
                             cb_mouse_emit;
    
      public GUI_Slider      sl_timestep, 
                             sl_iterations1,
                             sl_iterations2, 
                             sl_viscosity,
                             sl_diffusion,
                             sl_vorticity,
                             sl_mouse_red, sl_mouse_green, sl_mouse_blue,
                             sl_addObstacle_size, sl_removeObstacle_size, sl_mouse_emit_size;
                             
      public GUI_TextDisplay td_frameRate;
    
      int fluid_mode_;
     
    //------------------------------------------------------------------------------ 
      public GUI_CLASS(PApplet papplet, int gui_pos_x, int gui_pos_y, int gui_size_x, int gui_size_y, int fluid_mode){
        gpx_ = gui_pos_x;
        gpy_ = gui_pos_y;
        gsx_ = gui_size_x;
        gsy_ = gui_size_y;
        fluid_mode_ = fluid_mode;
        papplet_ = papplet;
      }
    
      
    
    
    //------------------------------------------------------------------------------ 
      public void makeGui(){
         
        gui = new GUI(papplet_);
    //    if( papplet_.g.is3D() )
    //      gui.autoBuild(false);
    //    else
          gui.autoBuild(true);
        
    // ----------------------------------------------------------------
    
        PFont gui_label_font = papplet_.createFont("Calibri", 12);
    
        int x, y, w, h;
        
    
       
        
        w = gsx_-offset_*2;
        h = h_def_*2;
        x = gpx_+offset_;
        y = offset_;
     
        
    //  tag 1
        String mode = fluid_mode_ == 0 ? "GPU" : "CPU";
        tag_caption = new GUI_Tag (gui, 1, "fluid simulation ["+mode+"]", x, y, w, h);
        tag_caption.Label().setLabelAlign(LABEL_ALIGN.CENTER);
        tag_caption.InfoBox().setVisible(false);
        
        
        h = h_def_;
        y += h+gap_y_;
        td_frameRate = new GUI_TextDisplay (gui, 1, "textdisplay", x, y, w, h);
        td_frameRate.Label().setLabelAlign(LABEL_ALIGN.CENTER);
        td_frameRate.Border().setVisible(false);
        td_frameRate.setMethodNameToInvoke("guiCallFrameRate");
        td_frameRate.InfoBox().setLabel("framerate on CPU-Simulation\nGPU simulation is about 10 to 20 times faster" );
        td_frameRate.InfoBox().setFont(papplet_.createFont("Calibri", 12));
        td_frameRate.InfoBox().setPopupDelay(600);
        
        x = gpx_+offset_;
        y += h+gap_y_;
        w = gsx_-offset_*2;
        h = h_def_;
    
        b_reset_fluid = new GUI_Button (gui, 1, "RESET FLUID", x, y, w, h);
        b_reset_fluid.Label().setFont(gui_label_font);
        b_reset_fluid.Label().setLabelAlign(LABEL_ALIGN.CENTER);
        b_reset_fluid.InfoBox().setLabel("reset fluid" );
        b_reset_fluid.InfoBox().setFont(papplet_.createFont("Calibri", 12));
        b_reset_fluid.InfoBox().setPopupDelay(600);
        
        
        x = gpx_+offset_;
        y += h+gap_y_;
        w = h;
        cb_pause = new GUI_CheckBox (gui, 1, "pause", x, y, w, h);
        cb_pause.Label().setLabelAlign(LABEL_ALIGN.LEFT);
        cb_pause.Label().setPosXrel(w);   
        cb_pause.InfoBox().setLabel("pause simulation" );
        cb_pause.InfoBox().setFont(papplet_.createFont("Calibri", 12));
        cb_pause.InfoBox().setPopupDelay(600);
        
        x = gpx_+gsx_/2;
        w = h;
        h = h_def_;
        cb_smooth = new GUI_CheckBox (gui, 1, "smooth output", x, y, w, h);
        cb_smooth.Label().setLabelAlign(LABEL_ALIGN.LEFT);
        cb_smooth.Label().setPosXrel(w);   
        cb_smooth.InfoBox().setLabel("smooth the output map" );
        cb_smooth.InfoBox().setFont(papplet_.createFont("Calibri", 12));
        cb_smooth.InfoBox().setPopupDelay(600);
        
    
        
        
        
        
    
    
        
        
        
        x = gpx_+offset_;
        w = gsx_-offset_*2;
        x += 80;
        w -= 80;
        y += h+gap_y_*2;
        h = (int)(2.0*h_def_/3.0);
        sl_timestep = new GUI_Slider (gui, 1, "timestep", x, y, w, h);
        sl_timestep.Label().setLabelAlign(LABEL_ALIGN.LEFT);
        sl_timestep.Label().setPosXrel(-80);
        sl_timestep.setValue(20f);
        sl_timestep.setValueMin(0);
        sl_timestep.setValueMax(100);
        sl_timestep.setLabelPrecision(4);
        sl_timestep.LabelValue().setLabelAlign(LABEL_ALIGN.CENTER);    
        sl_timestep.setOrientation(SLIDER_ORIENTATION.HORIZONTAL);
        sl_timestep.Border().setVisible(false);
        sl_timestep.InfoBox().setLabel("change timestep" );
        sl_timestep.InfoBox().setFont(papplet_.createFont("Calibri", 12));
        sl_timestep.InfoBox().setPopupDelay(600);
        
        
        y += h+gap_y_/2.0;
        sl_viscosity = new GUI_Slider (gui, 1, "viscosity", x, y, w, h);
        sl_viscosity.Label().setLabelAlign(LABEL_ALIGN.LEFT);
        sl_viscosity.Label().setPosXrel(-80);
        sl_viscosity.setValue(0);
        sl_viscosity.setValueMin(0);
        sl_viscosity.setValueMax(100);
        sl_viscosity.setLabelPrecision(4);
        sl_viscosity.LabelValue().setLabelAlign(LABEL_ALIGN.CENTER);    
        sl_viscosity.setOrientation(SLIDER_ORIENTATION.HORIZONTAL);
        sl_viscosity.Border().setVisible(false);
        sl_viscosity.InfoBox().setLabel("change viscosity" );
        sl_viscosity.InfoBox().setFont(papplet_.createFont("Calibri", 12));
        sl_viscosity.InfoBox().setPopupDelay(600);
        
        y += h+gap_y_/2.0;
        sl_diffusion = new GUI_Slider (gui, 1, "diffusion", x, y, w, h);
        sl_diffusion.Label().setLabelAlign(LABEL_ALIGN.LEFT);
        sl_diffusion.Label().setPosXrel(-80);
        sl_diffusion.setValue(6);
        sl_diffusion.setValueMin(0);
        sl_diffusion.setValueMax(100);
        sl_diffusion.setLabelPrecision(4);
        sl_diffusion.LabelValue().setLabelAlign(LABEL_ALIGN.CENTER);    
        sl_diffusion.setOrientation(SLIDER_ORIENTATION.HORIZONTAL);
        sl_diffusion.Border().setVisible(false);
        sl_diffusion.InfoBox().setLabel("change diffusion" );
        sl_diffusion.InfoBox().setFont(papplet_.createFont("Calibri", 12));
        sl_diffusion.InfoBox().setPopupDelay(600);
        
        y += h+gap_y_/2.0;
        sl_vorticity = new GUI_Slider (gui, 1, "vorticity", x, y, w, h);
        sl_vorticity.Label().setLabelAlign(LABEL_ALIGN.LEFT);
        sl_vorticity.Label().setPosXrel(-80);
        sl_vorticity.setValue(20);
        sl_vorticity.setValueMin(0);
        sl_vorticity.setValueMax(100);
        sl_vorticity.setLabelPrecision(4);
        sl_vorticity.LabelValue().setLabelAlign(LABEL_ALIGN.CENTER);    
        sl_vorticity.setOrientation(SLIDER_ORIENTATION.HORIZONTAL);
        sl_vorticity.Border().setVisible(false);
        sl_vorticity.InfoBox().setLabel("change vorticity" );
        sl_vorticity.InfoBox().setFont(papplet_.createFont("Calibri", 12));
        sl_vorticity.InfoBox().setPopupDelay(600);
        
        
        y += h+gap_y_/2.0;
        sl_iterations1 = new GUI_Slider (gui, 1, "iterations1", x, y, w, h);
        sl_iterations1.Label().setLabelAlign(LABEL_ALIGN.LEFT);
        sl_iterations1.Label().setPosXrel(-80);
        sl_iterations1.setValue(8);
        sl_iterations1.setValueMin(1);
        sl_iterations1.setValueMax(20);
        sl_iterations1.setLabelPrecision(0);
        sl_iterations1.LabelValue().setLabelAlign(LABEL_ALIGN.CENTER);    
        sl_iterations1.setOrientation(SLIDER_ORIENTATION.HORIZONTAL);
        sl_iterations1.Border().setVisible(false);
        sl_iterations1.InfoBox().setLabel("to speedup the simulation\n take a smaller value" );
        sl_iterations1.InfoBox().setFont(papplet_.createFont("Calibri", 12));
        sl_iterations1.InfoBox().setPopupDelay(600);
        
        y += h+gap_y_/2.0;
        sl_iterations2 = new GUI_Slider (gui, 1, "iterations2", x, y, w, h);
        sl_iterations2.Label().setLabelAlign(LABEL_ALIGN.LEFT);
        sl_iterations2.Label().setPosXrel(-80);
        sl_iterations2.setValue(1);
        sl_iterations2.setValueMin(1);
        sl_iterations2.setValueMax(20);
        sl_iterations2.setLabelPrecision(0);
        sl_iterations2.LabelValue().setLabelAlign(LABEL_ALIGN.CENTER);    
        sl_iterations2.setOrientation(SLIDER_ORIENTATION.HORIZONTAL);
        sl_iterations2.Border().setVisible(false);
        sl_iterations2.InfoBox().setLabel("to speedup the simulation\n take a smaller value" );
        sl_iterations2.InfoBox().setFont(papplet_.createFont("Calibri", 12));
        sl_iterations2.InfoBox().setPopupDelay(600);
    
    
    
        
        x = gpx_+offset_;
        h = h_def_;
        w = h;
    
        y += h+gap_y_*2;
        cb_emitter1 = new GUI_CheckBox (gui, 1, "emitter[1] on/off", x, y, w, h);
        cb_emitter1.Label().setLabelAlign(LABEL_ALIGN.LEFT);
        cb_emitter1.Label().setPosXrel(w);   
        cb_emitter1.InfoBox().setVisible(false);
        
        y += h+gap_y_/2.0f;
        cb_emitter2 = new GUI_CheckBox (gui, 1, "emitter[2] on/off", x, y, w, h);
        cb_emitter2.Label().setLabelAlign(LABEL_ALIGN.LEFT);
        cb_emitter2.Label().setPosXrel(w);   
        cb_emitter2.InfoBox().setVisible(false);
        
        y += h+gap_y_/2.0f;
        cb_emitter3 = new GUI_CheckBox (gui, 1, "emitter[3] on/off", x, y, w, h);
        cb_emitter3.Label().setLabelAlign(LABEL_ALIGN.LEFT);
        cb_emitter3.Label().setPosXrel(w);   
        cb_emitter3.InfoBox().setVisible(false);
        
        y += h+gap_y_/2.0f;
        cb_emitter4 = new GUI_CheckBox (gui, 1, "emitter[4] on/off", x, y, w, h);
        cb_emitter4.Label().setLabelAlign(LABEL_ALIGN.LEFT);
        cb_emitter4.Label().setPosXrel(w);   
        cb_emitter4.InfoBox().setVisible(false);
        
    
    
    
    
    
    
        
    
    
        y += h+gap_y_*2;
        x = gpx_+offset_;
        h = h_def_;
        w = h;
        cb_addObstacles = new GUI_CheckBox (gui, 1, "add obstacles", x, y, w, h);
        cb_addObstacles.Label().setLabelAlign(LABEL_ALIGN.LEFT);
        cb_addObstacles.Label().setPosXrel(w);   
        cb_addObstacles.InfoBox().setLabel("use mouse LMB to add obstacles" );
        cb_addObstacles.InfoBox().setFont(papplet_.createFont("Calibri", 12));
        cb_addObstacles.InfoBox().setPopupDelay(600);
        
        x = gpx_+gsx_/2;
        w = gsx_/2-offset_;
        h = (int)(2.0*h_def_/3.0);
        sl_addObstacle_size = new GUI_Slider (gui, 1, "add obstacle", x, y, w, h);
        sl_addObstacle_size.Label().setLabelAlign(LABEL_ALIGN.LEFT);
        sl_addObstacle_size.Label().setPosXrel(-80);
        sl_addObstacle_size.Label().setVisible(false);
        sl_addObstacle_size.setValue(2);
        sl_addObstacle_size.setValueMin(1);
        sl_addObstacle_size.setValueMax(10);
        sl_addObstacle_size.setLabelPrecision(0);
        sl_addObstacle_size.LabelValue().setLabelAlign(LABEL_ALIGN.CENTER);    
        sl_addObstacle_size.setOrientation(SLIDER_ORIENTATION.HORIZONTAL);
        sl_addObstacle_size.Border().setVisible(false);
        sl_addObstacle_size.InfoBox().setLabel("set square size of obstacle" );
        sl_addObstacle_size.InfoBox().setFont(papplet_.createFont("Calibri", 12));
        sl_addObstacle_size.InfoBox().setPopupDelay(600);
        
        y += h_def_+gap_y_/2.0;
        x = gpx_+offset_;
        h = h_def_;
        w = h;
        cb_removeObstacles = new GUI_CheckBox (gui, 1, "remove obstacles", x, y, w, h);
        cb_removeObstacles.Label().setLabelAlign(LABEL_ALIGN.LEFT);
        cb_removeObstacles.Label().setPosXrel(w);   
        cb_removeObstacles.InfoBox().setLabel("use mouse LMB to remove obstacles" );
        cb_removeObstacles.InfoBox().setFont(papplet_.createFont("Calibri", 12));
        cb_removeObstacles.InfoBox().setPopupDelay(600);
        
        
        x = gpx_+gsx_/2;
        w = gsx_/2-offset_;
        h = (int)(2.0*h_def_/3.0);
        sl_removeObstacle_size = new GUI_Slider (gui, 1, "remove obstacle", x, y, w, h);
        sl_removeObstacle_size.Label().setLabelAlign(LABEL_ALIGN.LEFT);
        sl_removeObstacle_size.Label().setPosXrel(-80);
        sl_removeObstacle_size.Label().setVisible(false);
        sl_removeObstacle_size.setValue(2);
        sl_removeObstacle_size.setValueMin(1);
        sl_removeObstacle_size.setValueMax(10);
        sl_removeObstacle_size.setLabelPrecision(0);
        sl_removeObstacle_size.LabelValue().setLabelAlign(LABEL_ALIGN.CENTER);    
        sl_removeObstacle_size.setOrientation(SLIDER_ORIENTATION.HORIZONTAL);
        sl_removeObstacle_size.Border().setVisible(false);
        sl_removeObstacle_size.InfoBox().setLabel("set square size of obstacle" );
        sl_removeObstacle_size.InfoBox().setFont(papplet_.createFont("Calibri", 12));
        sl_removeObstacle_size.InfoBox().setPopupDelay(600);
        
        
        y += h_def_+gap_y_/2.0;
        x = gpx_+offset_;
        h = h_def_;
        w = h;
        cb_mouse_emit = new GUI_CheckBox (gui, 1, "mouse as emitter", x, y, w, h);
        cb_mouse_emit.Label().setLabelAlign(LABEL_ALIGN.LEFT);
        cb_mouse_emit.Label().setPosXrel(w);   
        cb_mouse_emit.InfoBox().setLabel("use mouse as emitter\nLMB + drag = density\nRBM + drag = velocity" );
        cb_mouse_emit.InfoBox().setFont(papplet_.createFont("Calibri", 12));
        cb_mouse_emit.InfoBox().setPopupDelay(600);
        
        
        
    
        x = gpx_+gsx_/2;
        w = gsx_/2-offset_;
        h = (int)(2.0*h_def_/3.0);
        sl_mouse_emit_size = new GUI_Slider (gui, 1, "mouse emitter size", x, y, w, h);
        sl_mouse_emit_size.Label().setLabelAlign(LABEL_ALIGN.LEFT);
        sl_mouse_emit_size.Label().setPosXrel(-80);
        sl_mouse_emit_size.Label().setVisible(false);
        sl_mouse_emit_size.setValue(5);
        sl_mouse_emit_size.setValueMin(1);
        sl_mouse_emit_size.setValueMax(10);
        sl_mouse_emit_size.setLabelPrecision(0);
        sl_mouse_emit_size.LabelValue().setLabelAlign(LABEL_ALIGN.CENTER);    
        sl_mouse_emit_size.setOrientation(SLIDER_ORIENTATION.HORIZONTAL);
        sl_mouse_emit_size.Border().setVisible(false);
        sl_mouse_emit_size.InfoBox().setLabel("set square size of obstacle" );
        sl_mouse_emit_size.InfoBox().setFont(papplet_.createFont("Calibri", 12));
        sl_mouse_emit_size.InfoBox().setPopupDelay(600);
        
        
        
        
        
        x = gpx_+offset_;
        w = gsx_-offset_*2;
        x += 80;
        w -= 80;
        y += h+gap_y_;
        h = (int)(2.0*h_def_/3.0);
        sl_mouse_red = new GUI_Slider (gui, 1, "mouse: red", x, y, w, h);
        sl_mouse_red.Label().setLabelAlign(LABEL_ALIGN.LEFT);
        sl_mouse_red.Label().setPosXrel(-80);
        sl_mouse_red.setValue(255);
        sl_mouse_red.setValueMin(0);
        sl_mouse_red.setValueMax(255);
        sl_mouse_red.setLabelPrecision(0);
        sl_mouse_red.LabelValue().setLabelAlign(LABEL_ALIGN.CENTER);    
        sl_mouse_red.setOrientation(SLIDER_ORIENTATION.HORIZONTAL);
        sl_mouse_red.Border().setVisible(false);
        sl_mouse_red.InfoBox().setLabel("red-value for mouse-emitter" );
        sl_mouse_red.InfoBox().setFont(papplet_.createFont("Calibri", 12));
        sl_mouse_red.InfoBox().setPopupDelay(600);
        
        
        y += h+gap_y_/2.0;
        sl_mouse_green = new GUI_Slider (gui, 1, "mouse: green", x, y, w, h);
        sl_mouse_green.Label().setLabelAlign(LABEL_ALIGN.LEFT);
        sl_mouse_green.Label().setPosXrel(-80);
        sl_mouse_green.setValue(120);
        sl_mouse_green.setValueMin(0);
        sl_mouse_green.setValueMax(255);
        sl_mouse_green.setLabelPrecision(0);
        sl_mouse_green.LabelValue().setLabelAlign(LABEL_ALIGN.CENTER);    
        sl_mouse_green.setOrientation(SLIDER_ORIENTATION.HORIZONTAL);
        sl_mouse_green.Border().setVisible(false);
        sl_mouse_green.InfoBox().setLabel("green-value for mouse-emitter" );
        sl_mouse_green.InfoBox().setFont(papplet_.createFont("Calibri", 12));
        sl_mouse_green.InfoBox().setPopupDelay(600);
        
        y += h+gap_y_/2.0;
        sl_mouse_blue = new GUI_Slider (gui, 1, "mouse: blue", x, y, w, h);
        sl_mouse_blue.Label().setLabelAlign(LABEL_ALIGN.LEFT);
        sl_mouse_blue.Label().setPosXrel(-80);
        sl_mouse_blue.setValue(0);
        sl_mouse_blue.setValueMin(0);
        sl_mouse_blue.setValueMax(255);
        sl_mouse_blue.setLabelPrecision(0);
        sl_mouse_blue.LabelValue().setLabelAlign(LABEL_ALIGN.CENTER);    
        sl_mouse_blue.setOrientation(SLIDER_ORIENTATION.HORIZONTAL);
        sl_mouse_blue.Border().setVisible(false);
        sl_mouse_blue.InfoBox().setLabel("blue-value for mouse-emitter" );
        sl_mouse_blue.InfoBox().setFont(papplet_.createFont("Calibri", 12));
        sl_mouse_blue.InfoBox().setPopupDelay(600);
    
    
    
    //    edit all gui-elements
        ArrayList<GUI_Element> elements = gui.getElements(); 
        for(int i = 0; i < elements.size(); i++){
          GUI_Element e = elements.get(i);
          e.Border().setVisible(false);
          e.InfoBox().setBaseColor   (Color.col(0,150));
          e.InfoBox().setBorderColor (Color.col(50));
          e.InfoBox().setLabelColor  (Color.col(200));
          e.Base().setVisible(true);
          e.Base().setColor(ELEMENT_STATUS.DEFAULT, Color.col(30));
          e.Base().setColor(ELEMENT_STATUS.FOCUSED, Color.col(40));
          e.Base().setColor(ELEMENT_STATUS.PRESSED, Color.col(90));
          if( e instanceof GUI_Slider)
            ((GUI_Slider)e).setSliderColor(color(120));
        }
        
        
    //    set a function to call automatically
        gui.MethodWrapper().addMethod("guiCallBackground");
       
      }
      
      
      public String guiCallFrameRate(){
        String str = String.format(Locale.ENGLISH, "fps: %3.2f\n", papplet_.frameRate);
        return str;
      }
      
      public void guiCallBackground(){
         int xp, yp;
         papplet_.fill(0);  papplet_.noStroke();
         papplet_.rect(gpx_, gpy_, gsx_, gsy_);
         papplet_.stroke(100); strokeWeight(3);
         papplet_.line(gpx_, gpy_, gsy_, gsy_);
         
         strokeWeight(1);
         
         xp = gpx_+offset_ ;
         
         yp = sl_timestep.Base().getPosY() - h_def_/2;
         papplet_.line(xp, yp, xp+gsx_-offset_*2, yp);
         
         yp = cb_emitter1.Base().getPosY() - h_def_/2;
         papplet_.line(xp, yp, xp+gsx_-offset_*2, yp);
         
    
         yp = cb_addObstacles.Base().getPosY() - h_def_/2;
         papplet_.line(xp, yp, xp+gsx_-offset_*2, yp);
        
      }
      
    }
    
    
    public String guiCallFrameRate(){
      return my_gui.guiCallFrameRate();
    }
    
    public void guiCallBackground(){
      my_gui.guiCallBackground();
    }
    
    
    //------------------------------------------------------------------------------
    //
    // author: thomas diewald
    // date: 27.07.2011
    //
    // basic fluid examples with gui controlls
    //
    // interaction: see GUI on right side of application
    // 
    //------------------------------------------------------------------------------
    
    //import processing.opengl.*;
    //import codeanticode.glgraphics.*;
    
    import diewald.p5gui.*;
    import diewald.p5gui.constants.*;
    import diewald.p5gui.utilities.Color;
    
    import diewald_fluid.Fluid2D;
    import diewald_fluid.Fluid2D_CPU;
    import diewald_fluid.Fluid2D_GPU;
    
    //------------------------------------------------------------------------------
    //------------------------------------------------------------------------------
    int  CPU_GPU        = 1; // 0 is GPU, 1 is CPU;
    //------------------------------------------------------------------------------
    //------------------------------------------------------------------------------
    
    
    int  fluid_size_x = 150; 
    int  fluid_size_y = 150;
    
    int  cell_size    = 4;
    int  window_size_x = fluid_size_x  * cell_size + (cell_size * 2);
    int  window_size_y = fluid_size_y  * cell_size + (cell_size * 2);
    
    
    int gui_size_x = 300;
    int gui_size_y = window_size_y;
    int gui_pos_x  = window_size_x;
    int gui_pos_y  = 0;
    
    Fluid2D fluid;
    PImage output_densityMap;
    
    
    
    GUI_CLASS my_gui;
    GUI_Event gui_event_;
    /////////////////////////////////////////////////////////////////////////////////////////////////////////////
    public void setup() {
      size(900, 600, JAVA2D); // for applet export
    //  if ( CPU_GPU == 0 ) size(window_size_x + gui_size_x, window_size_y, GLConstants.GLGRAPHICS);
    //  if ( CPU_GPU == 1 ) size(window_size_x + gui_size_x, window_size_y, JAVA2D);
      
    
      fluid = createFluidSolver(CPU_GPU);
    
      initGUI();
      frameRate(60);
    }
    
    
    
    /////////////////////////////////////////////////////////////////////////////////////////////////////////////
    public void draw() {
      background(0);
      
      
      
      // mouse influence
      if ( mousePressed && !my_gui.cb_pause.Status().isActive()) 
        fluidInfluence(fluid);
        
        
        
      // emitters on corners
      float speed = .25f;
      int off = 15;
      if( my_gui.cb_emitter1.Status().isActive() ){
        setVel (fluid,               off,               10, 2, 2, speed, speed);
        setDens(fluid,               off,               10, 3, 3, 1, 0, 0);
      }
      if( my_gui.cb_emitter2.Status().isActive() ){
        setVel (fluid, window_size_x-off,               10, 2, 2, -speed, speed);
        setDens(fluid, window_size_x-off,               10, 3, 3, 1, 1, 1);
      }
      if( my_gui.cb_emitter3.Status().isActive() ){
        setVel (fluid, window_size_x-off, window_size_y-10, 2, 2, -speed, -speed);
        setDens(fluid, window_size_x-off, window_size_y-10, 3, 3, 0, 0, 1);
      }
      if( my_gui.cb_emitter4.Status().isActive() ){
        setVel (fluid,               off, window_size_y-10, 2, 2, speed, -speed);
        setDens(fluid,               off, window_size_y-10, 3, 3, 0, 1, 0);
      }
      
    
    
      // fluid parameters
      fluid.setParam_Timestep          (       my_gui.sl_timestep   .getValue() *.005 );
      fluid.setParam_Iterations        ( (int) my_gui.sl_iterations1.getValue() );
      fluid.setParam_IterationsDiffuse ( (int) my_gui.sl_iterations2.getValue() );
      fluid.setParam_Viscosity         (       my_gui.sl_viscosity  .getValue() * .0000005 );
      fluid.setParam_Diffusion         (       my_gui.sl_diffusion  .getValue() * .00000005 );
      fluid.setParam_Vorticity         (       my_gui.sl_vorticity  .getValue() * .1  );
      
    
      fluid.processViscosity   ( (my_gui.sl_viscosity.getValue() > 1) );
      fluid.processDiffusion   ( (my_gui.sl_diffusion.getValue() > 1) );
      fluid.processVorticity   ( (my_gui.sl_vorticity.getValue() > 1) );
      
      
      // smooth output
      fluid.smoothDensityMap(my_gui.cb_smooth.Status().isActive());
      
      // simulate next step
      if( !my_gui.cb_pause.Status().isActive() ){
        fluid.update();
      }
      
      // visualize
      image(fluid.getDensityMap(), 0, 0);
    //println(frameRate);
    
    }
    
    
    
    
    /////////////////////////////////////////////////////////////////////////////////////////////////////////////
    public void keyPressed() {
      if( online && key == ESC) key = 0;
    }
    
    
    
    
    
    
    /////////////////////////////////////////////////////////////////////////////////////////////////////////////
    // createFluidSolver();
    //
    Fluid2D createFluidSolver(int type) {
      Fluid2D fluid_tmp = null;
      
      if ( type == 0) fluid_tmp = new Fluid2D_GPU(this, fluid_size_x, fluid_size_y);
      if ( type == 1) fluid_tmp = new Fluid2D_CPU(this, fluid_size_x, fluid_size_y);
    
      fluid_tmp.setParam_Timestep  ( 0.10f );
      fluid_tmp.setParam_Iterations( 8 );
      fluid_tmp.setParam_IterationsDiffuse(1);
      fluid_tmp.setParam_Viscosity ( 0.00000000f );
      fluid_tmp.setParam_Diffusion ( 0.000001f );
      fluid_tmp.setParam_Vorticity ( 2.0f );
      fluid_tmp.processDensityMap  ( true );
      fluid_tmp.processDiffusion   ( true );
      fluid_tmp.processViscosity   ( true );
      fluid_tmp.processVorticity   ( true );
      fluid_tmp.setObjectsColor    (1, 1, 1, 1); 
      
      output_densityMap    = createImage(window_size_x, window_size_y, RGB);
      fluid_tmp.setDensityMap(output_densityMap);
      return fluid_tmp;
    }
    
    
    
    
    /////////////////////////////////////////////////////////////////////////////////////////////////////////////
    // fluidInfluence();
    //
    public void fluidInfluence( Fluid2D fluid2d ) {
      
      if (mouseButton == LEFT ){
        if( my_gui.cb_mouse_emit.Status().isActive() ){
          int size =  (int)my_gui.sl_mouse_emit_size.getValue();
          float r  =  my_gui.sl_mouse_red.getValue() /255f;
          float g  =  my_gui.sl_mouse_green.getValue() /255f;
          float b  =  my_gui.sl_mouse_blue.getValue() /255f;
    
          setDens(fluid2d, mouseX, mouseY, size, size, r, g, b);
        }
        if( my_gui.cb_addObstacles.Status().isActive() ){
          int size = (int)my_gui.sl_addObstacle_size.getValue();
          int xpos = (int)(mouseX/(float)cell_size) - size/2;
          int ypos = (int)(mouseY/(float)cell_size) - size/2;
          addObject(fluid2d, xpos, ypos, size, size, 0);
        }
        if( my_gui.cb_removeObstacles.Status().isActive() ){
          int size = (int)my_gui.sl_removeObstacle_size.getValue();
          int xpos = (int)(mouseX/(float)cell_size) - size/2;
          int ypos = (int)(mouseY/(float)cell_size) - size/2;
          addObject(fluid2d, xpos, ypos, size, size, 1);
        }
      }
      
      if (mouseButton == RIGHT ) {
        float vel_fac = 0.13f;
        int size = (int)(((fluid_size_x+fluid_size_y)/2.0) / 50.0);
        size = max(size, 1);
        setVel(fluid2d, mouseX, mouseY, size, size, (mouseX - pmouseX)*vel_fac, (mouseY - pmouseY)*vel_fac);
      }
    }    
    
    
    /////////////////////////////////////////////////////////////////////////////////////////////////////////////
    // setDens();
    //
    void setDens(Fluid2D fluid2d, int x, int y, int sizex, int sizey, float r, float g, float b) {
      for (int y1 = 0; y1 < sizey; y1++) {
        for (int x1 = 0; x1 < sizex; x1++) {
          int xpos = (int)(x/(float)cell_size) + x1 - sizex/2;
          int ypos = (int)(y/(float)cell_size) + y1 - sizey/2;
          fluid2d.addDensity(0, xpos, ypos, r);
          fluid2d.addDensity(1, xpos, ypos, g);
          fluid2d.addDensity(2, xpos, ypos, b);
        }
      }
    }
    
    
    /////////////////////////////////////////////////////////////////////////////////////////////////////////////
    // setVel();
    //
    void setVel(Fluid2D fluid2d, int x, int y, int sizex, int sizey, float velx, float vely) {
      for (int y1 = 0; y1 < sizey; y1++) {
        for (int x1 = 0; x1 < sizex; x1++) {
          int xpos = (int)((x/(float)cell_size)) + x1 - sizex/2;
          int ypos = (int)((y/(float)cell_size)) + y1 - sizey/2;
          fluid2d.addVelocity(xpos, ypos, velx, vely);
        }
      }
    }
    
    
    /////////////////////////////////////////////////////////////////////////////////////////////////////////////
    // addObject();
    //
    public void addObject(Fluid2D fluid2d, int posx, int posy, int sizex, int sizey, int mode) {
      int offset = 0;
      int xlow = posx;
      int xhig = posx + sizex;
      int ylow = posy;
      int yhig = posy + sizey;
    
      for (int x = xlow-offset ; x < xhig+offset ; x++) {
        for (int y = ylow-offset ; y < yhig+offset ; y++) {
          if ( x < 0 || x >= fluid2d.getSizeXTotal() || y < 0 || y >= fluid2d.getSizeYTotal() )
            continue;
          if ( mode == 0) fluid2d.addObject(x, y);
          if ( mode == 1) fluid2d.removeObject(x, y); 
        }
      }
    }
    
    

    code

    tweaks (0)

    about this sketch

    This sketch is running as Java applet, exported from Processing.

    license

    advertisement

    Thomas Diewald

    fluid simulation

    Add to Faves Me Likey@! 31
    You must login/register to add this sketch to your favorites.

    this is a demo of the fluid-library (diewald_fluid) i was working on the last view days.
    the simulation can either be done on the CPU or on the GPU (which is about 10 to 20 times faster).
    this demo shows the CPU version, since the GPU version wont work online.

    use RMB to steer around in the fluid

    DOWNLOAD: Processing Library – Fluid Simulation
    http://thomasdiewald.com/blog/?p=95

    Henderson
    27 Jul 2011
    Excellent! :)
    bejoscha
    8 Aug 2011
    Very good!
    jacques maire
    13 Feb 2012
    J'aime beaucoup ce travail!
    most fun!
    Martin Wood
    17 Sep 2012
    nice - good executive toy :)
    You need to login/register to comment.