Beispiel #1
0
bool	CKinematics::	PickBone			(const Fmatrix &parent_xform,  Fvector& normal, float& dist, const Fvector& start, const Fvector& dir, u16 bone_id)
{
	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);
	for (u32 i=0; i<children.size(); i++)
			if (LL_GetChild(i)->PickBone(normal,dist,S,D,bone_id))
			{
				parent_xform.transform_dir			(normal);
				return true;
			}
	return false;
}
Beispiel #2
0
void CKinematics::Copy(IRender_Visual *P) 
{
	inherited::Copy	(P);

	CKinematics* pFrom = (CKinematics*)P;
    PCOPY(pUserData	);
	PCOPY(bones		);
	PCOPY(iRoot		);
	PCOPY(bone_map_N);
	PCOPY(bone_map_P);
    PCOPY(visimask	);

	IBoneInstances_Create	();

	for (u32 i=0; i<children.size(); i++) 
		LL_GetChild(i)->SetParent(this);

	CalculateBones_Invalidate	();

    m_lod 			= (pFrom->m_lod)?::Render->model_Duplicate	(pFrom->m_lod):0;
}
Beispiel #3
0
void CKinematics::Copy(dxRender_Visual *P) 
{
	inherited::Copy	(P);

	CKinematics* pFrom = dynamic_cast<CKinematics*>(P);
	VERIFY(pFrom);
	pUserData  = pFrom->pUserData;
	bones	   = pFrom->bones;
	iRoot	   = pFrom->iRoot;
	bone_map_N = pFrom->bone_map_N;
	bone_map_P = pFrom->bone_map_P;
	visimask   = pFrom->visimask;

	IBoneInstances_Create	();

	for (u32 i=0; i<children.size(); i++) 
		LL_GetChild(i)->SetParent(this);

	CalculateBones_Invalidate	();

    m_lod 	   = (pFrom->m_lod)?(dxRender_Visual*)::Render->model_Duplicate	(pFrom->m_lod):0;
}
Beispiel #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);
}
Beispiel #5
0
void CKinematics::EnumBoneVertices	(SEnumVerticesCallback &C, u16 bone_id)
{
	for ( u32 i=0; i<children.size(); i++ )
		LL_GetChild( i )->EnumBoneVertices( C, bone_id );
}
Beispiel #6
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		();
}