Created
November 27, 2020 11:47
-
-
Save bdero/987a959c33b0d9dc8ab04bc5aeecb50c to your computer and use it in GitHub Desktop.
ImGui Particle Text demo
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
* ImGui Particle Text (deobfuscated) | |
* ================================== | |
* Done as part of the "ImDrawList coding party" challenge: | |
* https://github.com/ocornut/imgui/issues/3606#issuecomment-734636054 | |
* https://twitter.com/algebrandon/status/1332182010593304576 | |
*/ | |
#include <algorithm> | |
// 2D rotation formula. This demo uses Euler angles, and so this formula is used | |
// three times (once for each basis axis) when computing the position of each circle. | |
// See also: https://en.wikipedia.org/wiki/Rotation_matrix | |
#define Rotate(u, v, r) \ | |
{ \ | |
float U = u; \ | |
u = cos(r) * u - sin(r) * v; \ | |
v = sin(r) * U + cos(r) * v; \ | |
} | |
// This is a common S-curve function `1/(1+e^-t)`, but with a range of 0 to 2PI | |
// because this demo happens to only use it for computing rotations. | |
// See also: https://en.wikipedia.org/wiki/Sigmoid_function | |
#define Sigmoid(T) 1.f / (1 + exp(-(T))) * IM_PI * 2 | |
// This is a just a Sine function with an exponentially decaying magnitude `sin(t)`. | |
// The intended domain is 0 to ~5, and the range is -1 to 1. | |
#define Bounce(T) sin((T) *3) * exp(-(T)) | |
// The base diameter (and distance apart) all of the circles should be on the grid. | |
// The actual diameter is inflated a bit from this value so that the circles smoosh | |
// together. | |
const int DIAMETER = 11; | |
// This `unsigned int` array contains a 17x13 grid of circles (221 bits). Note that | |
// 7 32 bit numbers can store 224 bits, and so the least significant 3 bits of the | |
// first `int` are just ignored over when sampling the grid. | |
// | |
unsigned grid[] = {0xD9000080, 0x750A2B18, 0xDC2A2A17, 0x0200025D, 0x5AB1E800, 0x26EAB555, 0x01800100}; | |
struct GridCircle { | |
float x, y, z; | |
// When the circles array is sorted by depth, the circle's position in the | |
// grid can no longer be determined by just looking at the index, and so the | |
// index is preserved in this field. | |
// The index is then later used when computing the color. | |
int gridIndex; | |
// Overload the < operator so that circles with higher Z values (which are | |
// further away from the camera) are given lower order when calling | |
// `std::sort`. | |
bool operator<(GridCircle &o) { return z > o.z; } | |
}; | |
void FX(ImDrawList *drawList, ImVec2 windowPosition, ImVec2 b, ImVec2 windowSize, ImVec4 m, float time) { | |
float loopTime = fmod(time, 6) * 10; | |
GridCircle circles[221]; | |
for (int n = 3; n < 224; n++) { | |
int gridIndex = n - 3; | |
float x = gridIndex % 17 * DIAMETER - 8.5f * DIAMETER; | |
float y = gridIndex / 17 * DIAMETER - 6.5f * DIAMETER; | |
float z = 0; | |
float distance = sqrt(x * x + y * y) / 32; | |
float rotationX = Sigmoid(loopTime - 4 - distance) + cos(time / 3) / 4; | |
float rotationY = Sigmoid(loopTime - 12 - distance) + cos(time / 7) / 4; | |
float rotationZ = Sigmoid(loopTime - 20 - distance) + cos(time / 2) / 4; | |
Rotate(x, y, rotationZ);// Z axis | |
Rotate(y, z, rotationX);// X axis | |
Rotate(x, z, rotationY);// Y axis | |
z -= loopTime - distance > 28 ? Bounce((loopTime - 28 - distance) / 2) * 50 : 0; | |
z = grid[n / 32] & 1 << n % 32 ? z / 100 + 1 : 0; | |
circles[gridIndex] = {windowPosition.x + windowSize.x * .5f + x / z, | |
windowPosition.y + windowSize.y * .5f + y / z, z, gridIndex}; | |
} | |
std::sort(circles, &circles[221]); | |
for (int i = 0; i < 221; i++) { | |
if (circles[i].z != 0) { | |
drawList->AddCircleFilled(ImVec2(circles[i].x, circles[i].y), DIAMETER * .8 / circles[i].z, | |
ImColor(circles[i].gridIndex > 102 ? 0.f : 1.f, | |
circles[i].gridIndex < 102 ? 0.f : 1.f, 3.f - circles[i].z * 2.5f, 1.f)); | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment