コード例 #1
0
/*
==============
R_IQMBuildSkeleton
==============
*/
static int IQMBuildSkeleton( refSkeleton_t *skel, skelAnimation_t *skelAnim,
			     int startFrame, int endFrame, float frac )
{
	int            i;
	IQAnim_t       *anim;
	transform_t    *newPose, *oldPose;
	vec3_t         mins, maxs;

	anim = skelAnim->iqm;

	// Validate the frames so there is no chance of a crash.
	// This will write directly into the entity structure, so
	// when the surfaces are rendered, they don't need to be
	// range checked again.
	if( anim->flags & IQM_LOOP ) {
		startFrame %= anim->num_frames;
		endFrame %= anim->num_frames;
	} else {
		Q_clamp( startFrame, 0, anim->num_frames - 1 );
		Q_clamp( endFrame, 0, anim->num_frames - 1 );
	}

	// compute frame pointers
	oldPose = &anim->poses[ startFrame * anim->num_joints ];
	newPose = &anim->poses[ endFrame * anim->num_joints ];

	// calculate a bounding box in the current coordinate system
	if( anim->bounds ) {
		float *bounds = &anim->bounds[ 6 * startFrame ];
		VectorCopy( bounds, mins );
		VectorCopy( bounds + 3, maxs );

		bounds = &anim->bounds[ 6 * endFrame ];
		BoundsAdd( mins, maxs, bounds, bounds + 3 );
	}

	for ( i = 0; i < anim->num_joints; i++ )
	{
		TransStartLerp( &skel->bones[ i ].t );
		TransAddWeight( 1.0f - frac, &oldPose[ i ], &skel->bones[ i ].t );
		TransAddWeight( frac, &newPose[ i ], &skel->bones[ i ].t );
		TransEndLerp( &skel->bones[ i ].t );

#if defined( REFBONE_NAMES )
		Q_strncpyz( skel->bones[ i ].name, anim->name, sizeof( skel->bones[ i ].name ) );
#endif

		skel->bones[ i ].parentIndex = anim->jointParents[ i ];
	}

	skel->numBones = anim->num_joints;
	skel->type = refSkeletonType_t::SK_RELATIVE;
	VectorCopy( mins, skel->bounds[ 0 ] );
	VectorCopy( maxs, skel->bounds[ 1 ] );
	return true;
}
コード例 #2
0
ファイル: tr_animation.cpp プロジェクト: Kangz/Unvanquished
/*
==============
RE_BlendSkeleton
==============
*/
int RE_BlendSkeleton(refSkeleton_t* skel, const refSkeleton_t* blend, float frac) {
    int i;
    vec3_t bounds[2];

    if (skel->numBones != blend->numBones) {
        ri.Printf(PRINT_WARNING,
                  "RE_BlendSkeleton: different number of bones %d != %d\n",
                  skel->numBones,
                  blend->numBones);
        return false;
    }

    // lerp between the 2 bone poses
    for (i = 0; i < skel->numBones; i++) {
        transform_t trans;

        TransStartLerp(&trans);
        TransAddWeight(1.0f - frac, &skel->bones[i].t, &trans);
        TransAddWeight(frac, &blend->bones[i].t, &trans);
        TransEndLerp(&trans);

        TransCopy(&trans, &skel->bones[i].t);
    }

    // calculate a bounding box in the current coordinate system
    for (i = 0; i < 3; i++) {
        bounds[0][i] = skel->bounds[0][i] < blend->bounds[0][i]
                               ? skel->bounds[0][i]
                               : blend->bounds[0][i];
        bounds[1][i] = skel->bounds[1][i] > blend->bounds[1][i]
                               ? skel->bounds[1][i]
                               : blend->bounds[1][i];
    }

    VectorCopy(bounds[0], skel->bounds[0]);
    VectorCopy(bounds[1], skel->bounds[1]);

    return true;
}