summaryrefslogtreecommitdiffstats
path: root/debian/fireflies/fireflies-2.08/src/tail.cc
diff options
context:
space:
mode:
Diffstat (limited to 'debian/fireflies/fireflies-2.08/src/tail.cc')
-rw-r--r--debian/fireflies/fireflies-2.08/src/tail.cc89
1 files changed, 89 insertions, 0 deletions
diff --git a/debian/fireflies/fireflies-2.08/src/tail.cc b/debian/fireflies/fireflies-2.08/src/tail.cc
new file mode 100644
index 00000000..18e013b6
--- /dev/null
+++ b/debian/fireflies/fireflies-2.08/src/tail.cc
@@ -0,0 +1,89 @@
+#include "tail.h"
+#include "firefly.h"
+#include "scene.h"
+
+Tail::Tail(Firefly *_owner)
+ : owner(_owner)
+{
+}
+
+#define SET_COLOR(c, a) glColor4f(c[0], c[1], c[2], a)
+#define SET_VERTEX(v, dx) glVertex3d(v[0]+dx, v[1], v[2])
+#define DO_POINT(t, dx, a)\
+ SET_COLOR((t).color, a); SET_VERTEX((t).pos, dx)
+
+void Tail::draw()
+{
+ if (links.size() < 2) // need at least 2 links
+ return;
+
+ deque<Link>::iterator it = links.begin();
+ double glow_width = scene.glow_factor*scene.tail_width;
+ double stretch_factor = 2*scene.fsize*scene.wind[0];
+ double dx1, dx2;
+
+ dx2 = ((*it).glow ? glow_width : scene.tail_width);
+ for (; (it+1) != links.end(); it++) {
+ // half-width of the tail
+ dx1 = dx2;
+ dx2 = ((*(it+1)).glow ? glow_width : scene.tail_width);
+
+ // have the wind stretch the tail (greater effect on ends)
+ double age = (*it).age/scene.tail_length;
+ double stretch = stretch_factor*age*age;
+ double alpha = 0.9 - age;
+ if (alpha > scene.tail_opaq)
+ alpha = scene.tail_opaq;
+
+ // two rectangles: outer vertices have alpha=0, inner two have
+ // alpha based on age. note: alpha goes negative, but opengl
+ // should clamp it to 0.
+ if (stretch > 0) { // stretch to the right
+ glBegin(GL_QUAD_STRIP);
+ DO_POINT(*it, -dx1, 0);
+ DO_POINT(*(it+1), -dx2, 0);
+
+ DO_POINT(*it, 0, alpha);
+ DO_POINT(*(it+1), 0, alpha);
+
+ DO_POINT(*it, dx1 + stretch, 0);
+ DO_POINT(*(it+1), dx2 + stretch, 0);
+ }
+ else { // stretch to the left
+ glBegin(GL_QUAD_STRIP);
+ DO_POINT(*it, -dx1 + stretch, 0);
+ DO_POINT(*(it+1), -dx2 + stretch, 0);
+
+ DO_POINT(*it, 0, alpha);
+ DO_POINT(*(it+1), 0, alpha);
+
+ DO_POINT(*it, dx1, 0);
+ DO_POINT(*(it+1), dx2, 0);
+ }
+ glEnd();
+ }
+}
+
+bool Tail::elapse(double t)
+{
+ // pop off the dead ones.
+ // note we only have to check the end, since that's where they're gonna
+ // be dying from. deque is very nice for this, because it has constant
+ // time insertion/removal from both ends.
+ while (!links.empty() && links.back().age >= scene.tail_length)
+ links.pop_back();
+
+ deque<Link>::iterator it = links.begin();
+ for (; it != links.end(); it++) {
+ (*it).age += t;
+ double age = (*it).age/scene.tail_length;
+ (*it).pos += scene.wind*age*age;
+ }
+
+ if (owner == 0) // my owner died! grow no longer
+ return links.empty(); // if we're empty, tell caller we're dead
+
+ links.push_front(Link(owner->pos, owner->color, owner->bait->glow));
+
+ return false;
+}