void	CKinematicsAnimated::BoneChain_Calculate		(const CBoneData* bd, CBoneInstance &bi, u8 mask_channel, bool ignore_callbacks)
{
	u16 SelfID					= bd->GetSelfID();
	CBlendInstance& BLEND_INST	= LL_GetBlendInstance(SelfID);
	CBlendInstance::BlendSVec &Blend = BLEND_INST.blend_vector();
//ignore callbacks
	BoneCallback bc = bi.Callback;
	BOOL		 ow = bi.Callback_overwrite;
	if(ignore_callbacks)
	{
		bi.Callback	= 0;
		bi.Callback_overwrite =0;
	}
//
	if(SelfID==LL_GetBoneRoot())
	{
		CLBone(bd, bi, &Fidentity, Blend, mask_channel);
//restore callback	
		bi.Callback	= bc;
		bi.Callback_overwrite =ow;
//
		return;
	}
	u16 ParentID				= bd->GetParentID();
	CBoneData* ParrentDT		= &LL_GetData(ParentID);
	CBoneInstance parrent_bi	= LL_GetBoneInstance(ParentID);
	BoneChain_Calculate(ParrentDT, parrent_bi, mask_channel, ignore_callbacks);
	CLBone(bd, bi, &parrent_bi.mTransform, Blend, mask_channel);
//restore callback	
	bi.Callback	= bc;
	bi.Callback_overwrite =ow;
//
}
void CKinematicsAnimated::Bone_Calculate(CBoneData* bd, Fmatrix *parent)
{
	u16 SelfID					= bd->GetSelfID();
	CBlendInstance& BLEND_INST	= LL_GetBlendInstance(SelfID);
	CBoneInstance& BONE_INST	= LL_GetBoneInstance(SelfID);
	CLBone(bd,BONE_INST,parent,BLEND_INST.blend_vector(),u8(-1));
	// Calculate children
	for (xr_vector<CBoneData*>::iterator C=bd->children.begin(); C!=bd->children.end(); C++)
		Bone_Calculate(*C,&BONE_INST.mTransform);
}
Exemple #3
0
void CKinematics::RenderWallmark(intrusive_ptr<CSkeletonWallmark> wm, FVF::LIT* &V)
{
	VERIFY(wm);
	VERIFY(V);
	VERIFY2(bones,"Invalid visual. Bones already released.");
	VERIFY2(bone_instances,"Invalid visual. bone_instances already deleted.");

	if ((wm == 0) || (0==bones) || (0==bone_instances))	return;

	// skin vertices
	for (u32 f_idx=0; f_idx<wm->m_Faces.size(); f_idx++){
		CSkeletonWallmark::WMFace F = wm->m_Faces[f_idx];
		float w	= (Device.fTimeGlobal-wm->TimeStart())/LIFE_TIME;
		for (u32 k=0; k<3; k++){
			Fvector P;
			if (F.bone_id[k][0]==F.bone_id[k][1]){
				// 1-link
				Fmatrix& xform0			= LL_GetBoneInstance(F.bone_id[k][0]).mRenderTransform; 
				xform0.transform_tiny	(P,F.vert[k]);
			}else{
				// 2-link
				Fvector P0,P1;
				Fmatrix& xform0			= LL_GetBoneInstance(F.bone_id[k][0]).mRenderTransform; 
				Fmatrix& xform1			= LL_GetBoneInstance(F.bone_id[k][1]).mRenderTransform; 
				xform0.transform_tiny	(P0,F.vert[k]);
				xform1.transform_tiny	(P1,F.vert[k]);
				P.lerp					(P0,P1,F.weight[k]);
			}
			wm->XFORM()->transform_tiny	(V->p,P);
			V->t.set					(F.uv[k]);
			int			aC				= iFloor	( w * 255.f);	clamp	(aC,0,255);
			V->color					= color_rgba(128,128,128,aC);
			V++;
		}
	}
	wm->XFORM()->transform_tiny(wm->m_Bounds.P,wm->m_LocalBounds.P);
}
void	CKinematicsAnimated::Bone_GetAnimPos(Fmatrix& pos,u16 id,u8 mask_channel, bool ignore_callbacks)
{
	CBoneInstance bi = LL_GetBoneInstance(id);
	BoneChain_Calculate(&LL_GetData(id),bi,mask_channel,ignore_callbacks);
	pos.set(bi.mTransform);
}
Exemple #5
0
void CKinematics::AddWallmark(const Fmatrix* parent_xform, const Fvector3& start, const Fvector3& dir, ref_shader shader, float size)
{
	Fvector S,D,normal		= {0,0,0};
	// transform ray from world to model
	Fmatrix P;	P.invert	(*parent_xform);
	P.transform_tiny		(S,start);
	P.transform_dir			(D,dir);
	// find pick point
	float dist				= flt_max;
	BOOL picked				= FALSE;

	DEFINE_VECTOR			(Fobb,OBBVec,OBBVecIt);
	OBBVec					cache_obb;
	cache_obb.resize		(LL_BoneCount());

	for (u16 k=0; k<LL_BoneCount(); k++){
		CBoneData& BD		= LL_GetData(k);
		if (LL_GetBoneVisible(k)&&!BD.shape.flags.is(SBoneShape::sfNoPickable)){
			Fobb& obb		= cache_obb[k];
			obb.transform	(BD.obb,LL_GetBoneInstance(k).mTransform);
			if (CDB::TestRayOBB(S,D, obb))
				for (u32 i=0; i<children.size(); i++)
					if (LL_GetChild(i)->PickBone(normal,dist,S,D,k)) picked=TRUE;
		}
	}
	if (!picked) return; 
 
	// calculate contact point
	Fvector cp;	cp.mad		(S,D,dist); 
 
	// collect collide boxes
	Fsphere test_sphere;
    test_sphere.set			(cp,size); 
	U16Vec					test_bones;
	test_bones.reserve		(LL_BoneCount());
	for (k=0; k<LL_BoneCount(); k++){
		CBoneData& BD		= LL_GetData(k);  
		if (LL_GetBoneVisible(k)&&!BD.shape.flags.is(SBoneShape::sfNoPickable)){
			Fobb& obb		= cache_obb[k];
			if (CDB::TestSphereOBB(test_sphere, obb))
				test_bones.push_back(k);
		}
	}

	// find similar wm
	for (u32 wm_idx=0; wm_idx<wallmarks.size(); wm_idx++){
		intrusive_ptr<CSkeletonWallmark>& wm = wallmarks[wm_idx];		
		if (wm->Similar(shader,cp,0.02f)){ 
			if (wm_idx<wallmarks.size()-1) 
				wm = wallmarks.back();
			wallmarks.pop_back();
			break;
		}
	}

	// ok. allocate wallmark
	intrusive_ptr<CSkeletonWallmark>		wm = xr_new<CSkeletonWallmark>(this,parent_xform,shader,cp,Device.fTimeGlobal);
	wm->m_LocalBounds.set		(cp,size*2.f);
	wm->XFORM()->transform_tiny	(wm->m_Bounds.P,cp);
	wm->m_Bounds.R				= wm->m_Bounds.R; 

	Fvector tmp; tmp.invert		(D);
	normal.add(tmp).normalize	();

	// build UV projection matrix
	Fmatrix						mView,mRot;
	BuildMatrix					(mView,1/(0.9f*size),normal,cp);
	mRot.rotateZ				(::Random.randF(deg2rad(-20.f),deg2rad(20.f)));
	mView.mulA_43				(mRot);

	// fill vertices
	for (u32 i=0; i<children.size(); i++){
		CSkeletonX* S		= LL_GetChild(i);
		for (U16It b_it=test_bones.begin(); b_it!=test_bones.end(); b_it++)
			S->FillVertices		(mView,*wm,normal,size,*b_it);
	}

	wallmarks.push_back		(wm);
}