Pixelflow GetStart(二)
程序员文章站
2022-04-27 13:20:31
...
import com.thomasdiewald.pixelflow.java.DwPixelFlow;
import com.thomasdiewald.pixelflow.java.fluid.DwFluid2D;
import com.thomasdiewald.pixelflow.java.fluid.DwFluidParticleSystem2D;
private class MyFluidData implements DwFluid2D.FluidData {
@Override
// this is called during the fluid-simulation update step.
public void update(DwFluid2D fluid) {
float px, py, vx, vy, radius, vscale, temperature;
boolean mouse_input =mousePressed;
if (mouse_input ) {
vscale = 15;
px = mouseX;
py = height-mouseY;
vx = (mouseX - pmouseX) * +vscale;
vy = (mouseY - pmouseY) * -vscale;
if (mouseButton == LEFT) {
radius = 20;
fluid.addVelocity(px, py, radius, vx, vy);
}
if (mouseButton == CENTER) {
radius = 20;
fluid.addVelocity(px, py, radius, vx, vy);
fluid.addDensity (px, py, 8, 1, 1, 1, 1f, 1);
}
if (mouseButton == RIGHT) {
radius = 15;
fluid.addTemperature(px, py, radius, 1f);
}
}
temperature = 0.5f;
vscale = 15;
px = width/4 * 3-0;
py = 0;
radius = 100;
fluid.addDensity (px, py, radius, 1.0f, 0.0f, 0.40f, 1f, 1);
radius = 100;
fluid.addTemperature(px, py, radius, temperature); // 扩散方向
px = width/4+0;
py = 0;
radius = 100;
fluid.addDensity (px, py, radius, 0.00f, 0.40f, 1, 1f, 1);
radius = 100;
fluid.addTemperature(px, py, radius, -temperature);
}
}
int viewport_w = 1280;
int viewport_h = 720;
int viewport_x = 230;
int viewport_y = 0;
int fluidgrid_scale = 1;
DwFluid2D fluid;
MyFluidData cb_fluid_data;
// default particle system
DwFluidParticleSystem2D particle_system;
// fluid rendertarget
PGraphics2D pg_fluid;
//texture-buffer, for adding obstacles
PGraphics2D pg_obstacles;
// some state variables for the GUI/display
int BACKGROUND_COLOR = 0;
boolean UPDATE_FLUID = true;
boolean DISPLAY_FLUID_TEXTURES = true;
boolean DISPLAY_FLUID_VECTORS = false;
int DISPLAY_fluid_texture_mode = 0;
boolean DISPLAY_PARTICLES = false;
public void settings() {
size(viewport_w, viewport_h, P2D);
smooth(4); //绘制所有具有平滑(抗锯齿)边缘的几何图形
}
public void setup() {
surface.setLocation(viewport_x, viewport_y); // 设置草图 即是显示窗口相对于屏幕的位置
// main library context
DwPixelFlow context = new DwPixelFlow(this);
context.print();
context.printGL();
// fluid simulation
fluid = new DwFluid2D(context, viewport_w, viewport_h, fluidgrid_scale);
fluid.param.dissipation_density = 0.99f;
fluid.param.dissipation_velocity = 0.85f;
fluid.param.dissipation_temperature = 0.99f;
fluid.param.vorticity = 0.00f;
fluid.param.timestep = 0.25f;
fluid.param.num_jacobi_projection = 80;
// interface for adding data to the fluid simulation
cb_fluid_data = new MyFluidData();
fluid.addCallback_FluiData(cb_fluid_data);
// fluid render target
pg_fluid = (PGraphics2D) createGraphics(viewport_w, viewport_h, P2D);
pg_fluid.smooth(4);
//创建并返回一个新的PGraphics对象。如果需要绘制屏幕外图形缓冲区,请使用此类。
pg_obstacles = (PGraphics2D) createGraphics(viewport_w, viewport_h, P2D);
pg_obstacles.smooth(4);
pg_obstacles.beginDraw();
pg_obstacles.clear();
pg_obstacles.rectMode(CENTER);
pg_obstacles.fill(64);
pg_obstacles.noStroke();
pg_obstacles.translate(0, height/2);
pg_obstacles.rect( 0, -180, 80, 80);
pg_obstacles.rect(-30, +200, 50, 50);
pg_obstacles.rect(+30, +200, 50, 50);
pg_obstacles.ellipse( 0, -180, 80, 80);
pg_obstacles.ellipse(-30, +200, 50, 50);
pg_obstacles.ellipse(+30, +200, 50, 50);
pg_obstacles.endDraw();
// particles
particle_system = new DwFluidParticleSystem2D();
particle_system.resize(context, viewport_w/3, viewport_h/3);
background(0);
frameRate(60);
}
public void draw() {
if (UPDATE_FLUID) {
fluid.addObstacles(pg_obstacles);
fluid.update();
particle_system.update(fluid);
}
pg_fluid.beginDraw();
pg_fluid.background(BACKGROUND_COLOR);
pg_fluid.endDraw();
if (DISPLAY_FLUID_TEXTURES) {
fluid.renderFluidTextures(pg_fluid, DISPLAY_fluid_texture_mode);
}
if (DISPLAY_FLUID_VECTORS) {
fluid.renderFluidVectors(pg_fluid, 10);
}
if (DISPLAY_PARTICLES) {
particle_system.render(pg_fluid, null, 0);
}
// display
image(pg_fluid, 0, 0);
image(pg_obstacles, 0, 0);
// info
String txt_fps = String.format(getClass().getName()+ " [size %d/%d] [frame %d] [fps %6.2f]", fluid.fluid_w, fluid.fluid_h, fluid.simulation_step, frameRate);
surface.setTitle(txt_fps);
}
public void fluid_resizeUp() {
fluid.resize(width, height, fluidgrid_scale = max(1, --fluidgrid_scale));
}
public void fluid_resizeDown() {
fluid.resize(width, height, ++fluidgrid_scale);
}
public void fluid_reset() {
fluid.reset();
}
public void fluid_togglePause() {
UPDATE_FLUID = !UPDATE_FLUID;
}
public void fluid_displayMode(int val) {
DISPLAY_fluid_texture_mode = val;
DISPLAY_FLUID_TEXTURES = DISPLAY_fluid_texture_mode != -1;
}
public void fluid_displayVelocityVectors(int val) {
DISPLAY_FLUID_VECTORS = val != -1;
}
public void fluid_displayParticles(int val) {
DISPLAY_PARTICLES = val != -1;
}
public void keyReleased() {
if (key == 'p') fluid_togglePause(); // pause / unpause simulation
if (key == '+') fluid_resizeUp(); // increase fluid-grid resolution
if (key == '-') fluid_resizeDown(); // decrease fluid-grid resolution
if (key == 'r') fluid_reset(); // restart simulation
if (key == '1') DISPLAY_fluid_texture_mode = 0; // density
if (key == '2') DISPLAY_fluid_texture_mode = 1; // temperature
if (key == '3') DISPLAY_fluid_texture_mode = 2; // pressure
if (key == '4') DISPLAY_fluid_texture_mode = 3; // velocity
if (key == 'q') DISPLAY_FLUID_TEXTURES = !DISPLAY_FLUID_TEXTURES;
if (key == 'w') DISPLAY_FLUID_VECTORS = !DISPLAY_FLUID_VECTORS;
}