-
Notifications
You must be signed in to change notification settings - Fork 0
/
main.py
152 lines (112 loc) · 4 KB
/
main.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
import pyglet
import imgui
from imgui.integrations.pyglet import PygletProgrammablePipelineRenderer
from glumpy import app
# our modules
from modules import fluid
# Use pyglet as backend
# using opengl 4.3
app.use("pyglet", major=4, minor=3)
# Constants
WIDTH = 900
HEIGHT = 900
CELLS = 128
# create window with openGL context
window = app.Window(WIDTH, HEIGHT)
# create renderer of imgui on window
imgui.create_context()
imgui_renderer = PygletProgrammablePipelineRenderer(window.native_window) # pass native pyglet window.
fps_display = pyglet.window.FPSDisplay(window=window.native_window)
# main object
smoke_grid = fluid.Fluid(WIDTH, HEIGHT, CELLS)
# draw only lines, no rasterization, good for tests
# gl.glPolygonMode(gl.GL_FRONT_AND_BACK, gl.GL_LINE)
# dt default value avoids exception error
@window.event
def on_draw(dt=0):
window.clear()
smoke_grid.update_fields()
smoke_grid.solve_fields(dt)
# draw smoke first
smoke_grid.draw()
if smoke_grid.show_fps:
fps_display.draw()
# Imgui Interface
imgui.new_frame()
imgui.begin("Controls")
_, smoke_grid.show_grid = imgui.checkbox("Show Grid", smoke_grid.show_grid)
_, smoke_grid.show_vectors = imgui.checkbox("Show Vectors", smoke_grid.show_vectors)
_, smoke_grid.show_fps = imgui.checkbox("Show FPS", smoke_grid.show_fps)
changed, smoke_grid.smoke_color = imgui.color_edit3("Smoke Color", *smoke_grid.smoke_color)
if changed:
smoke_grid.update_smoke_color()
changed, vm = imgui.drag_float3("View Matrix", *smoke_grid.view_matrix, change_speed=0.01)
smoke_grid.view_matrix = list(vm)
if changed:
smoke_grid.update_view_matrix()
imgui.end()
# render gui on top of everything
try:
imgui.render()
imgui_renderer.render(imgui.get_draw_data())
except Exception:
imgui_renderer.shutdown()
@window.event
def on_mouse_drag(x, y, dx, dy, buttons):
"""The mouse was moved with some buttons pressed."""
# if mouse is on imgui window dont capture input
if imgui.get_io().want_capture_mouse:
return
# Case was right mouse button
if buttons == 4:
radius = 3
# will be inverted in opengl
idrow = CELLS - (int(y/smoke_grid.dx) + 1)
idcol = int(x/smoke_grid.dy) + 1
if idrow-radius < 0:
idrow = radius
elif idrow+radius > CELLS-1:
idrow = CELLS-1-radius
if idcol-radius < 0:
idcol = radius
elif idcol+radius > CELLS-1:
idcol = CELLS-1-radius
for i in range(-radius, radius):
idx = idrow + i
for j in range(-radius, radius):
idy = idcol + j
smoke_grid.density_field[idx, idy] = 1
# Case was left mouse button
if buttons == 1:
radius = 2
idrow = CELLS - (int(y/smoke_grid.dx))
idcol = int(x/smoke_grid.dy)
if idrow-radius < 0:
idrow = radius
elif idrow+radius > CELLS-1:
idrow = CELLS-1-radius
if idcol-radius < 0:
idcol = radius
elif idcol+radius > CELLS-1:
idcol = CELLS-1-radius
for i in range(-radius, radius):
idx = idrow + i
for j in range(-radius, radius):
idy = idcol + j
speed = 1000
smoke_grid.velocity_field[idx, idy] += [
speed*dx, speed*dy
]
@window.event
def on_show():
# disable resize on show
window.native_window.set_minimum_size(WIDTH, HEIGHT)
window.native_window.set_maximum_size(WIDTH, HEIGHT)
@window.event
def on_mouse_scroll(x, y, dx, dy):
'The mouse wheel was scrolled by (dx,dy).'
smoke_grid.view_matrix[-1] -= dy*0.1
smoke_grid.update_view_matrix()
if __name__ == "__main__":
# run app
app.run()