*
* 2005: opts work. added options -balls, -ballsize, -explosion
*
+ * 2006: opts work. added option -decay
+ *
+ * 2008: opts work. added option -momentum
+ *
*/
#include "boxed.h"
# define DEF_BALLS "25"
# define DEF_BALLSIZE "2.0"
# define DEF_EXPLOSION "15.0"
-# define DEF_DECAY "0.1"
+# define DEF_DECAY "0.07"
+# define DEF_MOMENTUM "0.6"
#undef countof
#define countof(x) (int)(sizeof((x))/sizeof((*x)))
static GLfloat cfg_ballsize;
static GLfloat cfg_explosion;
static GLfloat cfg_decay;
+static GLfloat cfg_momentum;
static XrmOptionDescRec opts[] = {
{"-ballsize", ".boxed.ballsize", XrmoptionSepArg, 0},
{"-explosion", ".boxed.explosion", XrmoptionSepArg, 0},
{"-decay", ".boxed.decay", XrmoptionSepArg, 0},
+ {"-momentum", ".boxed.momentum", XrmoptionSepArg, 0},
};
static argtype vars[] = {
{&cfg_ballsize, "ballsize", "Ball Size", DEF_BALLSIZE, t_Float},
{&cfg_explosion, "explosion", "Explosion", DEF_EXPLOSION, t_Float},
{&cfg_decay, "decay", "Explosion Decay", DEF_DECAY, t_Float},
+ {&cfg_momentum, "momentum", "Explosion Momentum", DEF_MOMENTUM, t_Float},
};
ENTRYPOINT ModeSpecOpt boxed_opts = {countof(opts), opts, countof(vars), vars, NULL};
float scalefac;
float explosion;
float decay;
+ float momentum;
vectorf color;
tri *tris;
GLint *indices;
float ballsize;
float explosion;
float decay;
+ float momentum;
BOOL textures;
BOOL transparent;
float camspeed;
GLXContext *glx_context;
GLuint listobjects;
GLuint gllists[3];
+ int list_polys[3];
Window window;
BOOL stop;
char *tex1;
return v->x * v->x + v->y * v->y + v->z * v->z;
}
+static inline GLfloat
+squaremagnitudehorz(vectorf * v)
+{
+ return v->x * v->x + v->z * v->z;
+}
+
/*
scalevector(&bman->balls[b].dir,&bman->balls[b].dir,0.80f);
if (squaremagnitude(&bman->balls[b].dir) < 0.08f) {
createball(&bman->balls[b]);
- }
+ }
+ if (squaremagnitudehorz(&bman->balls[b].dir) < 0.005f) {
+ createball(&bman->balls[b]);
+ }
}
}
{
int pos;
float explosion;
+ float momentum;
float scale;
register int i;
- vectorf avgdir,dvect;
+ vectorf avgdir,dvect,mvect;
tman->scalefac = b->radius;
copyvector(&tman->color,&b->color);
explosion = 1.0f + tman->explosion * 2.0 * rnd();
+ momentum = tman->momentum;
tman->num_tri = ind_num/3;
dvect.y = (0.15f - 0.3f*rnd());
dvect.z = (0.1f - 0.2f*rnd());
addvectors(&tman->tris[i].dir,&tman->tris[i].dir,&dvect);
+
+ /* add ball's momentum to each piece of the exploded ball */
+ mvect.x = b->dir.x * momentum;
+ mvect.y = 0;
+ mvect.z = b->dir.z * momentum;
+ addvectors(&tman->tris[i].dir,&tman->tris[i].dir,&mvect);
}
}
cfg_ballsize = MAX(1.0f,MIN(5.0f,cfg_ballsize));
cfg_explosion = MAX(0.0f,MIN(50.0f,cfg_explosion));
cfg_decay = MAX(0.0f,MIN(1.0f,cfg_decay));
+ cfg_momentum = MAX(0.0f,MIN(1.0f,cfg_momentum));
config->numballs = cfg_balls;
config->textures = TRUE;
config->transparent = FALSE;
config->explosion = cfg_explosion;
config->decay = cfg_decay;
+ config->momentum = cfg_momentum;
config->ballsize = cfg_ballsize;
config->camspeed = 35.0f;
}
/*
* draw bottom
*/
-static void drawfilledbox(boxedstruct *boxed, int wire)
+static int drawfilledbox(boxedstruct *boxed, int wire)
{
/* draws texture filled box,
top is drawn using the entire texture,
the sides are drawn using the edge of the texture
*/
+ int polys = 0;
/* front */
glBegin(wire ? GL_LINE_LOOP : GL_QUADS);
glVertex3f(1.0,-1.0,1.0);
glTexCoord2f(0,1);
glVertex3f(-1.0,-1.0,1.0);
+ polys++;
/* rear */
glTexCoord2f(0,1);
glVertex3f(1.0,1.0,-1.0);
glVertex3f(-1.0,-1.0,-1.0);
glTexCoord2f(0,1);
glVertex3f(1.0,-1.0,-1.0);
+ polys++;
/* left */
glTexCoord2f(1,1);
glVertex3f(-1.0,1.0,1.0);
glVertex3f(-1.0,-1.0,-1.0);
glTexCoord2f(0,1);
glVertex3f(-1.0,1.0,-1.0);
+ polys++;
/* right */
glTexCoord2f(0,1);
glVertex3f(1.0,1.0,1.0);
glVertex3f(1.0,-1.0,-1.0);
glTexCoord2f(0,1);
glVertex3f(1.0,-1.0,1.0);
+ polys++;
/* top */
glTexCoord2f(0.0,0.0);
glVertex3f(-1.0,1.0,1.0);
glVertex3f(1.0,1.0,-1.0);
glTexCoord2f(1.0,0.0);
glVertex3f(1.0,1.0,1.0);
+ polys++;
/* bottom */
glTexCoord2f(0,0);
glVertex3f(-1.0,-1.0,1.0);
glVertex3f(1.0,-1.0,-1.0);
glTexCoord2f(1,0);
glVertex3f(1.0,-1.0,1.0);
+ polys++;
glEnd();
+
+ return polys;
}
/*
* Draw a box made of lines
*/
-static void drawbox(boxedstruct *boxed)
+static int drawbox(boxedstruct *boxed)
{
+ int polys = 0;
/* top */
glBegin(GL_LINE_STRIP);
glVertex3f(-1.0,1.0,1.0);
- glVertex3f(-1.0,1.0,-1.0);
- glVertex3f(1.0,1.0,-1.0);
- glVertex3f(1.0,1.0,1.0);
- glVertex3f(-1.0,1.0,1.0);
+ glVertex3f(-1.0,1.0,-1.0); polys++;
+ glVertex3f(1.0,1.0,-1.0); polys++;
+ glVertex3f(1.0,1.0,1.0); polys++;
+ glVertex3f(-1.0,1.0,1.0); polys++;
glEnd();
/* bottom */
glBegin(GL_LINE_STRIP);
glVertex3f(-1.0,-1.0,1.0);
- glVertex3f(1.0,-1.0,1.0);
- glVertex3f(1.0,-1.0,-1.0);
- glVertex3f(-1.0,-1.0,-1.0);
- glVertex3f(-1.0,-1.0,1.0);
+ glVertex3f(1.0,-1.0,1.0); polys++;
+ glVertex3f(1.0,-1.0,-1.0); polys++;
+ glVertex3f(-1.0,-1.0,-1.0); polys++;
+ glVertex3f(-1.0,-1.0,1.0); polys++;
glEnd();
/* connect top & bottom */
glBegin(GL_LINES);
glVertex3f(-1.0,1.0,1.0);
- glVertex3f(-1.0,-1.0,1.0);
+ glVertex3f(-1.0,-1.0,1.0); polys++;
glVertex3f(1.0,1.0,1.0);
- glVertex3f(1.0,-1.0,1.0);
+ glVertex3f(1.0,-1.0,1.0); polys++;
glVertex3f(1.0,1.0,-1.0);
- glVertex3f(1.0,-1.0,-1.0);
+ glVertex3f(1.0,-1.0,-1.0); polys++;
glVertex3f(-1.0,1.0,-1.0);
- glVertex3f(-1.0,-1.0,-1.0);
+ glVertex3f(-1.0,-1.0,-1.0); polys++;
glEnd();
+ return polys;
}
/*
* Draw ball
*/
-static void drawball(boxedstruct *gp, ball *b, int wire)
+static int drawball(boxedstruct *gp, ball *b, int wire)
{
+ int polys = 0;
int i,pos,cnt;
GLint *spherei = gp->spherei;
vectorf *spherev = gp->spherev;
glNormal3f(spherev[spherei[pos+0]].x,spherev[spherei[pos+0]].y,spherev[spherei[pos+0]].z);
glVertex3f(spherev[spherei[pos+0]].x,spherev[spherei[pos+0]].y,spherev[spherei[pos+0]].z);
glNormal3f(spherev[spherei[pos+1]].x,spherev[spherei[pos+1]].y,spherev[spherei[pos+1]].z);
+ gp->list_polys[GLL_BALL]++;
glVertex3f(spherev[spherei[pos+1]].x,spherev[spherei[pos+1]].y,spherev[spherei[pos+1]].z);
glNormal3f(spherev[spherei[pos+2]].x,spherev[spherei[pos+2]].y,spherev[spherei[pos+2]].z);
glVertex3f(spherev[spherei[pos+2]].x,spherev[spherei[pos+2]].y,spherev[spherei[pos+2]].z);
+ gp->list_polys[GLL_BALL]++;
glEnd();
}
glEndList();
gp->gllists[GLL_BALL] = 1;
} else {
glCallList(gp->listobjects + GLL_BALL);
+ polys += gp->list_polys[GLL_BALL];
}
glPopMatrix();
+ return polys;
}
/*
* Draw all triangles in triman
*/
-static void drawtriman(triman *t, int wire)
+static int drawtriman(triman *t, int wire)
{
+ int polys = 0;
int i,pos;
vectorf *spherev = t->vertices;
GLfloat col[3];
glVertex3f(spherev[pos+0].x,spherev[pos+0].y,spherev[pos+0].z);
glVertex3f(spherev[pos+1].x,spherev[pos+1].y,spherev[pos+1].z);
glVertex3f(spherev[pos+2].x,spherev[pos+2].y,spherev[pos+2].z);
+ polys++;
glEnd();
glPopMatrix();
}
glPopMatrix();
+ return polys;
}
/*
* draw floor pattern
*/
-static void drawpattern(boxedstruct *gp)
+static int drawpattern(boxedstruct *gp)
{
+ int polys = 0;
if (!gp->gllists[GLL_PATTERN]) {
glNewList(gp->listobjects + GLL_PATTERN, GL_COMPILE);
glBegin(GL_LINE_STRIP);
glVertex3f(-25.0f, 0.0f, 35.0f);
- glVertex3f(-15.0f, 0.0f, 35.0f);
- glVertex3f(-5.0f, 0.0f, 25.0f);
- glVertex3f(5.0f, 0.0f, 25.0f);
- glVertex3f(15.0f, 0.0f, 35.0f);
- glVertex3f(25.0f, 0.0f, 35.0f);
- glVertex3f(35.0f, 0.0f, 25.0f);
- glVertex3f(35.0f, 0.0f, 15.0f);
- glVertex3f(25.0f, 0.0f, 5.0f);
- glVertex3f(25.0f, 0.0f, -5.0f);
- glVertex3f(35.0f, 0.0f, -15.0f);
- glVertex3f(35.0f, 0.0f, -25.0f);
- glVertex3f(25.0f, 0.0f, -35.0f);
- glVertex3f(15.0f, 0.0f,-35.0f);
- glVertex3f(5.0f, 0.0f, -25.0f);
- glVertex3f(-5.0f, 0.0f, -25.0f);
- glVertex3f(-15.0f, 0.0f,-35.0f);
- glVertex3f(-25.0f, 0.0f,-35.0f);
- glVertex3f(-35.0f, 0.0f, -25.0f);
- glVertex3f(-35.0f, 0.0f, -15.0f);
- glVertex3f(-25.0f, 0.0f, -5.0f);
- glVertex3f(-25.0f, 0.0f, 5.0f);
- glVertex3f(-35.0f, 0.0f, 15.0f);
- glVertex3f(-35.0f, 0.0f, 25.0f);
- glVertex3f(-25.0f, 0.0f, 35.0f);
+ glVertex3f(-15.0f, 0.0f, 35.0f); gp->list_polys[GLL_PATTERN]++;
+ glVertex3f(-5.0f, 0.0f, 25.0f); gp->list_polys[GLL_PATTERN]++;
+ glVertex3f(5.0f, 0.0f, 25.0f); gp->list_polys[GLL_PATTERN]++;
+ glVertex3f(15.0f, 0.0f, 35.0f); gp->list_polys[GLL_PATTERN]++;
+ glVertex3f(25.0f, 0.0f, 35.0f); gp->list_polys[GLL_PATTERN]++;
+ glVertex3f(35.0f, 0.0f, 25.0f); gp->list_polys[GLL_PATTERN]++;
+ glVertex3f(35.0f, 0.0f, 15.0f); gp->list_polys[GLL_PATTERN]++;
+ glVertex3f(25.0f, 0.0f, 5.0f); gp->list_polys[GLL_PATTERN]++;
+ glVertex3f(25.0f, 0.0f, -5.0f); gp->list_polys[GLL_PATTERN]++;
+ glVertex3f(35.0f, 0.0f, -15.0f); gp->list_polys[GLL_PATTERN]++;
+ glVertex3f(35.0f, 0.0f, -25.0f); gp->list_polys[GLL_PATTERN]++;
+ glVertex3f(25.0f, 0.0f, -35.0f); gp->list_polys[GLL_PATTERN]++;
+ glVertex3f(15.0f, 0.0f,-35.0f); gp->list_polys[GLL_PATTERN]++;
+ glVertex3f(5.0f, 0.0f, -25.0f); gp->list_polys[GLL_PATTERN]++;
+ glVertex3f(-5.0f, 0.0f, -25.0f); gp->list_polys[GLL_PATTERN]++;
+ glVertex3f(-15.0f, 0.0f,-35.0f); gp->list_polys[GLL_PATTERN]++;
+ glVertex3f(-25.0f, 0.0f,-35.0f); gp->list_polys[GLL_PATTERN]++;
+ glVertex3f(-35.0f, 0.0f, -25.0f); gp->list_polys[GLL_PATTERN]++;
+ glVertex3f(-35.0f, 0.0f, -15.0f); gp->list_polys[GLL_PATTERN]++;
+ glVertex3f(-25.0f, 0.0f, -5.0f); gp->list_polys[GLL_PATTERN]++;
+ glVertex3f(-25.0f, 0.0f, 5.0f); gp->list_polys[GLL_PATTERN]++;
+ glVertex3f(-35.0f, 0.0f, 15.0f); gp->list_polys[GLL_PATTERN]++;
+ glVertex3f(-35.0f, 0.0f, 25.0f); gp->list_polys[GLL_PATTERN]++;
+ glVertex3f(-25.0f, 0.0f, 35.0f); gp->list_polys[GLL_PATTERN]++;
glEnd();
glBegin(GL_LINE_STRIP);
glVertex3f(-5.0f, 0.0f, 15.0f);
- glVertex3f(5.0f, 0.0f, 15.0f);
- glVertex3f(15.0f, 0.0f, 5.0f);
- glVertex3f(15.0f, 0.0f, -5.0f);
- glVertex3f(5.0f, 0.0f, -15.0f);
- glVertex3f(-5.0f, 0.0f, -15.0f);
- glVertex3f(-15.0f, 0.0f, -5.0f);
- glVertex3f(-15.0f, 0.0f, 5.0f);
- glVertex3f(-5.0f, 0.0f, 15.0f);
+ glVertex3f(5.0f, 0.0f, 15.0f); gp->list_polys[GLL_PATTERN]++;
+ glVertex3f(15.0f, 0.0f, 5.0f); gp->list_polys[GLL_PATTERN]++;
+ glVertex3f(15.0f, 0.0f, -5.0f); gp->list_polys[GLL_PATTERN]++;
+ glVertex3f(5.0f, 0.0f, -15.0f); gp->list_polys[GLL_PATTERN]++;
+ glVertex3f(-5.0f, 0.0f, -15.0f); gp->list_polys[GLL_PATTERN]++;
+ glVertex3f(-15.0f, 0.0f, -5.0f); gp->list_polys[GLL_PATTERN]++;
+ glVertex3f(-15.0f, 0.0f, 5.0f); gp->list_polys[GLL_PATTERN]++;
+ glVertex3f(-5.0f, 0.0f, 15.0f); gp->list_polys[GLL_PATTERN]++;
glEnd();
glEndList();
gp->gllists[GLL_PATTERN] = 1;
} else {
glCallList(gp->listobjects + GLL_PATTERN);
- }
+ polys += gp->list_polys[GLL_PATTERN];
+ }
+ return polys;
}
GLfloat l1_diffuse[] = {0.5, 0.5, 0.5, 1.0};
GLfloat l1_position[] = {0.0, 1.0, 0.0, 0.0}; /* w = 0 -> directional light */
+ mi->polygon_count = 0;
+
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glLoadIdentity();
glColor3f(1.0,1.0,1.0);
glScalef(20.0,0.25,20.0);
glTranslatef(0.0,2.0,0.0);
- drawfilledbox(gp, wire);
+ mi->polygon_count += drawfilledbox(gp, wire);
glPopMatrix();
glDisable(GL_TEXTURE_2D);
glColor3f(0.2,0.5,0.2);
glScalef(20.0,20.0,0.25);
glTranslatef(0.0,1.0,81.0);
- drawbox(gp);
+ mi->polygon_count += drawbox(gp);
glPopMatrix();
glPushMatrix();
glColor3f(0.2,0.5,0.2);
glScalef(20.0,20.0,0.25);
glTranslatef(0.0,1.0,-81.0);
- drawbox(gp);
+ mi->polygon_count += drawbox(gp);
glPopMatrix();
glPushMatrix();
glColor3f(0.2,0.5,0.2);
glScalef(.25,20.0,20.0);
glTranslatef(-81.0,1.0,0.0);
- drawbox(gp);
+ mi->polygon_count += drawbox(gp);
glPopMatrix();
glPushMatrix();
glColor3f(0.2,0.5,0.2);
glScalef(.25,20.0,20.0);
glTranslatef(81.0,1.0,0.0);
- drawbox(gp);
+ mi->polygon_count += drawbox(gp);
glPopMatrix();
if (!wire) {
updatetris(&gp->tman[i]);
}
glDisable(GL_CULL_FACE);
- drawtriman(&gp->tman[i], wire);
+ mi->polygon_count += drawtriman(&gp->tman[i], wire);
if (!wire) glEnable(GL_CULL_FACE);
} else {
- drawball(gp, &gp->bman.balls[i], wire);
+ mi->polygon_count += drawball(gp, &gp->bman.balls[i], wire);
}
}
glShadeModel(GL_SMOOTH);
glClearDepth(1.0);
- glClearColor(0.0,0.05,0.1,0.0);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
/* Load configuration */
setdefaultconfig(&gp->config);
+
+ /* give the decay parameter a better curve */
+ if (gp->config.decay <= 0.8182) { gp->config.decay = gp->config.decay / 3; }
+ else { gp->config.decay = (gp->config.decay - 0.75) * 4; }
bman = &gp->bman;
for(i=0;i<bman->num_balls;i++) {
gp->tman[i].explosion = (float) (((int)gp->config.explosion) / 15.0f );
gp->tman[i].decay = gp->config.decay;
+ gp->tman[i].momentum = gp->config.momentum;
gp->tman[i].vertices = NULL;
gp->tman[i].normals = NULL;
gp->tman[i].tris = NULL;