Пример #1
0
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;
//
}
Пример #2
0
void CKinematics::LL_Validate()
{
	// check breakable
    BOOL bCheckBreakable			= FALSE;
    for (u16 k=0; k<LL_BoneCount(); k++){
        if (LL_GetData(k).IK_data.ik_flags.is(SJointIKData::flBreakable)&&(LL_GetData(k).IK_data.type!=jtNone)) {
        	bCheckBreakable			= TRUE;
            break;
        }
    }

    if (bCheckBreakable){
        BOOL bValidBreakable		= TRUE;

#pragma todo("container is created in stack!")
        xr_vector<xr_vector<u16> > 	groups;
        LL_GetBoneGroups			(groups);

#pragma todo("container is created in stack!")
        xr_vector<u16>   			b_parts(LL_BoneCount(),BI_NONE);
        CBoneData* root 			= &LL_GetData(LL_GetBoneRoot());
        u16 last_id					= 0;
        iBuildGroups    			(root,b_parts,0,last_id);

        for (u16 g=0; g<(u16)groups.size(); ++g){
            xr_vector<u16>&	group	= groups[g];
            u16 bp_id				= b_parts[group[0]];
            for (u32 b=1; b<groups[g].size(); b++)
                if (bp_id!=b_parts[groups[g][b]]){ bValidBreakable = FALSE; break; }
        }
    
        if (bValidBreakable==FALSE){
            for (u16 k=0; k<LL_BoneCount(); k++){
                CBoneData& BD		= LL_GetData(k);
                if (BD.IK_data.ik_flags.is(SJointIKData::flBreakable))
                    BD.IK_data.ik_flags.set(SJointIKData::flBreakable,FALSE);
            }
#ifdef DEBUG            
            Msg						("! ERROR: Invalid breakable object: '%s'",*dbg_name);
#endif
        }
    }
}
Пример #3
0
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);
}
Пример #4
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);
}