Exemplo n.º 1
0
// calculate single bone with key blending and callbck calling
void CKinematicsAnimated::CLBone(const CBoneData* bd,CBoneInstance& BONE_INST,const Fmatrix *parent,const CBlendInstance::BlendSVec &Blend, u8 channel_mask /*= (1<<0)*/)
{
	u16 SelfID		= bd->GetSelfID();
	if (LL_GetBoneVisible(SelfID)){
		if (BONE_INST.Callback_overwrite){
			if (BONE_INST.Callback)	BONE_INST.Callback(&BONE_INST);
		} else {

			CKey				R[MAX_CHANNELS][MAX_BLENDED];	//all keys 
			CKey				BK[MAX_CHANNELS][MAX_BLENDED];	//base keys
			float				BA[MAX_CHANNELS][MAX_BLENDED];	//all factors

			int					b_counts[MAX_CHANNELS]	= {0,0,0,0}; //channel counts
			//float				BCA[MAX_CHANNELS]		= {0,0,0,0}; //channel factors
	
			BlendSVecCIt		BI;
			for (BI=Blend.begin(); BI!=Blend.end(); BI++)
			{
				CBlend*			B		 =	*BI;
				int				&b_count =	b_counts[B->channel];
				CKey*			D		 =	&R[B->channel][b_count];
				if(!(channel_mask&(1<<B->channel)))
					continue;
				u8	channel					=  B->channel;
				BA[channel][b_count]		=  B->blendAmount;
				//BCA[channel]				+= B->blendAmount;
				CMotion			&M			=*LL_GetMotion(B->motionID,SelfID);
				Dequantize(*D,*B,M);

				QR2Quat( M._keysR[0], BK[channel][b_count].Q	);

				if(M.test_flag(flTKeyPresent))
					QT2T(M._keysT[0] ,M ,BK[channel][b_count].T );
				else
					BK[channel][b_count].T.set(M._initT);

				++b_count;
			///               PSGP.blerp				(D,&K1,&K2,delta);
			}

			// Blend them together
			CKey	channels[MAX_CHANNELS];
			float	BC		[MAX_CHANNELS];
			u16			ch_count = 0;

			for(u16 j= 0;MAX_CHANNELS>j;++j)
			{
				if(j!=0&&b_counts[j]==0)
					continue;
				//data for channel mix cycle based on ch_count
				CKey	&C		=	channels[ch_count];
						BC[ch_count]	=	channel_factors[j];//3.f;//BCA[j]*
				
				if(j != 0)
					keys_substruct(R[j],BK[j],b_counts[j]);
				MixInterlerp( C, R[j], BA[j], b_counts[j] );

				++ch_count;
			}
			CKey	Result;
			//Mix channels
			//MixInterlerp(Result,channels,BCA,ch_count);
			MixChannels( Result, channels,  BC, ch_count );
			Fmatrix					RES;
			RES.mk_xform			(Result.Q,Result.T);
			BONE_INST.mTransform.mul_43(*parent,RES);
#ifdef DEBUG
		
		if(!check_scale(RES))
		{
			VERIFY(check_scale(BONE_INST.mTransform));
		}
/*		
		if(!is_similar(BONE_INST.mPrevTransform,RES,0.3f))
		{
			Msg("bone %s",*bd->name)	;
		}
		BONE_INST.mPrevTransform.set(RES);
*/
#endif

			/*
			if(BONE_INST.mTransform.c.y>10000)
			{
			Log("BLEND_INST",BLEND_INST.Blend.size());
			Log("Bone",LL_BoneName_dbg(SelfID));
			Msg("Result.Q %f,%f,%f,%f",Result.Q.x,Result.Q.y,Result.Q.z,Result.Q.w);
			Log("Result.T",Result.T);
			Log("lp parent",(u32)parent);
			Log("parent",*parent);
			Log("RES",RES);
			Log("mT",BONE_INST.mTransform);

			CBlend*			B		=	*BI;
			CMotion&		M		=	*LL_GetMotion(B->motionID,SelfID);
			float			time	=	B->timeCurrent*float(SAMPLE_FPS);
			u32				frame	=	iFloor(time);
			u32				count	=	M.get_count();
			float			delta	=	time-float(frame);

			Log("flTKeyPresent",M.test_flag(flTKeyPresent));
			Log("M._initT",M._initT);
			Log("M._sizeT",M._sizeT);

			// translate
			if (M.test_flag(flTKeyPresent))
			{
			CKeyQT*	K1t	= &M._keysT[(frame+0)%count];
			CKeyQT*	K2t	= &M._keysT[(frame+1)%count];

			Fvector T1,T2,Dt;
			T1.x		= float(K1t->x)*M._sizeT.x+M._initT.x;
			T1.y		= float(K1t->y)*M._sizeT.y+M._initT.y;
			T1.z		= float(K1t->z)*M._sizeT.z+M._initT.z;
			T2.x		= float(K2t->x)*M._sizeT.x+M._initT.x;
			T2.y		= float(K2t->y)*M._sizeT.y+M._initT.y;
			T2.z		= float(K2t->z)*M._sizeT.z+M._initT.z;

			Dt.lerp	(T1,T2,delta);

			Msg("K1t %d,%d,%d",K1t->x,K1t->y,K1t->z);
			Msg("K2t %d,%d,%d",K2t->x,K2t->y,K2t->z);

			Log("count",count);
			Log("frame",frame);
			Log("T1",T1);
			Log("T2",T2);
			Log("delta",delta);
			Log("Dt",Dt);

			}else
			{
			D->T.set	(M._initT);
			}
			VERIFY(0);
			}
			*/
			if (BONE_INST.Callback)		BONE_INST.Callback(&BONE_INST);
		}
		BONE_INST.mRenderTransform.mul_43(BONE_INST.mTransform,bd->m2b_transform);
	}
}