Example #1
0
void Shape3D :: calc_face_normal(int face_index)
{
	GLfloat* fn = new GLfloat[4];
	// calculate face normal
	GLfloat vector1[4], vector2[4];
	vv_sub(verts[faces[face_index][0]], verts[faces[face_index][1]], vector1);
	vv_sub(verts[faces[face_index][2]], verts[faces[face_index][1]], vector2);
	vv_cross(vector2, vector1, fn);
	normalize(fn);
	// place into face normals array
	f_norms[face_index] = fn;
}
Example #2
0
void Cube :: make_face(int face_num, int v1, int v2, int v3)
{
	// allocate new face
	int* f = new int[3];
	// allocate new face normal
	GLfloat* fn = new GLfloat[4];
	init_vector(fn);
	
	// set face vertices
	f[0] = v1;
	f[1] = v2;
	f[2] = v3;
	// place into faces array
	faces[face_num] = f;
	
	// calculate face normal
	GLfloat vector1[4], vector2[4];
	vv_sub(verts[v2], verts[v1], vector1);
	vv_sub(verts[v2], verts[v3], vector2);
	vv_cross(vector1, vector2, fn);
	normalize(fn);
	// place into face normals array
	f_norms[face_num] = fn;
}
Example #3
0
int draw_3d_tri(
	pVector v1p, Graph3dColor c1p, pVector n1p,
	pVector v2p, Graph3dColor c2p, pVector n2p,
	pVector v3p, Graph3dColor c3p, pVector n3p) {

	int j;
	int x1, x2, x3;
	int y1, y2, y3;

	// First, convert the colors to floats
	Vector c1 = {
		(float)c1p.r / 255.0,
		(float)c1p.g / 255.0,
		(float)c1p.b / 255.0,
		1.0
	};
	Vector c2 = {
		(float)c2p.r / 255.0,
		(float)c2p.g / 255.0,
		(float)c2p.b / 255.0,
		1.0
	};
	Vector c3 = {
		(float)c3p.r / 255.0,
		(float)c3p.g / 255.0,
		(float)c3p.b / 255.0,
		1.0
	};

	Vector v1, v2, v3;
	Vector n1, n2, n3;
	Vector L1, L2, L3;

	// Next, apply the modelview matrix to the triangle's vertices
	vv_cpy(v1, v1p); vv_cpy(v2, v2p); vv_cpy(v3, v3p);
	vm_mul(v1, modelview);
	vm_mul(v2, modelview);
	vm_mul(v3, modelview);

	// And also to the normals
	vv_cpy(n1, n1p); vv_cpy(n2, n2p); vv_cpy(n3, n3p);
	vm_mul(n1, modelview);
	vm_mul(n2, modelview);
	vm_mul(n3, modelview);

	// Find the distance for each point from the light
	vv_cpy(L1, lightpos); vv_sub(L1, v1); v_norm(L1);
	vv_cpy(L2, lightpos); vv_sub(L2, v2); v_norm(L2);
	vv_cpy(L3, lightpos); vv_sub(L3, v3); v_norm(L3);

	// Then, apply our lighting equations
	// We assume that the triangle's ambient and diffuse values are the same
	// We also assume that 
	for(j = 0; j < 4; j++) {
		c1[j] = light_transform(c1[j], n1, L1, j);
		c2[j] = light_transform(c2[j], n2, L2, j);
		c2[j] = light_transform(c3[j], n3, L3, j);
	}

	// Convert the color values to values the graphics card will accept
	// c1p et al were passed by value, so we can modify them
	c1p.r = c1[0] * 255;
	c1p.g = c1[1] * 255;
	c1p.b = c1[2] * 255;
	c2p.r = c2[0] * 255;
	c2p.g = c2[1] * 255;
	c2p.b = c2[2] * 255;
	c3p.r = c3[0] * 255;
	c3p.g = c3[1] * 255;
	c3p.b = c3[2] * 255;

	// Lastly, find the coordinates on the screen for each point,
	// and draw the triangle
	x1 = 800 * (depth/height) * (v1[0] / v1[2]);
	y1 = 600 * (depth/height) * (v1[1] / v1[2]);
	x2 = 800 * (depth/height) * (v2[0] / v2[2]);
	y2 = 600 * (depth/height) * (v2[1] / v2[2]);
	x3 = 800 * (depth/height) * (v3[0] / v3[2]);
	y3 = 600 * (depth/height) * (v3[1] / v3[2]);
	draw_2d_tri(x1, y1, c1p, x2, y2, c2p, x3, y3, c3p);

	printf("v1: %f %f %f\n", v1[0], v1[1], v1[2]);
	printf("v2: %f %f %f\n", v2[0], v2[1], v2[2]);
	printf("v2: %f %f %f\n", v3[0], v3[1], v3[2]);
	printf("%d %d; %d %d; %d %d\n", x1, y1, x2, y2, x3, y3);

	return GRAPH3D_OK;
}
Example #4
0
// modify_scene modifies the global variables g_projectiles and g_explosions
// during the course of an attack sequence.  It takes a parameter dt which
// represents the amount of time between frames.
// Return: the number of items left to animate.
int modify_scene(float dt)
{
    int i, j, num_impacted;
    float t;
    struct Projectile *p;
    struct Explosion *e;
    struct Tank *tank;
    Vector v;
    float d;

    // Go through all the explosions and update them according to the
    // amount of time passed.
    for(j = 0; j < g_num_explosions; j++)
    {
        e = &g_explosions[j];
        t = update_explosion(e, dt);
    }

    // Go through all the projectiles and handle the ones that have not yet
    // been impacted.
    for(j = 0, num_impacted = 0; j < g_num_projectiles; j++)
    {
        p = &g_projectiles[j];
        if(p->o.state != STATE_IMPACTED)
        {
            t = update_projectile(p, dt);
            if(p->o.state == STATE_IMPACTED)
            {
                printf("Projectile %d has impacted.\n", j);
                // If the projectile has impacted, an explosion needs to be
                // created which is appropriate to the projectile which has
                // impacted, and which takes on properties of the former
                // projectile.
                e = new_explosion(p);

                // Now, using the remaining time that did not get used on the
                // projectile, update the new explosion.
                t = update_explosion(e, dt - t);

                // And play a sound to match
                sx3_play_sound(SX3_AUDIO_EXPLOSION);
            }
        }
        if(p->o.state == STATE_IMPACTED) num_impacted++;
    }

    // FIX ME!! These two checks don't work properly if we have a low
    // framerate.
    for(j = 0; j < g_num_explosions; j++)
    {
        e = &g_explosions[j];
        for(i = 0; i < g_num_tanks; i++)
        {
            tank = &g_tanks[i];
            // Don't check this tank if it's already been hit
            // FIX ME!! This should be on a per-projectile/explosion basis
            if(tank->s.temp_damage != 0.0) continue;

            // Find the distance between the tank and the explosion, and test
            vv_cpy(v, tank->o.props.position);
            vv_sub(v, e->props.position);
            d = v_mag(v);

            if(d < tank->o.props.radius + e->props.radius)
            {
                // A tank has been hit!
                sx3_play_sound(SX3_AUDIO_HIT);
                printf("Tank %d hit by explosion %d\n", i, j);
                // FIX ME!! This should not be constant damage.
                tank->s.temp_damage = 20.0;
            }
        }
    }

    for(j = 0; j < g_num_projectiles; j++)
    {
        p = &g_projectiles[j];
        if(p->o.state == STATE_IMPACTED) continue;
        for(i = 0; i < g_num_tanks; i++)
        {
            tank = &g_tanks[i];
            // Don't check this tank if it's already been hit
            // FIX ME!! This should be on a per-projectile/explosion basis
            if(tank->s.temp_damage != 0.0) continue;

            // Find the distance between the tank and the projectiles, and test
            vv_cpy(v, tank->o.props.position);
            vv_sub(v, p->o.props.position);
            d = v_mag(v);

            if(d < tank->o.props.radius + p->o.props.radius)
            {
                // A tank has been hit!
                sx3_play_sound(SX3_AUDIO_HIT);
                printf("Tank %d hit by projectile %d\n", i, j);
                // FIX ME!! This should not be constant damage.
                tank->s.temp_damage = 40.0;
            }
        }
    }
    return g_num_explosions + g_num_projectiles - num_impacted;
}