summaryrefslogtreecommitdiff
path: root/themes/src
diff options
context:
space:
mode:
Diffstat (limited to 'themes/src')
-rw-r--r--themes/src/Snowflake.cpp26
-rw-r--r--themes/src/Snowflake.h4
-rw-r--r--themes/src/Windfield.cpp28
-rw-r--r--themes/src/Windfield.hpp38
4 files changed, 86 insertions, 10 deletions
diff --git a/themes/src/Snowflake.cpp b/themes/src/Snowflake.cpp
index 1eb6b74..452a716 100644
--- a/themes/src/Snowflake.cpp
+++ b/themes/src/Snowflake.cpp
@@ -4,6 +4,16 @@
#include "list.h"
#include <cstdio>
+/*
+
+ What else to do?
+
+ - Windstream that blows a certain selection of snowflakes in a loop-dee-loop pattern
+ - Snowflakes that land on the ground and melt
+ - Snowflakes that spin along the Y-axis for a three dimensional effect
+
+ */
+
const Vector4 snowColor = Vector4(1.0, 0.98, 0.98, 1);
const Vector2 NUM_ARMS_RANGE = Vector2(6.f, 8.f);
const Vector2 RADIUS_RANGE = Vector2(8.f, 32.f);
@@ -65,10 +75,11 @@ inline void generateSnowflakeShape(matte::List<Vertex2D>* vertices, i32 numArms,
}
inline void initFlake(SnowflakeParticleRenderer* renderer, SnowflakeUpdateData* ud) {
+ ud->radius = randomFloatBetween(RADIUS_RANGE.x, RADIUS_RANGE.y);
ud->vtxIdx = renderer->vertices.numElements;
generateSnowflakeShape(&renderer->vertices,
randomFloatBetween(NUM_ARMS_RANGE.x, NUM_ARMS_RANGE.y),
- randomFloatBetween(RADIUS_RANGE.x, RADIUS_RANGE.y));
+ ud->radius);
ud->numVertices = renderer->vertices.numElements - ud->vtxIdx;
ud->velocity = Vector2(randomFloatBetween(VELOCITY_RANGE_X.x, VELOCITY_RANGE_X.y), randomFloatBetween(VELOCITY_RANGE_Y.x, VELOCITY_RANGE_Y.y));
@@ -126,9 +137,10 @@ void SnowflakeParticleRenderer::load(SnowflakeLoadParameters params, Renderer2d*
inline void resetFlake(SnowflakeParticleRenderer* renderer, SnowflakeUpdateData* ud) {
ud->position.y = 2 * renderer->yMax;
ud->velocity = Vector2(randomFloatBetween(-10, 10), randomFloatBetween(-100, -85));
+ ud->rotation = 0;
}
-inline void updateFlake(SnowflakeParticleRenderer* renderer, SnowflakeUpdateData* ud, i32 s, f32 dtSeconds, bool addWind) {
+inline void updateFlake(SnowflakeParticleRenderer* renderer, SnowflakeUpdateData* ud, i32 s, f32 dtSeconds) {
ud->velocity = ud->velocity + Vector2(0, -(GRAVITY * dtSeconds));
if (addWind) ud->velocity += renderer->windSpeed;
ud->position += ud->velocity * dtSeconds;
@@ -139,24 +151,20 @@ inline void updateFlake(SnowflakeParticleRenderer* renderer, SnowflakeUpdateData
renderer->vertices.data[v].vMatrix = m;
}
- if (ud->position.y <= -256) {
+ if (ud->position.y <= -ud->radius) {
resetFlake(renderer, ud);
}
}
void SnowflakeParticleRenderer::update(f32 dtSeconds) {
- bool addWind = false;
timeUntilNextWindSeconds -= dtSeconds;
if (timeUntilNextWindSeconds < 0) {
- timeUntilNextWindSeconds = windIntervalSeconds;
- windSpeed = Vector2(randomFloatBetween(WIND_VELOCITY_RANGE_X.x, WIND_VELOCITY_RANGE_X.y),
- randomFloatBetween(WIND_VELOCITY_RANGE_Y.x, WIND_VELOCITY_RANGE_Y.y));
- addWind = true;
+ timeUntilNextWindSeconds = randomFloatBetween(2.5f, 10.f);
}
for (i32 s = 0; s < numSnowflakes; s++) {
SnowflakeUpdateData* ud = &updateData[s];
- updateFlake(this, ud, s, dtSeconds, addWind);
+ updateFlake(this, ud, s, dtSeconds);
}
}
diff --git a/themes/src/Snowflake.h b/themes/src/Snowflake.h
index 2524483..c147469 100644
--- a/themes/src/Snowflake.h
+++ b/themes/src/Snowflake.h
@@ -4,6 +4,7 @@
#include "types.h"
#include "mathlib.h"
#include "list.h"
+#include "Windfield.hpp"
struct Renderer2d;
struct Vertex2D;
@@ -18,6 +19,7 @@ struct SnowflakeUpdateData {
Vector2 position;
f32 rotateVelocity = 0.f;
f32 rotation = 0;
+ f32 radius;
i32 vtxIdx = 0;
i32 numVertices = 0;
@@ -28,8 +30,8 @@ struct SnowflakeParticleRenderer {
f32 yMax = 0;
f32 windIntervalSeconds = 1.5;
i32 numSnowflakes = 0;
- Vector2 windSpeed;
f32 timeUntilNextWindSeconds = 0;
+ WindField wind;
SnowflakeUpdateData* updateData;
u32 vao;
diff --git a/themes/src/Windfield.cpp b/themes/src/Windfield.cpp
new file mode 100644
index 0000000..3a7563f
--- /dev/null
+++ b/themes/src/Windfield.cpp
@@ -0,0 +1,28 @@
+#include "Windfield.hpp"
+
+
+template <i32 Width, i32 Height, i32 CellDimension>
+void WindField<Width, Height, CellDimension>::load(f32 ttl, Vector2 origin) {
+ this->ttl = ttl;
+ this->origin = origin;
+ this->end = this->origin + Vector2(Width * CellDimension, Height * CellDimension);
+}
+
+template <i32 Width, i32 Height, i32 CellDimension>
+bool WindField<Width, Height, CellDimension>::addVector(i32 x, i32 y, Vector2& v) {
+ field[x][y] = v;
+ return false;
+}
+
+template <i32 Width, i32 Height, i32 CellDimension>
+Vector2 WindField<Width, Height, CellDimension>::getWindFactor(Vector2& v) {
+ if (v.x >= origin.x && v.x <= end.x
+ && v.y >= origin.y && v.y <= end.y) {
+ Vector2 positionInField = v - this->origin;
+ i32 cellX = static_cast<i32>(Width / positionInField.x);
+ i32 cellY = static_cast<i32>(Height / positionInField.y);
+ return field[cellX, cellY];
+ }
+
+ return Vector2();
+}
diff --git a/themes/src/Windfield.hpp b/themes/src/Windfield.hpp
new file mode 100644
index 0000000..5935c5d
--- /dev/null
+++ b/themes/src/Windfield.hpp
@@ -0,0 +1,38 @@
+#ifndef WIND_FIELD_HPP
+#define WIND_FIELD_HPP
+#include "types.h"
+#include "mathlib.h"
+
+/**
+ A Windfield represents a field of vectors in a rectangular region.
+ The Width and Height are given in units of CellDimenions. The CellDimension
+ is given in pixels.
+ */
+struct WindField {
+ f32 ttl = 0.f;
+ Vector2 origin;
+ Vector2 end;
+
+ /*
+ Granularity of each cell in pixels.
+ */
+ const f32 cellDimension = CellDimension;
+
+ /*
+ Width of the vector field in CellDimensions.
+ */
+ const f32 width = Width;
+
+ /*
+ Height of the vector vield in CellDimensions.
+ */
+ const f32 height = Height;
+
+ Vector2** field;
+
+ void load(f32 cellSizePixels, i32 fieldWithCells, i32 fieldHeightCells, f32 ttl, Vector2 origin);
+ bool addVector(i32 x, i32 y, Vector2& v);
+ Vector2 getWindFactor(Vector2& v);
+};
+
+#endif