def add_particles(self, position: tuple, radius: float, strength: float): if self.simulate: self._init_compute_kernels() bgfx.setUniform( self.position_uniform, as_void_ptr((c_float * 2)(position[0], position[1])), ) bgfx.setUniform(self.value_uniform, as_void_ptr((c_float * 1)(strength))) bgfx.setUniform(self.radius_uniform, as_void_ptr((c_float * 1)(radius))) bgfx.dispatch(0, self._add_particles_kernel, self._num_groups_x, self._num_groups_x, 1) self._flip_buffer()
def update(self, dt): mouse_x, mouse_y, buttons_states = self.get_mouse_state() ImGuiExtra.imguiBeginFrame( int(mouse_x), int(mouse_y), buttons_states, 0, self.fb_width, self.fb_height ) show_properties_dialog(self.fluid_simulator, self.particle_area, self.hidpi) ImGuiExtra.imguiEndFrame() vel_y = random.uniform(-0.08, 0.08) vel_x = random.uniform(-0.01, 0.1) strength = random.uniform(0.01, 0.09) at = (c_float * 3)(*[0.0, 0.0, 0.0]) eye = (c_float * 3)(*[0.0, 0.0, 10.0]) up = (c_float * 3)(*[0.0, 1.0, 0.0]) view = look_at(eye, at, up) projection = proj(11.4, 1, 0.1, 100.0) bgfx.setViewRect(0, 0, 0, self.fb_width, self.fb_height) bgfx.setViewTransform(0, as_void_ptr(view), as_void_ptr(projection)) bgfx.setVertexBuffer(0, self.vertex_buffer, 0, 4) bgfx.setIndexBuffer(self.index_buffer, 0, cube_indices.size) bgfx.setState(BGFX_STATE_DEFAULT) bgfx.setImage(0, self.output_texture, 0, bgfx.Access.Write) self.fluid_simulator.add_velocity((0.23, 0.5), (vel_x, vel_y), 34.0) self.fluid_simulator.add_circle_obstacle((0.5, 0.7), 30.0) self.fluid_simulator.add_triangle_obstacle( (0.65, 0.5), (0.42, 0.5), (0.42, 0.39) ) self.fluid_simulator.add_triangle_obstacle( (0.65, 0.06), (0.65, 0.39), (0.42, 0.39) ) self.fluid_simulator.update(dt) self.particle_area.add_particles((0.2, 0.5), 220.0, strength) self.particle_area.update(dt) bgfx.dispatch(0, self.cs_program, self.fb_width // 16, self.fb_height // 16) bgfx.setTexture(0, self.texture_uniform, self.output_texture) bgfx.setState(BGFX_STATE_WRITE_RGB | BGFX_STATE_WRITE_A) bgfx.submit(0, self.main_program, 0, False) bgfx.frame()
def add_velocity(self, position: tuple, velocity: tuple, radius: float): if self.simulate: self._init_compute_kernels() bgfx.setUniform( self.position_uniform, as_void_ptr((c_float * 2)(position[0], position[1])), ) bgfx.setUniform( self.value_uniform, as_void_ptr((c_float * 2)(velocity[0], velocity[1])) ) bgfx.setUniform(self.radius_uniform, as_void_ptr((c_float * 1)(radius))) bgfx.dispatch( 0, self._add_velocity_kernel, self._num_groups_x, self._num_groups_y, 1 ) self._flip_velocity_buffer()
def add_triangle_obstacle(self, p1: tuple, p2: tuple, p3: tuple, static=False): if self.simulate: self._init_compute_kernels() bgfx.setUniform(self.p1_uniform, as_void_ptr((c_float * 2)(p1[0], p1[1]))) bgfx.setUniform(self.p2_uniform, as_void_ptr((c_float * 2)(p2[0], p2[1]))) bgfx.setUniform(self.p3_uniform, as_void_ptr((c_float * 2)(p3[0], p3[1]))) bgfx.setUniform( self.static_uniform, as_void_ptr((c_float * 1)(1.0 if static else 0.0)) ) bgfx.dispatch( 0, self._add_triangle_obstacle_kernel, self._num_groups_x, self._num_groups_y, 1, )
def add_circle_obstacle(self, position: tuple, radius: float, static=False): if self.simulate: self._init_compute_kernels() bgfx.setUniform( self.position_uniform, as_void_ptr((c_float * 2)(position[0], position[1])), ) bgfx.setUniform(self.radius_uniform, as_void_ptr((c_float * 1)(radius))) bgfx.setUniform( self.static_uniform, as_void_ptr((c_float * 1)(1.0 if static else 0.0)) ) bgfx.dispatch( 0, self._add_circle_obstacle_kernel, self._num_groups_x, self._num_groups_y, 1, )
def update(self, time_delta: float): self._init_compute_kernels() if self.simulate: bgfx.setUniform(self.dissipation_uniform, as_void_ptr((c_float * 1)(self.dissipation))) bgfx.setUniform(self.elapsed_time_uniform, as_void_ptr((c_float * 1)(time_delta))) bgfx.setUniform(self.speed_uniform, as_void_ptr((c_float * 1)(self.speed))) bgfx.dispatch( 0, self._advect_particles_kernel, self._num_groups_x, self._num_groups_y, 1, ) self._flip_buffer()
def update(self, time_delta: float): if self.simulate: self._init_compute_kernels() self._update_params(time_delta) # Init boundaries if self.has_borders: bgfx.dispatch( 0, self._init_boundaries_kernel, self._num_groups_x, self._num_groups_y, 1, ) # Advect bgfx.dispatch( 0, self._advect_velocity_kernel, self._num_groups_x, self._num_groups_y, 1, ) self._flip_velocity_buffer() # Vorticity confinement 1 - Calculate vorticity bgfx.dispatch( 0, self._calc_vorticity_kernel, self._num_groups_x, self._num_groups_y, 1, ) # Vorticity confinement 2 - Apply vorticity force bgfx.dispatch( 0, self._apply_vorticity_kernel, self._num_groups_x, self._num_groups_y, 1, ) self._flip_velocity_buffer() # Viscosity if self.viscosity > 0.0: for _ in range(self.iterations): bgfx.dispatch( 0, self._viscosity_kernel, self._num_groups_x, self._num_groups_y, 1, ) self._flip_velocity_buffer() # Divergence bgfx.dispatch( 0, self._divergence_kernel, self._num_groups_x, self._num_groups_y, 1 ) # Clear pressure bgfx.setBuffer( TemplateConstants.GENERIC.value, self._pressure_buffer[self.PRESSURE_READ], bgfx.Access.ReadWrite, ) bgfx.dispatch( 0, self._clear_buffer_kernel, self._num_groups_x, self._num_groups_y, 1 ) bgfx.setBuffer( TemplateConstants.PRESSURE_IN.value, self._pressure_buffer[self.PRESSURE_READ], bgfx.Access.Read, ) # Poisson for _ in range(self.iterations): bgfx.dispatch( 0, self._poisson_kernel, self._num_groups_x, self._num_groups_y, 1 ) self._flip_pressure_buffer() # Subtract gradient bgfx.dispatch( 0, self._subtract_gradient_kernel, self._num_groups_x, self._num_groups_y, 1, ) self._flip_velocity_buffer() # Clear obstacles bgfx.setBuffer( TemplateConstants.GENERIC.value, self._obstacles_buffer, bgfx.Access.ReadWrite, ) bgfx.dispatch( 0, self._clear_buffer_kernel, self._num_groups_x, self._num_groups_y, 1 ) bgfx.setBuffer( TemplateConstants.OBSTACLES.value, self._obstacles_buffer, bgfx.Access.ReadWrite, )