void StudioModel::SetUpBones ( void )
{
	int					i;

	mstudiobone_t		*pbones;
	mstudioseqdesc_t	*pseqdesc;
	mstudioanim_t		*panim;

	static vec3_t		pos[MAXSTUDIOBONES];
	float				bonematrix[3][4];
	static vec4_t		q[MAXSTUDIOBONES];

	static vec3_t		pos2[MAXSTUDIOBONES];
	static vec4_t		q2[MAXSTUDIOBONES];
	static vec3_t		pos3[MAXSTUDIOBONES];
	static vec4_t		q3[MAXSTUDIOBONES];
	static vec3_t		pos4[MAXSTUDIOBONES];
	static vec4_t		q4[MAXSTUDIOBONES];


	if (m_sequence >=  m_pstudiohdr->numseq) {
		m_sequence = 0;
	}

	pseqdesc = (mstudioseqdesc_t *)((byte *)m_pstudiohdr + m_pstudiohdr->seqindex) + m_sequence;

	panim = GetAnim( pseqdesc );
	CalcRotations( pos, q, pseqdesc, panim, m_frame );

	if (pseqdesc->numblends > 1)
	{
		float				s;

		panim += m_pstudiohdr->numbones;
		CalcRotations( pos2, q2, pseqdesc, panim, m_frame );
		s = m_blending[0] / 255.0;

		SlerpBones( q, pos, q2, pos2, s );

		if (pseqdesc->numblends == 4)
		{
			panim += m_pstudiohdr->numbones;
			CalcRotations( pos3, q3, pseqdesc, panim, m_frame );

			panim += m_pstudiohdr->numbones;
			CalcRotations( pos4, q4, pseqdesc, panim, m_frame );

			s = m_blending[0] / 255.0;
			SlerpBones( q3, pos3, q4, pos4, s );

			s = m_blending[1] / 255.0;
			SlerpBones( q, pos, q3, pos3, s );
		}
	}

	pbones = (mstudiobone_t *)((byte *)m_pstudiohdr + m_pstudiohdr->boneindex);

	for (i = 0; i < m_pstudiohdr->numbones; i++) {
		QuaternionMatrix( q[i], bonematrix );

		bonematrix[0][3] = pos[i][0];
		bonematrix[1][3] = pos[i][1];
		bonematrix[2][3] = pos[i][2];

		if (pbones[i].parent == -1) {
			memcpy(g_bonetransform[i], bonematrix, sizeof(float) * 12);
		} 
		else {
			R_ConcatTransforms (g_bonetransform[pbones[i].parent], bonematrix, g_bonetransform[i]);
		}
	}
}
//-----------------------------------------------------------------------------
// Purpose: 
//-----------------------------------------------------------------------------
void C_AI_BaseHumanoid::StandardBlendingRules( Vector pos[], Quaternion q[], float currentTime, int boneMask )
{
	VPROF( "C_AI_BaseHumanoid::StandardBlendingRules" );

	BaseClass::StandardBlendingRules( pos, q, currentTime, boneMask );

	studiohdr_t *hdr = InitModel();
	if ( !hdr )
	{
		return;
	}

#if 0
	float		poseparam[MAXSTUDIOPOSEPARAM];

	if (m_nSequence >=  hdr->numseq) 
	{
		m_nSequence = 0;
	}

	// interpolate pose parameters
	for (int i = 0; i < hdr->numposeparameters; i++)
	{
		poseparam[ i ] = m_flPoseParameter[i];
	}

	// build root animation
	float fCycle = m_flCycle;
	CalcPose( hdr, NULL, pos, q, m_nSequence, fCycle, poseparam );

	// debugoverlay->AddTextOverlay( GetAbsOrigin() + Vector( 0, 0, 64 ), 0, 0, "%30s %6.2f : %6.2f", hdr->pSeqdesc( m_nSequence )->pszLabel( ), fCycle, 1.0 );

	MaintainSequenceTransitions( fCycle, poseparam, pos, q, boneMask );

#if 1
	for (i = 0; i < 4; i++)
	{
		if (m_Layer[i][2].nSequence != m_Layer[i][1].nSequence)
		{
			if (m_Layer[i][2].flWeight > 0.5) m_Layer[i][1].flWeight = 1.0; else m_Layer[i][1].flWeight = 0;
		}
	}
#endif

#if 1
	for (i = 0; i < 4; i++)
	{
		Vector		pos2[MAXSTUDIOBONES];
		Quaternion	q2[MAXSTUDIOBONES];
		float fWeight = m_Layer[i][1].flWeight * (1 - dadt) + m_Layer[i][2].flWeight * dadt;

		/*
		debugoverlay->AddTextOverlay( GetAbsOrigin() + Vector( 0, 0, 64 ), -i - 1, 0, 
			"%2d %6.2f %6.2f : %2d %6.2f %6.2f : %2d %6.2f %6.2f", 
				m_Layer[i][0].nSequence, m_Layer[i][0].flCycle, m_Layer[i][0].flWeight,
				m_Layer[i][1].nSequence, m_Layer[i][1].flCycle, m_Layer[i][1].flWeight,
				m_Layer[i][2].nSequence, m_Layer[i][2].flCycle, m_Layer[i][2].flWeight );
		*/

		if (fWeight > 0)
		{
			mstudioseqdesc_t *pseqdesc = hdr->pSeqdesc( m_Layer[i][2].nSequence );

			float fCycle =  m_Layer[i][2].flCycle;

			// UNDONE: Do IK here.
			CalcPose( hdr, NULL, pos2, q2, m_Layer[i][2].nSequence, fCycle, poseparam );

			if (fWeight > 1)
				fWeight = 1;
			SlerpBones( hdr, q, pos, pseqdesc, q2, pos2, fWeight );

			engine->Con_NPrintf( 10 + i, "%30s %6.2f : %6.2f", pseqdesc->pszLabel(), fCycle, fWeight );
		}
		else
		{
			engine->Con_NPrintf( 10 + i, "%30s %6.2f : %6.2f", "            ", 0, 0 );
		}

	}
#endif

	CIKContext auto_ik;
	auto_ik.Init( hdr, GetRenderAngles(), GetRenderOrigin(), gpGlobals->curtime );
	CalcAutoplaySequences( hdr, &auto_ik, pos, q, poseparam, boneMask, currentTime );

	float controllers[MAXSTUDIOBONECTRLS];
	GetBoneControllers(controllers);
	CalcBoneAdj( hdr, pos, q, controllers );
#endif
}