|
1 |
| -""" |
| 1 | +''' |
2 | 2 |
|
3 | 3 | Demo of the MSAFluid library (www.memo.tv/msafluid_for_processing)
|
4 | 4 | Move mouse to add dye and forces to the fluid.
|
5 |
| - Click mouse to turn off fluid rendering seeing only particles and their paths. |
| 5 | + LEFT mouse turns off fluid rendering, showing only particles and paths. |
| 6 | + RIGHT mouse turns off particles, showing only fluid rendering. |
6 | 7 | Demonstrates feeding input into the fluid and reading data back (to update
|
7 | 8 | the particles).
|
8 |
| - Also demonstrates using Vertex Arrays for particle rendering. |
9 |
| - Port to processing.py and Superfast Blur added |
10 |
| - (http://incubator.quasimondo.com/processing/superfast_blur.php) |
11 |
| - by Ben Alkov, 2014. |
| 9 | + Port to processing.py by Ben Alkov, 2014. |
12 | 10 |
|
13 |
| -""" |
| 11 | +''' |
14 | 12 | # * Copyright (c) 2008, 2009, Memo Akten, www.memo.tv
|
15 | 13 | # * *** The Mega Super Awesome Visuals Company ***
|
16 | 14 | # * All rights reserved.
|
|
42 | 40 | # * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
43 | 41 |
|
44 | 42 | add_library('MSAFluid')
|
45 |
| -# from processing.opengl import * |
46 |
| -# from javax.media.opengl import * |
47 | 43 | from particle_system import ParticleSystem
|
48 | 44 |
|
49 | 45 | FLUID_WIDTH = 120
|
50 | 46 | invWidth = 0
|
51 | 47 | invHeight = 0
|
52 | 48 | fluidSolver = None
|
53 | 49 | particleSystem = None
|
54 |
| -drawFluid = False |
| 50 | +drawFluid = True |
| 51 | +drawSparks = True |
55 | 52 | imgFluid = None
|
56 | 53 | aspectRatio = 0
|
57 | 54 |
|
58 | 55 |
|
59 | 56 | def setup():
|
60 |
| - size(960, 640, P3D) |
| 57 | + size(784, 484, OPENGL) |
61 | 58 | invWidth = 1.0 / width
|
62 | 59 | invHeight = 1.0 / height
|
63 | 60 | aspectRatio = (width * invHeight) ** 2
|
@@ -89,14 +86,18 @@ def draw():
|
89 | 86 | imgFluid.pixels[i] = color(fluidSolver.r[i] * 2,
|
90 | 87 | fluidSolver.g[i] * 2,
|
91 | 88 | fluidSolver.b[i] * 2)
|
92 |
| - # imgFluid.pixels = fastBlur(imgFluid, 2) |
93 | 89 | imgFluid.updatePixels()
|
94 | 90 | image(imgFluid, 0, 0, width, height)
|
95 |
| - particleSystem.updateAndDraw(invWidth, invHeight, drawFluid) |
| 91 | + if drawSparks: |
| 92 | + particleSystem.updateAndDraw(invWidth, invHeight, |
| 93 | + drawFluid, fluidSolver) |
96 | 94 |
|
97 | 95 |
|
98 | 96 | def mousePressed():
|
99 |
| - drawFluid = not drawFluid |
| 97 | + if mouseButton == LEFT: |
| 98 | + drawFluid = not drawFluid |
| 99 | + elif mouseButton == RIGHT: |
| 100 | + drawSparks = not drawSparks |
100 | 101 |
|
101 | 102 |
|
102 | 103 | # Add force and dye to fluid, and create particles.
|
@@ -127,70 +128,3 @@ def addForce(x, y, dx, dy):
|
127 | 128 | particleSystem.addParticles(x * width, y * height, 10)
|
128 | 129 | fluidSolver.uOld[index] += dx * velocityMult
|
129 | 130 | fluidSolver.vOld[index] += dy * velocityMult
|
130 |
| - |
131 |
| - |
132 |
| -def fastBlur(image, radius): |
133 |
| - # Super Fast Blur v1.1 |
134 |
| - # by Mario Klingemann <http://incubator.quasimondo.com> |
135 |
| - # |
136 |
| - # Tip: Multiple invovations of this filter with a small |
137 |
| - # radius will approximate a gaussian blur quite well. |
138 |
| - pix = image.pixels |
139 |
| - if radius < 1: |
140 |
| - return |
141 |
| - divisor = radius * 2 + 1 |
142 |
| - divisors = [i / divisor for i in range(256 * divisor)] |
143 |
| - imgWidth = image.width |
144 |
| - imgHeight = image.height |
145 |
| - widthMinus = imgWidth - 1 |
146 |
| - heightMinus = imgHeight - 1 |
147 |
| - plane = [i for i in range(imgWidth * imgHeight)] |
148 |
| - redPlane, greenPlane, bluePlane = plane, plane, plane |
149 |
| - vsize = max(imgWidth, imgHeight) |
150 |
| - vmin = [i for i in range(vsize)] |
151 |
| - vmax = vmin |
152 |
| - yWidth, yIndex = 0, 0 |
153 |
| - |
154 |
| - for y in range(imgHeight): |
155 |
| - rsum, gsum, bsum = 0, 0, 0 |
156 |
| - for i in range(-radius, radius + 1): |
157 |
| - pixel = pix[yIndex + min(widthMinus, max(i, 0))] |
158 |
| - rsum += (pixel & 0xff0000) >> 16 |
159 |
| - gsum += (pixel & 0x00f00) >> 8 |
160 |
| - bsum += pixel & 0x0000f |
161 |
| - for x in range(imgWidth): |
162 |
| - redPlane[yIndex] = divisors[rsum] |
163 |
| - greenPlane[yIndex] = divisors[gsum] |
164 |
| - bluePlane[yIndex] = divisors[bsum] |
165 |
| - if y == 0: |
166 |
| - vmin[x] = min(x + radius + 1, widthMinus) |
167 |
| - vmax[x] = max(x - radius, 0) |
168 |
| - pixel1 = pix[yWidth + vmin[x]] |
169 |
| - pixel2 = pix[yWidth + vmax[x]] |
170 |
| - rsum += ((pixel1 & 0xff0000) - (pixel2 & 0xff0000)) >> 16 |
171 |
| - gsum += ((pixel1 & 0x00f00) - (pixel2 & 0x00f00)) >> 8 |
172 |
| - bsum += (pixel1 & 0x0000f) - (pixel2 & 0x0000f) |
173 |
| - yIndex += 1 |
174 |
| - yWidth += imgWidth |
175 |
| - for x in range(imgWidth): |
176 |
| - rsum, gsum, bsum = 0, 0, 0 |
177 |
| - yPointer = -radius * imgWidth |
178 |
| - for i in range(-radius, radius + 1): |
179 |
| - yIndex = max(0, yPointer) + x |
180 |
| - rsum += redPlane[yIndex] |
181 |
| - gsum += greenPlane[yIndex] |
182 |
| - bsum += bluePlane[yIndex] |
183 |
| - yPointer += imgWidth |
184 |
| - yIndex = x |
185 |
| - for y in range(imgHeight): |
186 |
| - pix[yIndex] = 0xff000000 | (divisors[rsum] << 16) | (divisors[gsum] << 8) | divisors[bsum] |
187 |
| - if x == 0: |
188 |
| - vmin[y] = min(y + radius + 1, heightMinus) * imgWidth |
189 |
| - vmax[y] = max(y - radius, 0) * imgWidth |
190 |
| - pixel1 = x + vmin[y] |
191 |
| - pixel2 = x + vmax[y] |
192 |
| - rsum += redPlane[pixel1] - redPlane[pixel2] |
193 |
| - gsum += greenPlane[pixel1] - greenPlane[pixel2] |
194 |
| - bsum += bluePlane[pixel1] - bluePlane[pixel2] |
195 |
| - yIndex += imgWidth |
196 |
| - return pix |
0 commit comments