Beispiel #1
0
/*
 * TODO: If you look at the usage of this function, radians is often
 * the same for each call, so optimise this to not recalc m if radians
 * hasn't changed.
 */
void vec3_axisRotate(vec3 axis, vec3 target, float radians)
{
	float m[9];
	vec3 t;
	int i;

	vec3_getRotationMatrix(axis, m, radians);
	vec3_cpy(target, t);

#define M(row,col)	m[row*3 + col]

	for (i = 0; i < 3; i++)
		target[i] = t[0]*M(0,i) + t[1]*M(1,i) + t[2]*M(2,i);

#undef M
}
Beispiel #2
0
/*
 * Create the vertex array with vertexes in mip level order.
 */
static void lsc_setupPatchVtxArr(lsc l, int m,
								 int x0, int x1, int y0, int y1,
								 float *vtxArr)
{
	int i, j, k;
	vec3 v;
	unsigned char *hm = l->hm;
	int hmSize = l->hmSize;
	int patchSize = l->patchSize;
	float texScale = (float)l->texTile / (float)l->hmSize;
	float baseTexScale = (float)l->baseTexTile / (float)l->hmSize;
	int S = x0 % (l->hmSize / l->texTile);
	int T = y0 % (l->hmSize / l->texTile);
	unsigned short *patchIdx = l->patchIdx;

	if (hm)
		hm = &hm[x0 + y0*(hmSize+1)];

	for (j = 0; j <= patchSize; j++) {
		for (i = 0; i <= patchSize; i++) {

			k = patchIdx[j*(patchSize + 1) + i];

			v[0] = i + x0;
			v[1] = j + y0;

			/* Texture 0 */
			vtxArr[8*k + 4] = (S + i) * texScale;
			vtxArr[8*k + 5] = (T + j) * texScale;

			/* Texture 1 */
			vtxArr[8*k + 6] = v[0] * baseTexScale;
			vtxArr[8*k + 7] = v[1] * baseTexScale;

			/* Vertex */
			if (hm)
				v[2] = hm[j*(hmSize + 1) + i];
			else
				v[2] = 0.0f;
			vec3_mul(v, l->scale, v);
			vec3_cpy(v, (&vtxArr[8*k]));
		}
	}
}
Beispiel #3
0
X42_EXPORT bool X42_CALL x42_LerpAnims( x42animLerp_t *lerp,
	const x42data_t *x42, const x42animFrames_t *anim, x42opts_t *opts )
{
	uint i, j;
	
	const vec3_t * RESTRICT pv;
	const vec3_t * RESTRICT sv;
	const quat_t * RESTRICT rv;

	vec3_t * RESTRICT po;
	vec3_t * RESTRICT so;
	quat_t * RESTRICT ro;

	REF_PARAM( opts );

#ifndef LIBX42_NO_PARAM_VALIDATION
	demand_rf( lerp != NULL, X42_ERR_BADPTR, "lerp is NULL" );
	demand_rf( anim != NULL, X42_ERR_BADPTR, "anim is NULL" );
	demand_rf( x42 != NULL, X42_ERR_BADPTR, "x42 is NULL" );
	demand_rf( x42_ValidateHeader( &x42->header ), X42_ERR_BADDATA, "invalid x42 header data" );
#endif

	pv = x42->posValues;
	sv = x42->scaleValues;
	rv = x42->rotValues;

	po = lerp->p;
	so = lerp->s;
	ro = lerp->r;

	for( i = 0; i < x42->header.numAnimGroups; i++ )
	{
		const x42ksBoneEntry_t * RESTRICT p;

		uint beginBone = x42->animGroups[i].beginBone;
		uint endBone = x42->animGroups[i].endBone;

		float target = anim->frames[i].targetFrame;

		for( j = beginBone; j < endBone; j++ )
		{
			p = anim->kpairs[j][X42_KT_POSITION];

			if( p[0].value == p[1].value )
				vec3_cpy( po[j], pv[p[0].value] );
			else
			{
				float s = (float)(int)p[0].frame;
				float e = (float)(int)p[1].frame;

				float t = (target - s) / (e - s);

				vec3_lerp( po[j], pv[p[0].value], pv[p[1].value], t );
			}
		}

		for( j = beginBone; j < endBone; j++ )
		{
			p = anim->kpairs[j][X42_KT_SCALE];

			if( p[0].value == p[1].value )
				vec3_cpy( so[j], sv[p[0].value] );
			else
			{
				float s = (float)(int)p[0].frame;
				float e = (float)(int)p[1].frame;

				float t = (target - s) / (e - s);

				vec3_lerp( so[j], sv[p[0].value], sv[p[1].value], t );
			}
		}

		for( j = beginBone; j < endBone; j++ )
		{
			p = anim->kpairs[j][X42_KT_ROTATION];

			if( p[0].value == p[1].value )
				quat_cpy( ro[j], rv[p[0].value] );
			else
			{
				float s = (float)(int)p[0].frame;
				float e = (float)(int)p[1].frame;

				float t = (target - s) / (e - s);

				quat_interp( ro[j], rv[p[0].value], rv[p[1].value], t );
			}
		}
	}

	return true;
}
Beispiel #4
0
X42_EXPORT affine_t* X42_CALL x42_GetAnimBoneMatrices( void *out_buffer, const x42data_t *x42,
	const x42animLerp_t *lerp, x42opts_t *opts )
{
	uint i;

	affine_t * RESTRICT ret;

	const vec3_t * RESTRICT pv;
	const vec3_t * RESTRICT sv;
	const quat_t * RESTRICT rv;

	REF_PARAM( opts );

#ifndef LIBX42_NO_PARAM_VALIDATION
	demand_rn( out_buffer != NULL, X42_ERR_BADPTR, "out_buffer is NULL" );
	demand_rn( lerp != NULL, X42_ERR_BADPTR, "lerp is NULL" );
	demand_rn( x42 != NULL, X42_ERR_BADPTR, "x42 is NULL" );
	demand_rn( x42_ValidateHeader( &x42->header ), X42_ERR_BADDATA, "invalid x42 header data" );
#endif

	pv = lerp->p;
	sv = lerp->s;
	rv = lerp->r;

	ret = (affine_t*)out_buffer;

	for( i = 0; i < x42->header.numBones; i++ )
	{
		affine_t * RESTRICT o = ret + i;

		const x42bone_t * RESTRICT b = x42->bones + i;

		if( b->parentIdx != X42_MODEL_BONE && (b->flags & X42_BF_USE_INV_PARENT_SCALE) )
		{
			vec3_t ips;
			affine_t rs;

			quat_to_affine( &rs, rv[i] );

			vec3_scale( rs.c[0], rs.c[0], sv[i][0] );
			vec3_scale( rs.c[1], rs.c[1], sv[i][1] );
			vec3_scale( rs.c[2], rs.c[2], sv[i][2] );

			ips[0] = 1.0F / sv[b->parentIdx][0];
			ips[1] = 1.0F / sv[b->parentIdx][1];
			ips[2] = 1.0F / sv[b->parentIdx][2];

			vec3_mul( o->c[0], rs.c[0], ips );
			vec3_mul( o->c[1], rs.c[1], ips );
			vec3_mul( o->c[2], rs.c[2], ips );
		}
		else
		{
			quat_to_affine( o, rv[i] );

			vec3_scale( o->c[0], o->c[0], sv[i][0] );
			vec3_scale( o->c[1], o->c[1], sv[i][1] );
			vec3_scale( o->c[2], o->c[2], sv[i][2] );
		}

		vec3_cpy( o->c[3], pv[i] );
	}

	for( i = 0; i < x42->header.numBones; i++ )
	{
		const x42bone_t * RESTRICT b = x42->bones + i;

		if( b->parentIdx != X42_MODEL_BONE )
			affine_mul( ret + i, ret + b->parentIdx, ret + i );
		else if( x42->header.runFlags & X42_RF_ROOT_MATRIX )
			affine_mul( ret + i, &x42->rootMatrix, ret + i );		
	}

	return ret;
}
Beispiel #5
0
static void draw_screen( OBJSC * model )
{
    /* Our angle of rotation. */

    /*
     * EXERCISE:
     * Replace this awful mess with vertex
     * arrays and a call to glDrawElements.
     *
     * EXERCISE:
     * After completing the above, change
     * it to use compiled vertex arrays.
     *
     * EXERCISE:
     * Verify my windings are correct here ;).
     */

    static GLubyte red[]    = { 255,   0,   0, 255 };
    static GLubyte green[]  = {   0, 255,   0, 255 };
    static GLubyte blue[]   = {   0,   0, 255, 255 };
    static GLubyte white[]  = { 255, 255, 255, 255 };
    static GLubyte yellow[] = {   0, 255, 255, 255 };
    static GLubyte black[]  = {   0,   0,   0, 255 };
    static GLubyte orange[] = { 255, 255,   0, 255 };
    static GLubyte purple[] = { 255,   0, 255,   0 };

    /* Clear the color and depth buffers. */
    glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );

    /* We don't want to modify the projection matrix. */
    glMatrixMode( GL_MODELVIEW );
    glLoadIdentity( );

    /* Move down the z-axis. */
    glRotatef( 20, 1.0, 0.0, 0.0 );
    glTranslatef( 0.0, -100.0, -150.0 );

    /* Rotate. */
    glRotatef( angle*8, 0.0, 1.0, 0.0 );

    /* Send our triangle data to the pipeline. */

    int i;
    for(i = 0; i < model->vlen; i++) {
        calc_vertex(model, i, game_time, speed);
        calc_vertex_normal(model, i, model->vntable[i]);
    }
    
    glBegin( GL_TRIANGLES );

    for(i = 0; i < model->flen; i++) {


        if(model->ftable[i].data == 2) {
            glColor4ubv( white );
        } else if(model->ftable[i].data == 3) {
            glColor4ubv( black );
        } else {
            glColor4ubv( black );
        }

        vec3 normal;


        vec3 a;
        vec3 b;
        vec3 c;

        vec3 an;
        vec3 bn;
        vec3 cn;

        vec3_cpy(a, model->vtable[model->ftable[i].a]);
        vec3_cpy(b, model->vtable[model->ftable[i].b]);
        vec3_cpy(c, model->vtable[model->ftable[i].c]);

        vec3_cpy(an, model->vntable[model->ftable[i].a]);
        vec3_cpy(bn, model->vntable[model->ftable[i].b]);
        vec3_cpy(cn, model->vntable[model->ftable[i].c]);

        glColor3fv( an);
        glVertex3fv( a );
        glColor3fv( bn);
        glVertex3fv( b );
        glColor3fv( cn);
        glVertex3fv( c );
    }


    glEnd( );

    /*
     * EXERCISE:
     * Draw text telling the user that 'Spc'
     * pauses the rotation and 'Esc' quits.
     * Do it using vetors and textured quads.
     */

    /*
     * Swap the buffers. This this tells the driver to
     * render the next frame from the contents of the
     * back-buffer, and to set all rendering operations
     * to occur on what was the front-buffer.
     *
     * Double buffering prevents nasty visual tearing
     * from the application drawing on areas of the
     * screen that are being updated at the same time.
     */
    SDL_GL_SwapBuffers( );
}