Borrowed LH's VectorVectors.

Changed smoke trails a good bit.
This commit is contained in:
Zephaniah E. Hull 2001-04-06 18:37:23 +00:00
parent 1f25ab9ec2
commit a16b2c0070
6 changed files with 269 additions and 63 deletions

View file

@ -77,7 +77,7 @@ void _VectorCopy (vec3_t in, vec3_t out);
int VectorCompare (vec3_t v1, vec3_t v2);
vec_t Length (vec3_t v);
void CrossProduct (vec3_t v1, vec3_t v2, vec3_t cross);
void CrossProduct (const vec3_t v1, const vec3_t v2, vec3_t cross);
float VectorNormalize (vec3_t v); // returns vector length
void VectorInverse (vec3_t v);
void VectorScale (vec3_t in, vec_t scale, vec3_t out);
@ -93,6 +93,7 @@ fixed16_t Mul16_30(fixed16_t multiplier, fixed16_t multiplicand);
int GreatestCommonDivisor (int i1, int i2);
void AngleVectors (vec3_t angles, vec3_t forward, vec3_t right, vec3_t up);
void VectorVectors(const vec3_t forward, vec3_t right, vec3_t up);
int BoxOnPlaneSide (vec3_t emins, vec3_t emaxs, struct mplane_s *plane);
float anglemod(float a);

View file

@ -104,6 +104,21 @@ PerpendicularVector (vec3_t dst, const vec3_t src)
#pragma optimize( "", off )
#endif
void VectorVectors(const vec3_t forward, vec3_t right, vec3_t up)
{
float d;
right[0] = forward[2];
right[1] = -forward[0];
right[2] = forward[1];
d = DotProduct(forward, right);
right[0] -= d * forward[0];
right[1] -= d * forward[1];
right[2] -= d * forward[2];
VectorNormalize(right);
CrossProduct(right, forward, up);
}
void
RotatePointAroundVector (vec3_t dst, const vec3_t dir, const vec3_t point,
@ -410,7 +425,7 @@ _VectorCopy (vec3_t in, vec3_t out)
}
void
CrossProduct (vec3_t v1, vec3_t v2, vec3_t cross)
CrossProduct (const vec3_t v1, const vec3_t v2, vec3_t cross)
{
cross[0] = v1[1] * v2[2] - v1[2] * v2[1];
cross[1] = v1[2] * v2[0] - v1[0] * v2[2];

View file

@ -54,8 +54,9 @@ typedef enum {
} ptype_t;
typedef struct particle_s {
// driver-usable fields
vec3_t org;
vec3_t up;
vec3_t right;
int tex;
float color;
float alpha;
@ -80,15 +81,16 @@ extern qboolean lighthalf;
extern cvar_t *cl_max_particles;
extern int part_tex_smoke_ring[8];
extern int part_tex_smoke[8];
extern int part_tex_dot;
extern int part_tex_spark;
extern int part_tex_smoke[8];
int ramp[8] = { 0x6d, 0x6b, 0x06, 0x05, 0x04, 0x03, 0x02, 0x01 };
inline particle_t *
particle_new (ptype_t type, int texnum, vec3_t org, float scale, vec3_t vel,
float die, byte color, byte alpha)
float die, byte color, byte alpha, vec3_t up, vec3_t right)
{
particle_t *part;
@ -108,6 +110,9 @@ particle_new (ptype_t type, int texnum, vec3_t org, float scale, vec3_t vel,
part->tex = texnum;
part->scale = scale;
VectorScale (up, 1.5, part->up);
VectorScale (right, 1.5, part->right);
return part;
}
@ -125,7 +130,7 @@ particle_new_random (ptype_t type, int texnum, vec3_t org, int org_fuzz,
if (vel_fuzz)
pvel[j] = lhrandom (-vel_fuzz, vel_fuzz);
}
return particle_new (type, texnum, porg, scale, pvel, die, color, alpha);
return particle_new (type, texnum, porg, scale, pvel, die, color, alpha, vec3_origin, vec3_origin);
}
/*
@ -226,7 +231,7 @@ R_ReadPointFile_f (void)
c++;
if (!particle_new (pt_static, part_tex_dot, org, 1.5, vec3_origin,
99999, (-c) & 15, 255)) {
99999, (-c) & 15, 255, vec3_origin, vec3_origin)) {
Con_Printf ("Not enough free particles\n");
break;
}
@ -281,7 +286,7 @@ R_RunSparkEffect (vec3_t org, int count, int ofuzz)
particle_new (pt_smokecloud, part_tex_smoke[rand () & 7], org,
(ofuzz / 8) * .75, vec3_origin, cl.time + 99,
12 + (rand () & 3), 96);
12 + (rand () & 3), 96, vec3_origin, vec3_origin);
while (count--)
particle_new_random (pt_fallfadespark, part_tex_spark, org, ofuzz * .75,
1, 96, cl.time + 5, ramp[rand () % 6],
@ -312,7 +317,8 @@ R_BloodPuff (vec3_t org, int count)
return;
particle_new (pt_bloodcloud, part_tex_smoke[rand () & 7], org, 9,
vec3_origin, cl.time + 99, 68 + (rand () & 3), 128);
vec3_origin, cl.time + 99, 68 + (rand () & 3), 128,
vec3_origin, vec3_origin);
}
/*
@ -362,7 +368,7 @@ R_RunParticleEffect (vec3_t org, int color, int count)
}
particle_new (pt_grav, part_tex_dot, porg, 1.5, vec3_origin,
(cl.time + 0.1 * (rand () % 5)),
(color & ~7) + (rand () & 7), 255);
(color & ~7) + (rand () & 7), 255, vec3_origin, vec3_origin);
}
}
@ -413,7 +419,7 @@ R_LavaSplash (vec3_t org)
VectorScale (dir, vel, pvel);
particle_new (pt_grav, part_tex_dot, porg, 3, pvel,
(cl.time + 2 + (rand () & 31) * 0.02),
(224 + (rand () & 7)), 193);
(224 + (rand () & 7)), 193, vec3_origin, vec3_origin);
}
}
}
@ -447,7 +453,7 @@ R_TeleportSplash (vec3_t org)
VectorScale (dir, vel, pvel);
particle_new (pt_grav, part_tex_spark, porg, 0.6, pvel,
(cl.time + 0.2 + (rand () & 7) * 0.02),
(7 + (rand () & 7)), 255);
(7 + (rand () & 7)), 255, vec3_origin, vec3_origin);
}
}
@ -458,7 +464,7 @@ R_RocketTrail (int type, entity_t *ent)
float len;
int j, ptex;
ptype_t ptype;
vec3_t porg, pvel;
vec3_t porg, pvel, up, right;
float pdie, pscale;
byte palpha, pcolor;
@ -471,6 +477,8 @@ R_RocketTrail (int type, entity_t *ent)
VectorSubtract (ent->origin, ent->old_origin, vec);
len = VectorNormalize (vec);
while (len > 0) {
VectorCopy (vec3_origin, up);
VectorCopy (vec3_origin, right);
VectorCopy (vec3_origin, pvel);
pdie = cl.time + 2;
ptype = pt_static;
@ -489,11 +497,12 @@ R_RocketTrail (int type, entity_t *ent)
common_rocket_gren_trail:
len -= 4;
ptex = part_tex_smoke[rand () & 7];
pscale = lhrandom (6, 9);
ptex = part_tex_smoke_ring[rand () & 7];
pscale = lhrandom (10, 15);
palpha = 48 + (rand () & 31);
ptype = pt_smoke;
pdie = cl.time + 1;
VectorVectors(vec, right, up);
VectorCopy (ent->old_origin, porg);
break;
case 4: // slight blood
@ -548,7 +557,8 @@ R_RocketTrail (int type, entity_t *ent)
VectorAdd (ent->old_origin, vec, ent->old_origin);
particle_new (ptype, ptex, porg, pscale, pvel, pdie, pcolor, palpha);
particle_new (ptype, ptex, porg, pscale, pvel, pdie, pcolor, palpha,
up, right);
}
}
@ -564,15 +574,18 @@ R_DrawParticles (void)
float minparticledist;
unsigned char *at;
byte alpha;
vec3_t up, right;
float scale;
particle_t *part;
vec3_t up, right, o_up, o_right;
int activeparticles, maxparticle, j, k, vnum;
varray_t vertex_array[4];
// LordHavoc: particles should not affect zbuffer
glDepthMask (GL_FALSE);
VectorScale (up, 1.5, o_up);
VectorScale (right, 1.5, o_right);
glInterleavedArrays (GL_T2F_C4UB_V3F, 0, (void *) &(vertex_array[0]));
vertex_array[0].texcoord[0] = 0; vertex_array[0].texcoord[1] = 1;
@ -582,9 +595,6 @@ R_DrawParticles (void)
vnum = 0;
VectorScale (vup, 1.5, up);
VectorScale (vright, 1.5, right);
grav = (fast_grav = host_frametime * 800) * 0.05;
dvel = 4 * host_frametime;
@ -611,6 +621,14 @@ R_DrawParticles (void)
at = (byte *) & d_8to24table[(byte) part->color];
alpha = part->alpha;
if (VectorCompare(part->up, part->right)) {
VectorCopy(o_up, up);
VectorCopy(o_right, right);
} else {
VectorCopy(part->up, up);
VectorCopy(part->right, right);
}
if (lighthalf) {
vertex_array[0].color[0] = (byte) ((int) at[0] >> 1);
vertex_array[0].color[1] = (byte) ((int) at[1] >> 1);
@ -680,7 +698,7 @@ R_DrawParticles (void)
case pt_smoke:
if ((part->alpha -= host_frametime * 90) < 1)
part->die = -1;
part->scale += host_frametime * 6;
part->scale += host_frametime * 10;
part->org[2] += host_frametime * 30;
break;
case pt_smokecloud:

View file

@ -40,10 +40,12 @@ extern void noise_plasma(unsigned char *noise, int size);
static void GDT_InitDotParticleTexture (void);
static void GDT_InitSparkParticleTexture (void);
static void GDT_InitSmokeParticleTexture (void);
static void GDT_InitSmokeRingParticleTexture (void);
int part_tex_smoke_ring[8];
int part_tex_smoke[8];
int part_tex_dot;
int part_tex_spark;
int part_tex_smoke[8];
void
GDT_Init (void)
@ -51,6 +53,7 @@ GDT_Init (void)
GDT_InitDotParticleTexture ();
GDT_InitSparkParticleTexture ();
GDT_InitSmokeParticleTexture ();
GDT_InitSmokeRingParticleTexture ();
}
static void
@ -152,3 +155,46 @@ GDT_InitSmokeParticleTexture (void)
GL_UNSIGNED_BYTE, data);
}
}
static void
GDT_InitSmokeRingParticleTexture (void)
{
int i, x, y, b;
float dx, dy, c, c2;
byte d, data[32][32][2], noise1[32][32], noise2[32][32];
for (i = 0; i < 8; i++) {
noise_diamondsquare (&noise1[0][0], 32);
noise_plasma (&noise2[0][0], 32);
for (y = 0; y < 32; y++)
{
dy = y - 16;
dy *= dy;
for (x = 0; x < 32; x++) {
dx = x - 16;
dx *= dx;
c = 255 - (dx + dy);
c2 = (dx + dy);
if (c < 1) c = 0;
if (c2 < 1) c2 = 0;
//b = ((c / 255) * (c2 / 255)) * 512;
b = (c * c2) * 512 / (255*255);
if (b < 1) b = 0;
d = (noise1[y][x] + noise2[y][x]) / 3;
if (d > 0) {
data[y][x][0] = 255;
data[y][x][1] = (d * b)/255;
} else {
data[y][x][0] = 255;
data[y][x][1] = 0;
}
}
}
part_tex_smoke_ring[i] = texture_extension_number++;
glBindTexture (GL_TEXTURE_2D, part_tex_smoke_ring[i]);
glTexParameterf (GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameterf (GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexImage2D (GL_TEXTURE_2D, 0, 2, 32, 32, 0, GL_LUMINANCE_ALPHA,
GL_UNSIGNED_BYTE, data);
}
}

View file

@ -198,65 +198,89 @@ void
R_MarkLights (vec3_t lightorigin, dlight_t *light, int bit, mnode_t *node)
{
mplane_t *splitplane;
float dist, l, maxdist;
float ndist, maxdist;
msurface_t *surf;
int i, j, s, t;
vec3_t impact;
int i;
maxdist = light->radius * light->radius;
loc0:
if (node->contents < 0)
return;
splitplane = node->plane;
dist = DotProduct (lightorigin, splitplane->normal) - splitplane->dist;
ndist = DotProduct (lightorigin, splitplane->normal) - splitplane->dist;
if (dist > light->radius) {
if (node->children[0]->contents >= 0) // save some time by not
// pushing another stack
// frame
R_MarkLights (lightorigin, light, bit, node->children[0]);
if (ndist > light->radius) {
// Save time by not pushing another stack frame.
if (node->children[0]->contents >= 0) {
node = node->children[0];
goto loc0;
}
return;
}
if (dist < -light->radius) {
if (node->children[1]->contents >= 0) // save some time by not
// pushing another stack
// frame
R_MarkLights (lightorigin, light, bit, node->children[1]);
if (ndist < -light->radius) {
// Save time by not pushing another stack frame.
if (node->children[1]->contents >= 0) {
node = node->children[1];
goto loc0;
}
return;
}
maxdist = light->radius * light->radius;
// mark the polygons
surf = cl.worldmodel->surfaces + node->firstsurface;
for (i = 0; i < node->numsurfaces; i++, surf++) {
// LordHavoc: MAJOR dynamic light speedup here, eliminates marking of
// surfaces that are too far away from light, thus preventing
// unnecessary renders and uploads
for (j = 0; j < 3; j++)
impact[j] = lightorigin[j] - surf->plane->normal[j] * dist;
int s, t;
float l, dist, dist2;
vec3_t impact;
// clamp center of light to corner and check brightness
l =
DotProduct (impact,
surf->texinfo->vecs[0]) + surf->texinfo->vecs[0][3] -
surf->texturemins[0];
dist = ndist;
dist2 = dist * dist;
if (dist2 >= maxdist)
continue;
impact[0] = light->origin[0] - surf->plane->normal[0] * dist;
impact[1] = light->origin[1] - surf->plane->normal[1] * dist;
impact[2] = light->origin[2] - surf->plane->normal[2] * dist;
l = DotProduct (impact, surf->texinfo->vecs[0]) +
surf->texinfo->vecs[0][3] - surf->texturemins[0];
s = l + 0.5;
if (s < 0)
s = 0;
else if (s > surf->extents[0])
s = surf->extents[0];
s = l - s;
l =
DotProduct (impact,
surf->texinfo->vecs[1]) + surf->texinfo->vecs[1][3] -
surf->texturemins[1];
l = DotProduct (impact, surf->texinfo->vecs[1]) +
surf->texinfo->vecs[1][3] - surf->texturemins[1];
t = l + 0.5;
if (t < 0)
t = 0;
else if (t > surf->extents[1])
t = surf->extents[1];
t = l - t;
// compare to minimum light
/*
for (j = 0; j < 2; j++) {
d = DotProduct (impact, surf->texinfo->vecs[j]) + surf->texinfo->vecs[j][3] - surf->texturemins[j];
if (d < 0) {
dist2 += d * d;
if (dist2 >= maxdist)
continue;
} else {
d -= surf->extents[j] + 16;
if (d > 0) {
dist2 += d * d;
if (dist2 >= maxdist)
continue;
}
}
}
*/
if ((s * s + t * t + dist * dist) < maxdist) {
if (surf->dlightframe != r_framecount) {
surf->dlightframe = r_framecount;
@ -267,14 +291,117 @@ R_MarkLights (vec3_t lightorigin, dlight_t *light, int bit, mnode_t *node)
}
}
if (node->children[0]->contents >= 0) // save some time by not pushing
// another stack frame
R_MarkLights (lightorigin, light, bit, node->children[0]);
if (node->children[1]->contents >= 0) // save some time by not pushing
// another stack frame
R_MarkLights (lightorigin, light, bit, node->children[1]);
if (node->children[0]->contents >= 0) {
if (node->children[1]->contents >= 0)
R_MarkLights (lightorigin, light, bit, node->children[1]);
node = node->children[0];
goto loc0;
} else if (node->children[1]->contents >= 0) {
node = node->children[1];
goto loc0;
}
}
#if 0
void
R_MarkLights (vec3_t lightorigin, dlight_t *light, int bit, mnode_t *node)
{
mplane_t *splitplane;
float ndist, maxdist;
msurface_t *surf;
int i;
maxdist = light->radius * light->radius;
loc0:
if (node->contents < 0)
return;
splitplane = node->plane;
ndist = DotProduct (lightorigin, splitplane->normal) - splitplane->dist;
if (ndist > light->radius) {
// Save time by not pushing another stack frame.
if (node->children[0]->contents >= 0) {
node = node->children[0];
goto loc0;
}
return;
}
if (ndist < -light->radius) {
// Save time by not pushing another stack frame.
if (node->children[1]->contents >= 0) {
node = node->children[1];
goto loc0;
}
return;
}
// mark the polygons
surf = cl.worldmodel->surfaces + node->firstsurface;
for (i = 0; i < node->numsurfaces; i++, surf++) {
int j, d;
float dist, dist2, impact[3];
if (surf->flags & SURF_PLANEBACK)
dist = -ndist;
else
dist = ndist;
if (dist < -0.25f)
continue;
/*
if (dist < -0.25f && !(surf->flags & SURF_LIGHTBOTHSIDES))
continue;
*/
dist2 = dist * dist;
if (dist2 >= maxdist)
continue;
impact[0] = light->origin[0] - surf->plane->normal[0] * dist;
impact[1] = light->origin[1] - surf->plane->normal[1] * dist;
impact[2] = light->origin[2] - surf->plane->normal[2] * dist;
for (j = 0; j < 2; j++) {
d = DotProduct (impact, surf->texinfo->vecs[j]) + surf->texinfo->vecs[j][3] - surf->texturemins[j];
if (d < 0) {
dist2 += d * d;
if (dist2 >= maxdist)
continue;
} else {
d -= surf->extents[j] + 16;
if (d > 0) {
dist2 += d * d;
if (dist2 >= maxdist)
continue;
}
}
}
if (surf->dlightframe != r_framecount) {
surf->dlightframe = r_framecount;
surf->dlightbits = bit;
} else {
surf->dlightbits |= bit;
}
}
if (node->children[0]->contents >= 0) {
if (node->children[1]->contents >= 0)
R_MarkLights (lightorigin, light, bit, node->children[1]);
node = node->children[0];
goto loc0;
} else if (node->children[1]->contents >= 0) {
node = node->children[1];
goto loc0;
}
}
#endif
/*
R_PushDlights
*/
@ -294,6 +421,7 @@ R_PushDlights (vec3_t entorigin)
if (l->die < cl.time || !l->radius)
continue;
VectorSubtract (l->origin, entorigin, lightorigin);
//R_MarkLights (lightorigin, l, 1 << i, cl.worldmodel->nodes + cl.worldmodel->hulls[0].firstclipnode);
R_MarkLights (lightorigin, l, 1 << i, cl.worldmodel->nodes);
}
}

View file

@ -1015,16 +1015,14 @@ SCR_UpdateScreen (void)
glDisable (GL_TEXTURE_2D);
Cvar_SetValue (brightness, bound (1, brightness->value, 5));
if (lighthalf) { // LordHavoc: render was done at half
// brightness
if (lighthalf) { // LordHavoc: render was done at half brightness
f = brightness->value * 2;
} else {
Cvar_SetValue (brightness, bound (1, brightness->value, 5));
f = brightness->value;
}
if (f >= 1.002) { // Make sure we don't get bit by
// roundoff errors
if (f >= 1.002) { // Make sure we don't get bit by roundoff errors
glBlendFunc (GL_DST_COLOR, GL_ONE);
glBegin (GL_QUADS);
while (f >= 1.002) { // precision