Esempio n. 1
0
void CKinematicsAnimated::IBlendSetup(CBlend& B,u16 part,u8 channel, MotionID motion_ID, BOOL  bMixing, float blendAccrue, float blendFalloff, float Speed, BOOL noloop, PlayCallback Callback, LPVOID CallbackParam)
{
	VERIFY(B.channel<MAX_CHANNELS);
	// Setup blend params
	if (bMixing)	{
		B.blend		= CBlend::eAccrue;
		B.blendAmount	= EPS_S;
	} else {
		//B.blend		= CBlend::eFixed;
		B.blend		= CBlend::eAccrue;
		B.blendAmount	= 1;
	}
	B.blendAccrue	= blendAccrue;
	B.blendFalloff	= 0; // blendFalloff used for previous cycles
	B.blendPower	= 1;
	B.speed			= Speed;
	B.motionID		= motion_ID;
	B.timeCurrent	= 0;
	B.timeTotal	= m_Motions[B.motionID.slot].bone_motions[LL_GetBoneRoot()]->at(motion_ID.idx).GetLength();
	B.bone_or_part	= part;
	B.stop_at_end	= noloop;
	B.playing		= TRUE;
	B.Callback		= Callback;
	B.CallbackParam= CallbackParam;

	B.channel		= channel;
	B.fall_at_end	= B.stop_at_end && (channel != 0);
}
Esempio n. 2
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;
//
}
Esempio n. 3
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
        }
    }
}
Esempio n. 4
0
void	CKinematics::Load(const char* N, IReader *data, u32 dwFlags)
{
	//Msg				("skeleton: %s",N);
	inherited::Load	(N, data, dwFlags);

    pUserData		= NULL;
    m_lod			= NULL;
    // loading lods

	IReader* LD 	= data->open_chunk(OGF_S_LODS);
    if (LD)
	{
        string_path		short_name;
        strcpy_s		(short_name,sizeof(short_name),N);

        if (strext(short_name)) *strext(short_name)=0;
        // From stream
		{
			string_path		lod_name;
			LD->r_string	(lod_name, sizeof(lod_name));
//.         strconcat		(sizeof(name_load),name_load, short_name, ":lod:", lod_name.c_str());
            m_lod 			= ::Render->model_CreateChild(lod_name, NULL);
            VERIFY3(m_lod,"Cant create LOD model for", N);
//.			VERIFY2			(m_lod->Type==MT_HIERRARHY || m_lod->Type==MT_PROGRESSIVE || m_lod->Type==MT_NORMAL,lod_name.c_str());
/*
			strconcat		(name_load, short_name, ":lod:1");
            m_lod 			= ::Render->model_CreateChild(name_load,LD);
			VERIFY			(m_lod->Type==MT_SKELETON_GEOMDEF_PM || m_lod->Type==MT_SKELETON_GEOMDEF_ST);
*/
        }
        LD->close	();
    }

#ifndef _EDITOR    
	// User data
	IReader* UD 	= data->open_chunk(OGF_S_USERDATA);
    pUserData		= UD?xr_new<CInifile>(UD,FS.get_path("$game_config$")->m_Path):0;
    if (UD)			UD->close();
#endif

	// Globals
	bone_map_N		= xr_new<accel>		();
	bone_map_P		= xr_new<accel>		();
	bones			= xr_new<vecBones>	();
	bone_instances	= NULL;

	// Load bones
#pragma todo("container is created in stack!")
	xr_vector<shared_str>	L_parents;

	R_ASSERT		(data->find_chunk(OGF_S_BONE_NAMES));

    visimask.zero	();
	int dwCount 	= data->r_u32();
	// Msg				("!!! %d bones",dwCount);
	// if (dwCount >= 64)	Msg			("!!! More than 64 bones is a crazy thing! (%d), %s",dwCount,N);
	VERIFY3			(dwCount < 64, "More than 64 bones is a crazy thing!",N);
	for (; dwCount; dwCount--)		{
		string256	buf;

		// Bone
		u16			ID				= u16(bones->size());
		data->r_stringZ				(buf,sizeof(buf));	strlwr(buf);
		CBoneData* pBone 			= CreateBoneData(ID);
		pBone->name					= shared_str(buf);
		pBone->child_faces.resize	(children.size());
		bones->push_back			(pBone);
		bone_map_N->push_back		(mk_pair(pBone->name,ID));
		bone_map_P->push_back		(mk_pair(pBone->name,ID));

		// It's parent
		data->r_stringZ				(buf,sizeof(buf));	strlwr(buf);
		L_parents.push_back			(buf);

		data->r						(&pBone->obb,sizeof(Fobb));
        visimask.set				(u64(1)<<ID,TRUE);
	}
	std::sort	(bone_map_N->begin(),bone_map_N->end(),pred_sort_N);
	std::sort	(bone_map_P->begin(),bone_map_P->end(),pred_sort_P);

	// Attach bones to their parents
	iRoot = BI_NONE;
	for (u32 i=0; i<bones->size(); i++) {
		shared_str	P 		= L_parents[i];
		CBoneData* B	= (*bones)[i];
		if (!P||!P[0]) {
			// no parent - this is root bone
			R_ASSERT	(BI_NONE==iRoot);
			iRoot		= u16(i);
			B->SetParentID(BI_NONE);
			continue;
		} else {
			u16 ID		= LL_BoneID(P);
			R_ASSERT	(ID!=BI_NONE);
			(*bones)[ID]->children.push_back(B);
			B->SetParentID(ID);
		}
	}
	R_ASSERT	(BI_NONE != iRoot);

	// Free parents
    L_parents.clear();

    // IK data
	IReader* IKD 	= data->open_chunk(OGF_S_IKDATA);
    if (IKD){
        for (u32 i=0; i<bones->size(); i++) {
            CBoneData*	B 	= (*bones)[i];
            u16 vers		= (u16)IKD->r_u32();
            IKD->r_stringZ	(B->game_mtl_name);
            IKD->r			(&B->shape,sizeof(SBoneShape));
            B->IK_data.Import(*IKD,vers);
            Fvector vXYZ,vT;
            IKD->r_fvector3	(vXYZ);
            IKD->r_fvector3	(vT);
            B->bind_transform.setXYZi(vXYZ);
            B->bind_transform.translate_over(vT);
	        B->mass			= IKD->r_float();
    	    IKD->r_fvector3	(B->center_of_mass);
        }
        // calculate model to bone converting matrix
        (*bones)[LL_GetBoneRoot()]->CalculateM2B(Fidentity);
    	IKD->close();
    }

	// after load process
	{
		for (u16 child_idx=0; child_idx<(u16)children.size(); child_idx++)
			LL_GetChild(child_idx)->AfterLoad	(this,child_idx);
	}

	// unique bone faces
	{
		for (u32 bone_idx=0; bone_idx<bones->size(); bone_idx++) {
			CBoneData*	B 	= (*bones)[bone_idx];
			for (u32 child_idx=0; child_idx<children.size(); child_idx++){
				CBoneData::FacesVec faces		= B->child_faces[child_idx];
				std::sort						(faces.begin(),faces.end());
				CBoneData::FacesVecIt new_end	= std::unique(faces.begin(),faces.end());
				faces.erase						(new_end,faces.end());
				B->child_faces[child_idx].clear_and_free();
				B->child_faces[child_idx]		= faces;
			}
		}
	}

	// reset update_callback
	Update_Callback	= NULL;
	// reset update frame
	wm_frame		= u32(-1);

    LL_Validate		();
}