Anthropocene Tornadoes
Anthropocene: a thought that humans have become a geological force. -Vladimir Verdansky
Climate change is happening, and it will reshape the way we think about our daily lives. At the epicenter of this global phenomenon is us: humans. Throughout the ages, we have been kneeling under the force of nature. But beginning in the Industrial Revolution and onwards, we began to revolutionize how we do things. Without looking at its long-term consequences, we conquered nature and became a destructive force in return.
Anthropocene Tornadoes is my attempt and initiative to raise awareness regarding this matter. It is a simple program but a philosophical piece that combines interactiveness and mindfulness.
The goal is simple: You are the tornado. Destroy.
Sketch DemoInspiration and Challenges
As some of you might have seen from the previous drafts, my initial concept of this project was to use AR systems to generate the tornado and have the user play around with it. But, after really really arduous long hours of testing and developing, I concluded: that AR is too limited and not the best environment to do this project.
I spent a good 5-6 hours trying to solve the big issue of interactiveness. I wanted the user to experience something different than the usual things displayed in the IM Show. But it seems like for this case, using AR was not the key.
SimpleAR library has a solid limitation: the ENTIRE p5.js sketch will turn into a camera. The camera then scans a marker, which then displays the sketch in the draw() function. But, because of this, it also significantly limits the amount of choice I have over the interaction the user can make. Plus, using camera and rendering particles were way too heavy for the intended viewing device, smartphones and ipads.
But the original concept remains the same. The program is a somewhat tornado simulation. It begins with a vortex-shaped particles that speeds up and inflates once the user move and ‘eat’ buildings represented by the rectangle.
The project’s visual choice is inspired by old 3d modeling software capabilities. Simple, abstracted, low-poly shapes are joined together to hopefully take the shape of something. In Anthropocene Tornadoes’ case, it was a city filled with skyscrapers, a grassland, and a tornado.
How The Program Works
▶️The sketch runs on a WebGL-based rendering, meaning that is has 3D capabilities. To adjust the camera, I used a p5.js library called EasyCam, which allowed me to manipulate the camera and only allowed the user to zoom in-and-out without rotating the canvas.
▶️The core of the program, the tornado, works by having a Particle class generated in a vortex-like shape in the beginning. This class is a vector class. It starts with a circle which converges downwards. This gives the effect of the vortex.
When the tornado collides with a skyscraper, it will increment a speed modifier, speedMultiplier, that effects the radius of the circle. Thus, with each particle spinning on this radius, it gets bigger and bigger. Combine it with noise, lerp, constrain, and you get yourself a somewhat convincing tornado-like particle system.
update(speedMultiplier) { // Increment the angular position to simulate swirling this.angle += (0.02 + noise(this.noiseOffset) * 0.02) * speedMultiplier; // Update the radius slightly with Perlin noise for organic motion this.radius += noise(this.noiseOffset) * 5 - 2.5; // Constrain the radius to a certain bound this.radius = constrain(this.radius, 20, 500); // Update height with sinusoidal oscillation (independent of speedMultiplier) this.pos.y += sin(frameCount * 0.01) * 0.5; // Wrap height to loop the tornado if (this.pos.y > 300) { this.pos.y = 0; this.radius = map(this.pos.y, 0, 300, 100, 10); // Reset radius } // Update the x and z coordinates based on the angle and radius this.pos.x = this.radius * cos(this.angle); this.pos.z = this.radius * sin(this.angle); this.noiseOffset += 0.01 * speedMultiplier; }
▶️The collisions are handled by a collision check, which also plays collision sounds. It works by splicing the collided skyscraper stored in the skyscraper array.
for (let i = skyscrapers.length - 1; i >= 0; i--) { let skyscraper = skyscrapers[i]; let distance = dist(tornadoX, 0, tornadoZ, skyscraper.x, 0, skyscraper.z); // If tornado is within a threshold distance, remove the skyscraper if (distance < 50) { skyscrapers.splice(i, 1); fill(0, 100, 100); speedMultiplier += speedIncrement; let randomCollisionSound = random(collisionSounds); randomCollisionSound.play(); continue; } else { fill(0, 0, 100); }
▶️The rest of the program is handled by a programStateLogic function which controls the state of the program and its appropriate ending.
Interaction
The program, as mentioned earlier is intentionally a simple one. The user moves the tornado using the mouse which controls the vector location of the tornado.
ENDINGs: There are three possible endings within the program.
1️⃣The user consumed all buildings.
2️⃣The user ‘failed’ to consume all buildings within the respective time
3️⃣The user does not decide to do anything and becomes a ‘savior’
These endings were created for the users to reflect our own actions as a human, and how we became a destructive force of nature. Nature here, being the tornado that we control.
User Testing & Reactions
Because my body said that it’s time to get sick at the end of the semester, I could not almost finish this project in time. But, I was able to receive feedback and user testing albeit from far away.
I sent the sketch link to some of my friends and asked them a simple question: How long did it take for you to figure out how to move the tornado?
I found two issues: a) While it is true that the user got the hang of it, I wanted the interaction to be more clear, so I added a simple mouse move command in the center of the screen. (Let’s not give super clear instructions shall we?)
b) The white screen. On some devices, the ending screen did not render the text properly. I fixed this and gave a clear message on what the ending is and what to do if the user wants to redo the program.
IM SHOWCASE
For the IM Showcase, I think it was very interesting to see how people reacted to both our midterm and final project. The leap from two-dimensional program to a three-dimensional is a huge one. From the ‘gameplay’, I believe that the endings could have been made more clear on how to obtain them. But regardless, it was interesting to give people a bit of information regarding tornadoes!
Reflections and Future Improvements
I wanted to work on the visuality of the project. Had I not been hospitalized for a few days during the holiday, I might have had more time to work on this aspect. But, after spending way too much time on the AR aspect and giving it up, I had no energy left to work on the visual aspect.
The project also surprisingly worked on mobile devices, although severely unoptimized. The gesture controls do work, but they don’t work very well. I was also thinking of doing something regarding the EF Scale. Perhaps, depending on how big the tornado gets, a color or something else changes. Also, for some reason the tornado flies upwards even though I did not change anything in that coordinate? what?
Regardless, this project was really fun for me to work on (although stressful at times). It really taught me how to emulate physics, but also how demanding simulating it for the machine.
Resources Used
touches – a p5.js feature I did not use
Tornado Sound #1 | Sound FX – YouTube – tornado sound
collision sounds – from plater addon, curseforge
p5.js WebGL camera – Daniel Shiffman
Tornado simulation inspiration – emmetdj
ChatGPT for the amazing debugging.