Beispiel #1
0
void batching_add_point_bitmap(primitive_batch *batch, vertex *position, float rad, float angle, float depth)
{
    Assert(batch->get_render_info().prim_type == PRIM_TYPE_POINTS);

    float radius = rad;
    radius *= 1.41421356f;//1/0.707, becase these are the points of a square or width and height rad

    vec3d PNT(position->world);
    vec3d fvec;

    // get the direction from the point to the eye
    vm_vec_sub(&fvec, &View_position, &PNT);
    vm_vec_normalize_safe(&fvec);

    // move the center of the sprite based on the depth parameter
    if ( depth != 0.0f )
        vm_vec_scale_add(&PNT, &PNT, &fvec, depth);

    batch_vertex new_particle;
    vec3d up;

    vm_rot_point_around_line(&up, &vmd_y_vector, angle, &vmd_zero_vector, &vmd_z_vector);

    new_particle.position = position->world;
    new_particle.radius = radius;
    new_particle.uvec = up;

    batch->add_point_sprite(&new_particle);
}
Beispiel #2
0
void batching_add_point_bitmap(primitive_batch *batch, vertex *position, int orient, float rad, float depth)
{
    Assert(batch->get_render_info().prim_type == PRIM_TYPE_POINTS);

    float radius = rad;
    radius *= 1.41421356f;//1/0.707, becase these are the points of a square or width and height rad

    vec3d PNT(position->world);
    vec3d fvec;

    // get the direction from the point to the eye
    vm_vec_sub(&fvec, &View_position, &PNT);
    vm_vec_normalize_safe(&fvec);

    // move the center of the sprite based on the depth parameter
    if ( depth != 0.0f )
        vm_vec_scale_add(&PNT, &PNT, &fvec, depth);

    batch_vertex new_particle;
    vec3d up = {{{ 0.0f, 1.0f, 0.0f }}};

    new_particle.position = position->world;
    new_particle.radius = radius;

    int direction = orient % 4;

    switch ( direction ) {
    case 0:
        up.xyz.x = 0.0f;
        up.xyz.y = 1.0f;
        up.xyz.z = 0.0f;
        break;
    case 1:
        up.xyz.x = 0.0f;
        up.xyz.y = -1.0f;
        up.xyz.z = 0.0f;
        break;
    case 2:
        up.xyz.x = -1.0f;
        up.xyz.y = 0.0f;
        up.xyz.z = 0.0f;
        break;
    case 3:
        up.xyz.x = 1.0f;
        up.xyz.y = 0.0f;
        up.xyz.z = 0.0f;
        break;
    }

    new_particle.uvec = up;

    batch->add_point_sprite(&new_particle);
}
// Creates a bunch of particles. You pass a structure
// rather than a bunch of parameters.
void particle_emit( particle_emitter *pe, int type, int optional_data, float range )
{
	int i, n;

	if ( !Particles_enabled )
		return;

	int n1, n2;

	// Account for detail
	int percent = get_percent(Detail.num_particles);

	//Particle rendering drops out too soon.  Seems to be around 150 m.  Is it detail level controllable?  I'd like it to be 500-1000 
	float min_dist = 125.0f;
	float dist = vm_vec_dist_quick( &pe->pos, &Eye_position ) / range;
	if ( dist > min_dist )	{
		percent = fl2i( i2fl(percent)*min_dist / dist );
		if ( percent < 1 ) {
			return;
		}
	}
	//mprintf(( "Dist = %.1f, percent = %d%%\n", dist, percent ));

	n1 = (pe->num_low*percent)/100;
	n2 = (pe->num_high*percent)/100;

	// How many to emit?
	n = (rand() % (n2-n1+1)) + n1;
	
	if ( n < 1 ) return;


	for (i=0; i<n; i++ )	{
		// Create a particle
		vec3d tmp_vel;
		vec3d normal;				// What normal the particle emit arond

		float radius = (( pe->max_rad - pe->min_rad ) * frand()) + pe->min_rad;

		float speed = (( pe->max_vel - pe->min_vel ) * frand()) + pe->min_vel;

		float life = (( pe->max_life - pe->min_life ) * frand()) + pe->min_life;

		normal.xyz.x = pe->normal.xyz.x + (frand()*2.0f - 1.0f)*pe->normal_variance;
		normal.xyz.y = pe->normal.xyz.y + (frand()*2.0f - 1.0f)*pe->normal_variance;
		normal.xyz.z = pe->normal.xyz.z + (frand()*2.0f - 1.0f)*pe->normal_variance;
		vm_vec_normalize_safe( &normal );
		vm_vec_scale_add( &tmp_vel, &pe->vel, &normal, speed );

		particle_create( &pe->pos, &tmp_vel, life, radius, type, optional_data );
	}
}
void geometry_shader_batcher::draw_bitmap(vertex *position, int orient, float rad, float depth)
{
	rad *= 1.41421356f;//1/0.707, becase these are the points of a square or width and height rad

	vec3d PNT(position->world);
	vec3d fvec;

	// get the direction from the point to the eye
	vm_vec_sub(&fvec, &View_position, &PNT);
	vm_vec_normalize_safe(&fvec);

	// move the center of the sprite based on the depth parameter
	if ( depth != 0.0f )
		vm_vec_scale_add(&PNT, &PNT, &fvec, depth);

	particle_pnt new_particle;
	vec3d up = {{{0.0f, 1.0f, 0.0f}}};

	new_particle.position = position->world;
	new_particle.size = rad;

	int direction = orient % 4;

	if ( direction == 1 ) {
		up.xyz.x = 0.0f;
		up.xyz.y = -1.0f;
		up.xyz.z = 0.0f;
	} else if ( direction == 2 ) {
		up.xyz.x = -1.0f;
		up.xyz.y = 0.0f;
		up.xyz.z = 0.0f;
	} else if ( direction == 3 ) {
		up.xyz.x = 1.0f;
		up.xyz.y = 0.0f;
		up.xyz.z = 0.0f;
	}

	new_particle.up = up;

	vertices.push_back(new_particle);
}
Beispiel #5
0
float g3_draw_laser_htl(vec3d* p0, float width1, vec3d* p1, float width2, int r, int g, int b, uint tmap_flags)
{
	width1 *= 0.5f;
	width2 *= 0.5f;
	vec3d uvec, fvec, rvec, center, reye;

	vm_vec_sub(&fvec, p0, p1);
	vm_vec_normalize_safe(&fvec);

	vm_vec_avg(&center, p0, p1); //needed for the return value only
	vm_vec_sub(&reye, &Eye_position, &center);
	vm_vec_normalize(&reye);

	vm_vec_crossprod(&uvec, &fvec, &reye);
	vm_vec_normalize(&uvec);
	vm_vec_crossprod(&fvec, &uvec, &reye);
	vm_vec_normalize(&fvec);

	//	if(vm_vec_mag_squared(&uvec)==0) uvec.xyz.y = 1.0f; //in case fvec is exactly equal to matrx.rvec, stick some arbitrary value in uvec
	//normalize new perpendicular vector
	//	vm_vec_normalize(&uvec);

	//now recompute right vector, in case it wasn't entirely perpendiclar
	vm_vec_crossprod(&rvec, &uvec, &fvec);

	// Now have uvec, which is up vector and rvec which is the normal
	// of the face.

	int i;
	vec3d start, end;
	vm_vec_scale_add(&start, p0, &fvec, -width1);
	vm_vec_scale_add(&end, p1, &fvec, width2);
	vec3d vecs[4];
	vertex pts[4];
	vertex* ptlist[8] =
	{
		&pts[3],
		&pts[2],
		&pts[1],
		&pts[0],
		&pts[0],
		&pts[1],
		&pts[2],
		&pts[3]
	};

	vm_vec_scale_add(&vecs[0], &start, &uvec, width1);
	vm_vec_scale_add(&vecs[1], &end, &uvec, width2);
	vm_vec_scale_add(&vecs[2], &end, &uvec, -width2);
	vm_vec_scale_add(&vecs[3], &start, &uvec, -width1);

	for (i = 0; i < 4; i++)
	{
		g3_transfer_vertex(&pts[i], &vecs[i]);
	}
	ptlist[0]->u = 0.0f;
	ptlist[0]->v = 0.0f;
	ptlist[1]->u = 1.0f;
	ptlist[1]->v = 0.0f;
	ptlist[2]->u = 1.0f;
	ptlist[2]->v = 1.0f;
	ptlist[3]->u = 0.0f;
	ptlist[3]->v = 1.0f;
	ptlist[0]->r = (ubyte)r;
	ptlist[0]->g = (ubyte)g;
	ptlist[0]->b = (ubyte)b;
	ptlist[0]->a = 255;
	ptlist[1]->r = (ubyte)r;
	ptlist[1]->g = (ubyte)g;
	ptlist[1]->b = (ubyte)b;
	ptlist[1]->a = 255;
	ptlist[2]->r = (ubyte)r;
	ptlist[2]->g = (ubyte)g;
	ptlist[2]->b = (ubyte)b;
	ptlist[2]->a = 255;
	ptlist[3]->r = (ubyte)r;
	ptlist[3]->g = (ubyte)g;
	ptlist[3]->b = (ubyte)b;
	ptlist[3]->a = 255;

	gr_tmapper(4, ptlist, tmap_flags | TMAP_FLAG_RGB | TMAP_FLAG_GOURAUD | TMAP_FLAG_CORRECT);

	return center.xyz.z;
}
void physics_apply_shock(vec3d *direction_vec, float pressure, physics_info *pi, matrix *orient, vec3d *min, vec3d *max, float radius)
{
	vec3d normal;
	vec3d local_torque, temp_torque, torque;
	vec3d impact_vec;
	vec3d area;
	vec3d sin;

	if (radius > MAX_RADIUS) {
		return;
	}

	vm_vec_normalize_safe ( direction_vec );

	area.xyz.x = (max->xyz.y - min->xyz.z) * (max->xyz.z - min->xyz.z);
	area.xyz.y = (max->xyz.x - min->xyz.x) * (max->xyz.z - min->xyz.z);
	area.xyz.z = (max->xyz.x - min->xyz.x) * (max->xyz.y - min->xyz.y);

	normal.xyz.x = vm_vec_dotprod( direction_vec, &orient->vec.rvec );
	normal.xyz.y = vm_vec_dotprod( direction_vec, &orient->vec.uvec );
	normal.xyz.z = vm_vec_dotprod( direction_vec, &orient->vec.fvec );

	sin.xyz.x = fl_sqrt( fl_abs(1.0f - normal.xyz.x*normal.xyz.x) );
	sin.xyz.y = fl_sqrt( fl_abs(1.0f - normal.xyz.y*normal.xyz.y) );
	sin.xyz.z = fl_sqrt( fl_abs(1.0f - normal.xyz.z*normal.xyz.z) );

	vm_vec_make( &torque, 0.0f, 0.0f, 0.0f );

	// find the torque exerted due to the shockwave hitting each face
	//  model the effect of the shockwave as if the shockwave were a plane of projectiles,
	//  all moving in the direction direction_vec.  then find the torque as the cross prod
	//  of the force (pressure * area * normal * sin * scale * mass)
	//  normal takes account the fraction of the surface exposed to the shockwave
	//  the sin term is not technically needed but "feels" better
	//  scale factors out the increase in area with larger objects
	//  more massive objects get less rotation

	// find torque due to forces on the right/left face
	if ( normal.xyz.x < 0.0f )		// normal < 0, hits the right face
		vm_vec_copy_scale( &impact_vec, &orient->vec.rvec, max->xyz.x * pressure * area.xyz.x *  normal.xyz.x * sin.xyz.x / pi->mass );
	else								// normal > 0, hits the left face
		vm_vec_copy_scale( &impact_vec, &orient->vec.rvec, min->xyz.x * pressure * area.xyz.x * -normal.xyz.x * sin.xyz.x / pi->mass );

	vm_vec_crossprod( &temp_torque, &impact_vec, direction_vec );
	vm_vec_add2( &torque, &temp_torque );

	// find torque due to forces on the up/down face
	if ( normal.xyz.y < 0.0f )
		vm_vec_copy_scale( &impact_vec, &orient->vec.uvec, max->xyz.y * pressure * area.xyz.y *  normal.xyz.y * sin.xyz.y / pi->mass );
	else
		vm_vec_copy_scale( &impact_vec, &orient->vec.uvec, min->xyz.y * pressure * area.xyz.y * -normal.xyz.y * sin.xyz.y / pi->mass );

	vm_vec_crossprod( &temp_torque, &impact_vec, direction_vec );
	vm_vec_add2( &torque, &temp_torque );

	// find torque due to forces on the forward/backward face
	if ( normal.xyz.z < 0.0f )
		vm_vec_copy_scale( &impact_vec, &orient->vec.fvec, max->xyz.z * pressure * area.xyz.z *  normal.xyz.z * sin.xyz.z / pi->mass );
	else
		vm_vec_copy_scale( &impact_vec, &orient->vec.fvec, min->xyz.z * pressure * area.xyz.z * -normal.xyz.z * sin.xyz.z / pi->mass );

	vm_vec_crossprod( &temp_torque, &impact_vec, direction_vec );
	vm_vec_add2( &torque, &temp_torque );

	// compute delta rotvel, scale according to blast and radius
	float scale;

	if (radius < MIN_RADIUS) {
		scale = 1.0f;
	} else {
		scale = (MAX_RADIUS - radius)/(MAX_RADIUS-MIN_RADIUS);
	}

	// set shockwave shake amplitude, duration, flag
	pi->shockwave_shake_amp = (float)(MAX_SHAKE*(pressure/STD_PRESSURE)*scale);
	pi->shockwave_decay = timestamp( SW_BLAST_DURATION );
	pi->flags |= PF_IN_SHOCKWAVE;

	// safety dance
	if (!(IS_VEC_NULL_SQ_SAFE(&torque))) {
		vec3d delta_rotvel;
		vm_vec_rotate( &local_torque, &torque, orient );
		vm_vec_copy_normalize(&delta_rotvel, &local_torque);
		
		vm_vec_scale(&delta_rotvel, (float)(MAX_ROTVEL*(pressure/STD_PRESSURE)*scale));
		// nprintf(("Physics", "rotvel scale %f\n", (MAX_ROTVEL*(pressure/STD_PRESSURE)*scale)));
		vm_vec_add2(&pi->rotvel, &delta_rotvel);
	}

	// set reduced translational damping, set flags
	float velocity_scale = (float)MAX_VEL*scale;
	pi->flags |= PF_REDUCED_DAMP;
	update_reduced_damp_timestamp( pi, velocity_scale*pi->mass );
	vm_vec_scale_add2( &pi->vel, direction_vec, velocity_scale );
	vm_vec_rotate(&pi->prev_ramp_vel, &pi->vel, orient);	// set so velocity will ramp starting from current speed

	// check that kick from shockwave is not too large
	if (!(pi->flags & PF_USE_VEL) && (vm_vec_mag_squared(&pi->vel) > MAX_SHIP_SPEED*MAX_SHIP_SPEED)) {
		// Get DaveA
		nprintf(("Physics", "speed reset in physics_apply_shock [speed: %f]\n", vm_vec_mag(&pi->vel)));
		vm_vec_normalize(&pi->vel);
		vm_vec_scale(&pi->vel, (float)RESET_SHIP_SPEED);
	}
}
Beispiel #7
0
void batching_add_beam_internal(primitive_batch *batch, vec3d *start, vec3d *end, float width, color *clr, float offset)
{
    Assert(batch->get_render_info().prim_type == PRIM_TYPE_TRIS);

    vec3d p[4];
    batch_vertex verts[6];

    vec3d fvec, uvecs, uvece, evec;

    vm_vec_sub(&fvec, start, end);
    vm_vec_normalize_safe(&fvec);

    vm_vec_sub(&evec, &View_position, start);
    vm_vec_normalize_safe(&evec);

    vm_vec_cross(&uvecs, &fvec, &evec);
    vm_vec_normalize_safe(&uvecs);

    vm_vec_sub(&evec, &View_position, end);
    vm_vec_normalize_safe(&evec);

    vm_vec_cross(&uvece, &fvec, &evec);
    vm_vec_normalize_safe(&uvece);

    vm_vec_scale_add(&p[0], start, &uvecs, width);
    vm_vec_scale_add(&p[1], end, &uvece, width);
    vm_vec_scale_add(&p[2], end, &uvece, -width);
    vm_vec_scale_add(&p[3], start, &uvecs, -width);

    //move all the data from the vecs into the verts
    //tri 1
    verts[0].position = p[3];
    verts[1].position = p[2];
    verts[2].position = p[1];

    //tri 2
    verts[3].position = p[3];
    verts[4].position = p[1];
    verts[5].position = p[0];

    //set up the UV coords
    //tri 1
    verts[0].tex_coord.u = 0.0f;
    verts[0].tex_coord.v = 0.0f;
    verts[1].tex_coord.u = 1.0f;
    verts[1].tex_coord.v = 0.0f;
    verts[2].tex_coord.u = 1.0f;
    verts[2].tex_coord.v = 1.0f;

    //tri 2
    verts[3].tex_coord.u = 0.0f;
    verts[3].tex_coord.v = 0.0f;
    verts[4].tex_coord.u = 1.0f;
    verts[4].tex_coord.v = 1.0f;
    verts[5].tex_coord.u = 0.0f;
    verts[5].tex_coord.v = 1.0f;

    for(int i = 0; i < 6; i++) {
        verts[i].r = clr->red;
        verts[i].g = clr->green;
        verts[i].b = clr->blue;
        verts[i].a = clr->alpha;

        if(offset > 0.0f) {
            verts[i].radius = offset;
        } else {
            verts[i].radius = width;
        }
    }

    batch->add_triangle(&verts[0], &verts[1], &verts[2]);
    batch->add_triangle(&verts[3], &verts[4], &verts[5]);
}
Beispiel #8
0
void batching_add_laser_internal(primitive_batch *batch, vec3d *p0, float width1, vec3d *p1, float width2, int r, int g, int b)
{
    Assert(batch->get_render_info().prim_type == PRIM_TYPE_TRIS);

    width1 *= 0.5f;
    width2 *= 0.5f;

    vec3d uvec, fvec, rvec, center, reye;

    vm_vec_sub( &fvec, p0, p1 );
    vm_vec_normalize_safe( &fvec );

    vm_vec_avg( &center, p0, p1 ); // needed for the return value only
    vm_vec_sub(&reye, &Eye_position, &center);
    vm_vec_normalize(&reye);

    // compute the up vector
    vm_vec_cross(&uvec, &fvec, &reye);
    vm_vec_normalize_safe(&uvec);
    // ... the forward vector
    vm_vec_cross(&fvec, &uvec, &reye);
    vm_vec_normalize_safe(&fvec);
    // now recompute right vector, in case it wasn't entirely perpendiclar
    vm_vec_cross(&rvec, &uvec, &fvec);

    // Now have uvec, which is up vector and rvec which is the normal
    // of the face.

    vec3d start, end;

    vm_vec_scale_add(&start, p0, &fvec, -width1);
    vm_vec_scale_add(&end, p1, &fvec, width2);

    vec3d vecs[4];
    batch_vertex verts[6];

    vm_vec_scale_add( &vecs[0], &end, &uvec, width2 );
    vm_vec_scale_add( &vecs[1], &start, &uvec, width1 );
    vm_vec_scale_add( &vecs[2], &start, &uvec, -width1 );
    vm_vec_scale_add( &vecs[3], &end, &uvec, -width2 );

    verts[0].position = vecs[0];
    verts[1].position = vecs[1];
    verts[2].position = vecs[2];

    verts[3].position = vecs[0];
    verts[4].position = vecs[2];
    verts[5].position = vecs[3];

    verts[0].tex_coord.u = 1.0f;
    verts[0].tex_coord.v = 0.0f;
    verts[1].tex_coord.u = 0.0f;
    verts[1].tex_coord.v = 0.0f;
    verts[2].tex_coord.u = 0.0f;
    verts[2].tex_coord.v = 1.0f;

    verts[3].tex_coord.u = 1.0f;
    verts[3].tex_coord.v = 0.0f;
    verts[4].tex_coord.u = 0.0f;
    verts[4].tex_coord.v = 1.0f;
    verts[5].tex_coord.u = 1.0f;
    verts[5].tex_coord.v = 1.0f;

    verts[0].r = (ubyte)r;
    verts[0].g = (ubyte)g;
    verts[0].b = (ubyte)b;
    verts[0].a = 255;
    verts[1].r = (ubyte)r;
    verts[1].g = (ubyte)g;
    verts[1].b = (ubyte)b;
    verts[1].a = 255;
    verts[2].r = (ubyte)r;
    verts[2].g = (ubyte)g;
    verts[2].b = (ubyte)b;
    verts[2].a = 255;
    verts[3].r = (ubyte)r;
    verts[3].g = (ubyte)g;
    verts[3].b = (ubyte)b;
    verts[3].a = 255;
    verts[4].r = (ubyte)r;
    verts[4].g = (ubyte)g;
    verts[4].b = (ubyte)b;
    verts[4].a = 255;
    verts[5].r = (ubyte)r;
    verts[5].g = (ubyte)g;
    verts[5].b = (ubyte)b;
    verts[5].a = 255;

    batch->add_triangle(&verts[0], &verts[1], &verts[2]);
    batch->add_triangle(&verts[3], &verts[4], &verts[5]);
}
Beispiel #9
0
void batching_add_bitmap_rotated_internal(primitive_batch *batch, vertex *pnt, float angle, float rad, color *clr, float depth)
{
    Assert(batch->get_render_info().prim_type == PRIM_TYPE_TRIS);

    float radius = rad;
    rad *= 1.41421356f;//1/0.707, becase these are the points of a square or width and height rad

    extern float Physics_viewer_bank;
    angle -= Physics_viewer_bank;

    if ( angle < 0.0f )
        angle += PI2;
    else if ( angle > PI2 )
        angle -= PI2;

    vec3d PNT(pnt->world);
    vec3d p[4];
    vec3d fvec, rvec, uvec;
    batch_vertex verts[6];

    vm_vec_sub(&fvec, &View_position, &PNT);
    vm_vec_normalize_safe(&fvec);

    vm_rot_point_around_line(&uvec, &View_matrix.vec.uvec, angle, &vmd_zero_vector, &View_matrix.vec.fvec);

    vm_vec_cross(&rvec, &View_matrix.vec.fvec, &uvec);
    vm_vec_normalize_safe(&rvec);
    vm_vec_cross(&uvec, &View_matrix.vec.fvec, &rvec);

    vm_vec_scale_add(&PNT, &PNT, &fvec, depth);
    vm_vec_scale_add(&p[0], &PNT, &rvec, rad);
    vm_vec_scale_add(&p[2], &PNT, &rvec, -rad);

    vm_vec_scale_add(&p[1], &p[2], &uvec, rad);
    vm_vec_scale_add(&p[3], &p[0], &uvec, -rad);
    vm_vec_scale_add(&p[0], &p[0], &uvec, rad);
    vm_vec_scale_add(&p[2], &p[2], &uvec, -rad);


    //move all the data from the vecs into the verts
    //tri 1
    verts[5].position = p[3];
    verts[4].position = p[2];
    verts[3].position = p[1];

    //tri 2
    verts[2].position = p[3];
    verts[1].position = p[1];
    verts[0].position = p[0];

    //tri 1
    verts[5].tex_coord.u = 0.0f;
    verts[5].tex_coord.v = 0.0f;
    verts[4].tex_coord.u = 1.0f;
    verts[4].tex_coord.v = 0.0f;
    verts[3].tex_coord.u = 1.0f;
    verts[3].tex_coord.v = 1.0f;

    //tri 2
    verts[2].tex_coord.u = 0.0f;
    verts[2].tex_coord.v = 0.0f;
    verts[1].tex_coord.u = 1.0f;
    verts[1].tex_coord.v = 1.0f;
    verts[0].tex_coord.u = 0.0f;
    verts[0].tex_coord.v = 1.0f;

    for (int i = 0; i < 6 ; i++) {
        verts[i].r = clr->red;
        verts[i].g = clr->green;
        verts[i].b = clr->blue;
        verts[i].a = clr->alpha;

        verts[i].radius = radius;
    }

    batch->add_triangle(&verts[0], &verts[1], &verts[2]);
    batch->add_triangle(&verts[3], &verts[4], &verts[5]);
}
void trail_render( trail * trailp )
{
	int sections[NUM_TRAIL_SECTIONS];
	int num_sections = 0;
	int i;
	vec3d topv, botv, *fvec, last_pos, tmp_fvec;
	vertex  top, bot;
	int nv = 0;
	float w;
	ubyte l;
	vec3d centerv;

	if (trailp->tail == trailp->head)
		return;

	// if this trail is on the player ship, and he's in any padlock view except rear view, don't draw	
	if ( (Player_ship != NULL) && trail_is_on_ship(trailp, Player_ship) &&
		(Viewer_mode & (VM_PADLOCK_UP | VM_PADLOCK_LEFT | VM_PADLOCK_RIGHT)) )
	{
		return;
	}

	trail_info *ti	= &trailp->info;

	int n = trailp->tail;

	do	{
		n--;

		if (n < 0)
			n = NUM_TRAIL_SECTIONS-1;

		if (trailp->val[n] > 1.0f)
			break;

		sections[num_sections++] = n;
	} while ( n != trailp->head );

	if (num_sections <= 0)
		return;

	Assertion(ti->texture.bitmap_id != -1, "Weapon trail %s could not be loaded", ti->texture.filename); // We can leave this as an assert, but tell them how to fix it. --Chief

	memset( &top, 0, sizeof(vertex) );
	memset( &bot, 0, sizeof(vertex) );

	// it's a tristrip, so allocate for 2+1
	allocate_trail_verts((num_sections * 2) + 1);

	float w_size = (ti->w_end - ti->w_start);
	float a_size = (ti->a_end - ti->a_start);
	int num_faded_sections = ti->n_fade_out_sections;

	for (i = 0; i < num_sections; i++) {
		n = sections[i];
		float init_fade_out = 1.0f;

		if ((num_faded_sections > 0) && (i < num_faded_sections)) {
			init_fade_out = ((float) i) / (float) num_faded_sections;
		}

		w = trailp->val[n] * w_size + ti->w_start;
		if (init_fade_out != 1.0f) {
			l = (ubyte)fl2i((trailp->val[n] * a_size + ti->a_start) * 255.0f * init_fade_out * init_fade_out);
		} else {
			l = (ubyte)fl2i((trailp->val[n] * a_size + ti->a_start) * 255.0f);
		}

		if ( i == 0 )	{
			if ( num_sections > 1 )	{
				vm_vec_sub(&tmp_fvec, &trailp->pos[n], &trailp->pos[sections[i+1]] );
				vm_vec_normalize_safe(&tmp_fvec);
				fvec = &tmp_fvec;
			} else {
				fvec = &tmp_fvec;
				fvec->xyz.x = 0.0f;
				fvec->xyz.y = 0.0f;
				fvec->xyz.z = 1.0f;
			}
		} else {
			vm_vec_sub(&tmp_fvec, &last_pos, &trailp->pos[n] );
			vm_vec_normalize_safe(&tmp_fvec);
			fvec = &tmp_fvec;
		}

		trail_calc_facing_pts( &topv, &botv, fvec, &trailp->pos[n], w );

		if ( !Cmdline_nohtl ) {
			g3_transfer_vertex( &top, &topv );
			g3_transfer_vertex( &bot, &botv );
		} else {
			g3_rotate_vertex( &top, &topv );
			g3_rotate_vertex( &bot, &botv );
		}

		top.a = bot.a = l;	

		if (i > 0) {
			float U = i2fl(i);

			if (i == num_sections-1) {
				// Last one...
				vm_vec_avg( &centerv, &topv, &botv );

				if ( !Cmdline_nohtl )
					g3_transfer_vertex( &Trail_v_list[nv+2], &centerv );
				else
					g3_rotate_vertex( &Trail_v_list[nv+2], &centerv );

				Trail_v_list[nv].a = l;	

				Trail_v_list[nv].texture_position.u = U;
				Trail_v_list[nv].texture_position.v = 1.0f; 
				Trail_v_list[nv].r = Trail_v_list[nv].g = Trail_v_list[nv].b = l;
				nv++;

				Trail_v_list[nv].texture_position.u = U;
				Trail_v_list[nv].texture_position.v = 0.0f; 
				Trail_v_list[nv].r = Trail_v_list[nv].g = Trail_v_list[nv].b = l;
				nv++;

				Trail_v_list[nv].texture_position.u = U + 1.0f;
				Trail_v_list[nv].texture_position.v = 0.5f;
				Trail_v_list[nv].r = Trail_v_list[nv].g = Trail_v_list[nv].b = 0;
				nv++;
			} else {
				Trail_v_list[nv].texture_position.u = U;
				Trail_v_list[nv].texture_position.v = 1.0f; 
				Trail_v_list[nv].r = Trail_v_list[nv].g = Trail_v_list[nv].b = l;
				nv++;

				Trail_v_list[nv].texture_position.u = U;
				Trail_v_list[nv].texture_position.v = 0.0f; 
				Trail_v_list[nv].r = Trail_v_list[nv].g = Trail_v_list[nv].b = l;
				nv++;
			}
		}

		last_pos = trailp->pos[n];
		Trail_v_list[nv] = top;
		Trail_v_list[nv+1] = bot;
	}

	if ( !nv )
		return;

	if (nv < 3)
		Error( LOCATION, "too few verts in trail render\n" );

	// there should always be three verts in the last section and 2 everyware else, therefore there should always be an odd number of verts
	if ( (nv % 2) != 1 )
		Warning( LOCATION, "even number of verts in trail render\n" );

	profile_begin("Trail Draw");
	gr_set_bitmap( ti->texture.bitmap_id, GR_ALPHABLEND_FILTER, GR_BITBLT_MODE_NORMAL, 1.0f );
	gr_render(nv, Trail_v_list, TMAP_FLAG_TEXTURED | TMAP_FLAG_ALPHA | TMAP_FLAG_GOURAUD | TMAP_FLAG_RGB | TMAP_HTL_3D_UNLIT | TMAP_FLAG_TRISTRIP);
	profile_end("Trail Draw");
}
Beispiel #11
0
void batching_add_bitmap_internal(primitive_batch *batch, vertex *pnt, int orient, float rad, color *clr, float depth)
{
    Assert(batch->get_render_info().prim_type == PRIM_TYPE_TRIS);

    float radius = rad;
    rad *= 1.41421356f;//1/0.707, becase these are the points of a square or width and height rad

    vec3d PNT(pnt->world);
    vec3d p[4];
    vec3d fvec, rvec, uvec;
    batch_vertex verts[6];

    // get the direction from the point to the eye
    vm_vec_sub(&fvec, &View_position, &PNT);
    vm_vec_normalize_safe(&fvec);

    // get an up vector in the general direction of what we want
    uvec = View_matrix.vec.uvec;

    // make a right vector from the f and up vector, this r vec is exactly what we want, so...
    vm_vec_cross(&rvec, &View_matrix.vec.fvec, &uvec);
    vm_vec_normalize_safe(&rvec);

    // fix the u vec with it
    vm_vec_cross(&uvec, &View_matrix.vec.fvec, &rvec);

    // move the center of the sprite based on the depth parameter
    if ( depth != 0.0f )
        vm_vec_scale_add(&PNT, &PNT, &fvec, depth);

    // move one of the verts to the left
    vm_vec_scale_add(&p[0], &PNT, &rvec, rad);

    // and one to the right
    vm_vec_scale_add(&p[2], &PNT, &rvec, -rad);

    // now move all oof the verts to were they need to be
    vm_vec_scale_add(&p[1], &p[2], &uvec, rad);
    vm_vec_scale_add(&p[3], &p[0], &uvec, -rad);
    vm_vec_scale_add(&p[0], &p[0], &uvec, rad);
    vm_vec_scale_add(&p[2], &p[2], &uvec, -rad);

    //move all the data from the vecs into the verts
    //tri 1
    verts[5].position = p[3];
    verts[4].position = p[2];
    verts[3].position = p[1];

    //tri 2
    verts[2].position = p[3];
    verts[1].position = p[1];
    verts[0].position = p[0];

    // set up the UV coords
    if ( orient & 1 ) {
        // tri 1
        verts[5].tex_coord.u = 1.0f;
        verts[4].tex_coord.u = 0.0f;
        verts[3].tex_coord.u = 0.0f;

        // tri 2
        verts[2].tex_coord.u = 1.0f;
        verts[1].tex_coord.u = 0.0f;
        verts[0].tex_coord.u = 1.0f;
    } else {
        // tri 1
        verts[5].tex_coord.u = 0.0f;
        verts[4].tex_coord.u = 1.0f;
        verts[3].tex_coord.u = 1.0f;

        // tri 2
        verts[2].tex_coord.u = 0.0f;
        verts[1].tex_coord.u = 1.0f;
        verts[0].tex_coord.u = 0.0f;
    }

    if ( orient & 2 ) {
        // tri 1
        verts[5].tex_coord.v = 1.0f;
        verts[4].tex_coord.v = 1.0f;
        verts[3].tex_coord.v = 0.0f;

        // tri 2
        verts[2].tex_coord.v = 1.0f;
        verts[1].tex_coord.v = 0.0f;
        verts[0].tex_coord.v = 0.0f;
    } else {
        // tri 1
        verts[5].tex_coord.v = 0.0f;
        verts[4].tex_coord.v = 0.0f;
        verts[3].tex_coord.v = 1.0f;

        // tri 2
        verts[2].tex_coord.v = 0.0f;
        verts[1].tex_coord.v = 1.0f;
        verts[0].tex_coord.v = 1.0f;
    }

    for (int i = 0; i < 6 ; i++) {
        verts[i].r = clr->red;
        verts[i].g = clr->green;
        verts[i].b = clr->blue;
        verts[i].a = clr->alpha;

        verts[i].radius = radius;
    }

    batch->add_triangle(&verts[5], &verts[4], &verts[3]);
    batch->add_triangle(&verts[2], &verts[1], &verts[0]);
}
float g3_draw_laser_htl(vec3d *p0,float width1,vec3d *p1,float width2, int r, int g, int b, uint tmap_flags)
{
	width1 *= 0.5f;
	width2 *= 0.5f;
	vec3d uvec, fvec, rvec, center, reye, rfvec;

	vm_vec_sub( &fvec, p0, p1 );
	vm_vec_normalize_safe( &fvec );
	vm_vec_copy_scale(&rfvec, &fvec, -1.0f);

	vm_vec_avg( &center, p0, p1 ); //needed for the return value only
	vm_vec_sub(&reye, &Eye_position, &center);
	vm_vec_normalize(&reye);

	// code intended to prevent possible null vector normalize issue - start
	if (vm_test_parallel(&reye,&fvec)){
		fvec.xyz.x = -reye.xyz.z;
		fvec.xyz.y = 0.0f;
		fvec.xyz.z = -reye.xyz.x;
	}

	if (vm_test_parallel(&reye,&rfvec)){
		fvec.xyz.x = reye.xyz.z;
		fvec.xyz.y = 0.0f;
		fvec.xyz.z = reye.xyz.x;
	}
	// code intended to prevent possible null vector normalize issue - end

	vm_vec_crossprod(&uvec,&fvec,&reye);
	vm_vec_normalize(&uvec);
	vm_vec_crossprod(&fvec,&uvec,&reye);
	vm_vec_normalize(&fvec);
	 
	//now recompute right vector, in case it wasn't entirely perpendiclar
	vm_vec_crossprod(&rvec,&uvec,&fvec);

	// Now have uvec, which is up vector and rvec which is the normal
	// of the face.

	int i;
	vec3d start, end;
	vm_vec_scale_add(&start, p0, &fvec, -width1);
	vm_vec_scale_add(&end, p1, &fvec, width2);
	vec3d vecs[4];
	vertex pts[4];
	vertex *ptlist[8] = 
	{ &pts[3], &pts[2], &pts[1], &pts[0], 
	  &pts[0], &pts[1], &pts[2], &pts[3]};

	vm_vec_scale_add( &vecs[0], &start, &uvec, width1 );
	vm_vec_scale_add( &vecs[1], &end, &uvec, width2 );
	vm_vec_scale_add( &vecs[2], &end, &uvec, -width2 );
	vm_vec_scale_add( &vecs[3], &start, &uvec, -width1 );

	for (i=0; i<4; i++ )	{
		g3_transfer_vertex( &pts[i], &vecs[i] );
	}
	ptlist[0]->texture_position.u = 0.0f;
	ptlist[0]->texture_position.v = 0.0f;
	ptlist[1]->texture_position.u = 1.0f;
	ptlist[1]->texture_position.v = 0.0f;
	ptlist[2]->texture_position.u = 1.0f;
	ptlist[2]->texture_position.v = 1.0f;
	ptlist[3]->texture_position.u = 0.0f;
	ptlist[3]->texture_position.v = 1.0f;
	ptlist[0]->r = (ubyte)r;
	ptlist[0]->g = (ubyte)g;
	ptlist[0]->b = (ubyte)b;
	ptlist[0]->a = 255;
	ptlist[1]->r = (ubyte)r;
	ptlist[1]->g = (ubyte)g;
	ptlist[1]->b = (ubyte)b;
	ptlist[1]->a = 255;
	ptlist[2]->r = (ubyte)r;
	ptlist[2]->g = (ubyte)g;
	ptlist[2]->b = (ubyte)b;
	ptlist[2]->a = 255;
	ptlist[3]->r = (ubyte)r;
	ptlist[3]->g = (ubyte)g;
	ptlist[3]->b = (ubyte)b;
	ptlist[3]->a = 255;

	gr_tmapper(4, ptlist,tmap_flags | TMAP_FLAG_RGB | TMAP_FLAG_GOURAUD | TMAP_FLAG_CORRECT);
	
	return center.xyz.z;
}
void trail_add_batch(trail * trailp)
{
	int sections[NUM_TRAIL_SECTIONS];
	int num_sections = 0;
	int i;
	vec3d topv, botv, *fvec, last_pos, tmp_fvec;
	vertex  top, bot, top_prev, bot_prev;
	float w;
	ubyte l;
	vec3d centerv;

	if (trailp->tail == trailp->head)
		return;

	// if this trail is on the player ship, and he's in any padlock view except rear view, don't draw	
	if ((Player_ship != NULL) && trail_is_on_ship(trailp, Player_ship) &&
		(Viewer_mode & (VM_PADLOCK_UP | VM_PADLOCK_LEFT | VM_PADLOCK_RIGHT)))
	{
		return;
	}

	trail_info *ti = &trailp->info;

	int n = trailp->tail;

	do	{
		n--;

		if (n < 0)
			n = NUM_TRAIL_SECTIONS - 1;

		if (trailp->val[n] > 1.0f)
			break;

		sections[num_sections++] = n;
	} while (n != trailp->head);

	if (num_sections <= 0)
		return;

	Assertion(ti->texture.bitmap_id != -1, "Weapon trail %s could not be loaded", ti->texture.filename); // We can leave this as an assert, but tell them how to fix it. --Chief

	memset(&top, 0, sizeof(vertex));
	memset(&bot, 0, sizeof(vertex));
	memset(&top_prev, 0, sizeof(vertex));
	memset(&bot_prev, 0, sizeof(vertex));

	float w_size = (ti->w_end - ti->w_start);
	float a_size = (ti->a_end - ti->a_start);
	int num_faded_sections = ti->n_fade_out_sections;

	for (i = 0; i < num_sections; i++) {
		n = sections[i];
		float init_fade_out = 1.0f;

		if ((num_faded_sections > 0) && (i < num_faded_sections)) {
			init_fade_out = ((float)i) / (float)num_faded_sections;
		}

		w = trailp->val[n] * w_size + ti->w_start;
		if (init_fade_out != 1.0f) {
			l = (ubyte)fl2i((trailp->val[n] * a_size + ti->a_start) * 255.0f * init_fade_out * init_fade_out);
		}
		else {
			l = (ubyte)fl2i((trailp->val[n] * a_size + ti->a_start) * 255.0f);
		}

		if (i == 0)	{
			if (num_sections > 1)	{
				vm_vec_sub(&tmp_fvec, &trailp->pos[n], &trailp->pos[sections[i + 1]]);
				vm_vec_normalize_safe(&tmp_fvec);
				fvec = &tmp_fvec;
			}
			else {
				fvec = &tmp_fvec;
				fvec->xyz.x = 0.0f;
				fvec->xyz.y = 0.0f;
				fvec->xyz.z = 1.0f;
			}
		}
		else {
			vm_vec_sub(&tmp_fvec, &last_pos, &trailp->pos[n]);
			vm_vec_normalize_safe(&tmp_fvec);
			fvec = &tmp_fvec;
		}

		trail_calc_facing_pts(&topv, &botv, fvec, &trailp->pos[n], w);

		if (!Cmdline_nohtl) {
			g3_transfer_vertex(&top, &topv);
			g3_transfer_vertex(&bot, &botv);
		}
		else {
			g3_rotate_vertex(&top, &topv);
			g3_rotate_vertex(&bot, &botv);
		}

		top.r = top.g = top.b = l;
		bot.r = bot.g = bot.b = l;
		top.a = bot.a = l;

		float U = i2fl(i);
		
		top.texture_position.u = U;
		top.texture_position.v = 1.0f;

		bot.texture_position.u = U;
		bot.texture_position.v = 0.0f;

		if (i > 0) {
			if (i == num_sections - 1) {
				// Last one...
				vm_vec_avg(&centerv, &topv, &botv);

				vertex center_vert = vertex();

				if (!Cmdline_nohtl)
					g3_transfer_vertex(&center_vert, &centerv);
				else
					g3_rotate_vertex(&center_vert, &centerv);

				center_vert.texture_position.u = U + 1.0f;
				center_vert.texture_position.v = 0.5f;
				center_vert.a = center_vert.r = center_vert.g = center_vert.b = l;

				vertex tri[3];

				tri[1] = top_prev;
				tri[2] = bot_prev;
				tri[0] = center_vert;

				batch_add_tri(
					ti->texture.bitmap_id,
					TMAP_FLAG_TEXTURED | TMAP_FLAG_ALPHA | TMAP_FLAG_GOURAUD | TMAP_FLAG_RGB | TMAP_HTL_3D_UNLIT,
					tri,
					1.0f
				);
			} else {
				vertex quad[4];

				quad[0] = top_prev;
				quad[1] = bot_prev;
				quad[2] = bot;
				quad[3] = top;

				batch_add_quad(
					ti->texture.bitmap_id, 
					TMAP_FLAG_TEXTURED | TMAP_FLAG_ALPHA | TMAP_FLAG_GOURAUD | TMAP_FLAG_RGB | TMAP_HTL_3D_UNLIT,
					quad,
					1.0f
				);
			}
		}

		last_pos = trailp->pos[n];
		top_prev = top;
		bot_prev = bot;
	}
}
float geometry_batcher::draw_laser(vec3d *p0, float width1, vec3d *p1, float width2, int r, int g, int b)
{
	width1 *= 0.5f;
	width2 *= 0.5f;

	vec3d uvec, fvec, rvec, center, reye;

	vm_vec_sub( &fvec, p0, p1 );
	vm_vec_normalize_safe( &fvec );

	vm_vec_avg( &center, p0, p1 ); // needed for the return value only
	vm_vec_sub(&reye, &Eye_position, &center);
	vm_vec_normalize(&reye);

	// compute the up vector
	vm_vec_cross(&uvec, &fvec, &reye);
	vm_vec_normalize_safe(&uvec);
	// ... the forward vector
	vm_vec_cross(&fvec, &uvec, &reye);
	vm_vec_normalize_safe(&fvec);
	// now recompute right vector, in case it wasn't entirely perpendiclar
	vm_vec_cross(&rvec, &uvec, &fvec);

	// Now have uvec, which is up vector and rvec which is the normal
	// of the face.

	vec3d start, end;

	vm_vec_scale_add(&start, p0, &fvec, -width1);
	vm_vec_scale_add(&end, p1, &fvec, width2);

	vec3d vecs[4];

	vertex *pts = &vert[n_to_render * 3];

	vm_vec_scale_add( &vecs[0], &end, &uvec, width2 );
	vm_vec_scale_add( &vecs[1], &start, &uvec, width1 );
	vm_vec_scale_add( &vecs[2], &start, &uvec, -width1 );
	vm_vec_scale_add( &vecs[3], &end, &uvec, -width2 );

	g3_transfer_vertex( &pts[0], &vecs[0] );
	g3_transfer_vertex( &pts[1], &vecs[1] );
	g3_transfer_vertex( &pts[2], &vecs[2] );

	g3_transfer_vertex( &pts[3], &vecs[0] );
	g3_transfer_vertex( &pts[4], &vecs[2] );
	g3_transfer_vertex( &pts[5], &vecs[3] );

	pts[0].texture_position.u = 1.0f;
	pts[0].texture_position.v = 0.0f;
	pts[1].texture_position.u = 0.0f;
	pts[1].texture_position.v = 0.0f;
	pts[2].texture_position.u = 0.0f;
	pts[2].texture_position.v = 1.0f;

	pts[3].texture_position.u = 1.0f;
	pts[3].texture_position.v = 0.0f;
	pts[4].texture_position.u = 0.0f;
	pts[4].texture_position.v = 1.0f;
	pts[5].texture_position.u = 1.0f;
	pts[5].texture_position.v = 1.0f;

	pts[0].r = (ubyte)r;
	pts[0].g = (ubyte)g;
	pts[0].b = (ubyte)b;
	pts[0].a = 255;
	pts[1].r = (ubyte)r;
	pts[1].g = (ubyte)g;
	pts[1].b = (ubyte)b;
	pts[1].a = 255;
	pts[2].r = (ubyte)r;
	pts[2].g = (ubyte)g;
	pts[2].b = (ubyte)b;
	pts[2].a = 255;
	pts[3].r = (ubyte)r;
	pts[3].g = (ubyte)g;
	pts[3].b = (ubyte)b;
	pts[3].a = 255;
	pts[4].r = (ubyte)r;
	pts[4].g = (ubyte)g;
	pts[4].b = (ubyte)b;
	pts[4].a = 255;
	pts[5].r = (ubyte)r;
	pts[5].g = (ubyte)g;
	pts[5].b = (ubyte)b;
	pts[5].a = 255;


	n_to_render += 2;
	use_radius = false;

	return center.xyz.z;
}
void geometry_batcher::draw_beam(vec3d *start, vec3d *end, float width, float intensity, float offset)
{
	vec3d p[4];
	vertex *P = &vert[n_to_render * 3];
	float *R = &radius_list[n_to_render * 3];

	vec3d fvec, uvecs, uvece, evec;

	vm_vec_sub(&fvec, start, end);
	vm_vec_normalize_safe(&fvec);

	vm_vec_sub(&evec, &View_position, start);
	vm_vec_normalize_safe(&evec);

	vm_vec_cross(&uvecs, &fvec, &evec);
	vm_vec_normalize_safe(&uvecs);

	vm_vec_sub(&evec, &View_position, end);
	vm_vec_normalize_safe(&evec);

	vm_vec_cross(&uvece, &fvec, &evec);
	vm_vec_normalize_safe(&uvece);


	vm_vec_scale_add(&p[0], start, &uvecs, width);
	vm_vec_scale_add(&p[1], end, &uvece, width);
	vm_vec_scale_add(&p[2], end, &uvece, -width);
	vm_vec_scale_add(&p[3], start, &uvecs, -width);


	//move all the data from the vecs into the verts
	//tri 1
	g3_transfer_vertex(&P[0], &p[3]);
	g3_transfer_vertex(&P[1], &p[2]);
	g3_transfer_vertex(&P[2], &p[1]);

	//tri 2
	g3_transfer_vertex(&P[3], &p[3]);
	g3_transfer_vertex(&P[4], &p[1]);
	g3_transfer_vertex(&P[5], &p[0]);

	//set up the UV coords
	//tri 1
	P[0].texture_position.u = 0.0f;	P[0].texture_position.v = 0.0f;
	P[1].texture_position.u = 1.0f;	P[1].texture_position.v = 0.0f;
	P[2].texture_position.u = 1.0f;	P[2].texture_position.v = 1.0f;

	//tri 2
	P[3].texture_position.u = 0.0f;	P[3].texture_position.v = 0.0f;
	P[4].texture_position.u = 1.0f;	P[4].texture_position.v = 1.0f;
	P[5].texture_position.u = 0.0f;	P[5].texture_position.v = 1.0f;

	ubyte _color = (ubyte)(255.0f * intensity);

	for(int i = 0; i < 6; i++){
		P[i].r = P[i].g = P[i].b = P[i].a = _color;
		if(offset > 0.0f) {
			R[i] = offset;
		} else {
			R[i] = width;
		}
	}

	n_to_render += 2;
	use_radius = true;
}
void geometry_batcher::draw_bitmap(vertex *pnt, float rad, float angle, float depth)
{
	float radius = rad;
	rad *= 1.41421356f;//1/0.707, becase these are the points of a square or width and height rad

	extern float Physics_viewer_bank;
	angle -= Physics_viewer_bank;

	if ( angle < 0.0f )
		angle += PI2;
	else if ( angle > PI2 )
		angle -= PI2;

	vec3d PNT(pnt->world);
	vec3d p[4];
	vec3d fvec, rvec, uvec;
	vertex *P = &vert[n_to_render * 3];
	float *R = &radius_list[n_to_render * 3];

	vm_vec_sub(&fvec, &View_position, &PNT);
	vm_vec_normalize_safe(&fvec);

	vm_rot_point_around_line(&uvec, &View_matrix.vec.uvec, angle, &vmd_zero_vector, &View_matrix.vec.fvec);

	vm_vec_cross(&rvec, &View_matrix.vec.fvec, &uvec);
	vm_vec_normalize_safe(&rvec);
	vm_vec_cross(&uvec, &View_matrix.vec.fvec, &rvec);

	vm_vec_scale_add(&PNT, &PNT, &fvec, depth);
	vm_vec_scale_add(&p[0], &PNT, &rvec, rad);
	vm_vec_scale_add(&p[2], &PNT, &rvec, -rad);

	vm_vec_scale_add(&p[1], &p[2], &uvec, rad);
	vm_vec_scale_add(&p[3], &p[0], &uvec, -rad);
	vm_vec_scale_add(&p[0], &p[0], &uvec, rad);
	vm_vec_scale_add(&p[2], &p[2], &uvec, -rad);


	//move all the data from the vecs into the verts
	//tri 1
	g3_transfer_vertex(&P[5], &p[3]);
	g3_transfer_vertex(&P[4], &p[2]);
	g3_transfer_vertex(&P[3], &p[1]);

	//tri 2
	g3_transfer_vertex(&P[2], &p[3]);
	g3_transfer_vertex(&P[1], &p[1]);
	g3_transfer_vertex(&P[0], &p[0]);

	//tri 1
	P[5].texture_position.u = 0.0f;	P[5].texture_position.v = 0.0f;
	P[4].texture_position.u = 1.0f;	P[4].texture_position.v = 0.0f;
	P[3].texture_position.u = 1.0f;	P[3].texture_position.v = 1.0f;

	//tri 2
	P[2].texture_position.u = 0.0f;	P[2].texture_position.v = 0.0f;
	P[1].texture_position.u = 1.0f;	P[1].texture_position.v = 1.0f;
	P[0].texture_position.u = 0.0f;	P[0].texture_position.v = 1.0f;

	for (int i = 0; i < 6 ; i++) {
		P[i].r = pnt->r;
		P[i].g = pnt->g;
		P[i].b = pnt->b;
		P[i].a = pnt->a;

		R[i] = radius;
	}

	n_to_render += 2;
}
/*
0----1
|\   |
|  \ |
3----2
*/
void geometry_batcher::draw_bitmap(vertex *pnt, int orient, float rad, float depth)
{
	float radius = rad;
	rad *= 1.41421356f;//1/0.707, becase these are the points of a square or width and height rad

	vec3d PNT(pnt->world);
	vec3d p[4];
	vec3d fvec, rvec, uvec;
	vertex *P = &vert[n_to_render * 3];
	float *R = &radius_list[n_to_render * 3];

	// get the direction from the point to the eye
	vm_vec_sub(&fvec, &View_position, &PNT);
	vm_vec_normalize_safe(&fvec);

	// get an up vector in the general direction of what we want
	uvec = View_matrix.vec.uvec;

	// make a right vector from the f and up vector, this r vec is exactly what we want, so...
	vm_vec_cross(&rvec, &View_matrix.vec.fvec, &uvec);
	vm_vec_normalize_safe(&rvec);

	// fix the u vec with it
	vm_vec_cross(&uvec, &View_matrix.vec.fvec, &rvec);

	// move the center of the sprite based on the depth parameter
	if ( depth != 0.0f )
		vm_vec_scale_add(&PNT, &PNT, &fvec, depth);

	// move one of the verts to the left
	vm_vec_scale_add(&p[0], &PNT, &rvec, rad);

	// and one to the right
	vm_vec_scale_add(&p[2], &PNT, &rvec, -rad);

	// now move all oof the verts to were they need to be
	vm_vec_scale_add(&p[1], &p[2], &uvec, rad);
	vm_vec_scale_add(&p[3], &p[0], &uvec, -rad);
	vm_vec_scale_add(&p[0], &p[0], &uvec, rad);
	vm_vec_scale_add(&p[2], &p[2], &uvec, -rad);


	//move all the data from the vecs into the verts
	//tri 1
	g3_transfer_vertex(&P[5], &p[3]);
	g3_transfer_vertex(&P[4], &p[2]);
	g3_transfer_vertex(&P[3], &p[1]);

	//tri 2
	g3_transfer_vertex(&P[2], &p[3]);
	g3_transfer_vertex(&P[1], &p[1]);
	g3_transfer_vertex(&P[0], &p[0]);

	// set up the UV coords
	if ( orient & 1 ) {
		// tri 1
		P[5].texture_position.u = 1.0f;
		P[4].texture_position.u = 0.0f;
		P[3].texture_position.u = 0.0f;
		// tri 2
		P[2].texture_position.u = 1.0f;
		P[1].texture_position.u = 0.0f;
		P[0].texture_position.u = 1.0f;
	} else {
		// tri 1
		P[5].texture_position.u = 0.0f;
		P[4].texture_position.u = 1.0f;
		P[3].texture_position.u = 1.0f;
		// tri 2
		P[2].texture_position.u = 0.0f;
		P[1].texture_position.u = 1.0f;
		P[0].texture_position.u = 0.0f;
	}

	if ( orient & 2 ) {
		// tri 1
		P[5].texture_position.v = 1.0f;
		P[4].texture_position.v = 1.0f;
		P[3].texture_position.v = 0.0f;
		// tri 2
		P[2].texture_position.v = 1.0f;
		P[1].texture_position.v = 0.0f;
		P[0].texture_position.v = 0.0f;
	} else {
		// tri 1
		P[5].texture_position.v = 0.0f;
		P[4].texture_position.v = 0.0f;
		P[3].texture_position.v = 1.0f;
		// tri 2
		P[2].texture_position.v = 0.0f;
		P[1].texture_position.v = 1.0f;
		P[0].texture_position.v = 1.0f;
	}

	for (int i = 0; i < 6 ; i++) {
		P[i].r = pnt->r;
		P[i].g = pnt->g;
		P[i].b = pnt->b;
		P[i].a = pnt->a;

		R[i] = radius;
	}

	n_to_render += 2;
}