void CEditableObject::OnFrame() { if (IsSkeleton()){ BoneVec& lst = m_Bones; if (IsSMotionActive()){ Fvector R,T; int i=0; for(BoneIt b_it=lst.begin(); b_it!=lst.end(); b_it++, i++){ m_ActiveSMotion->_Evaluate(i,m_SMParam.Frame(),T,R); (*b_it)->_Update(T,R); } m_SMParam.Update(Device.fTimeDelta,m_ActiveSMotion->fSpeed,!m_ActiveSMotion->m_Flags.is(esmStopAtEnd)); }else{ //for (BoneIt b_it=lst.begin(); b_it!=lst.end(); b_it++) (*b_it)->Reset(); } CalculateAnimation(m_ActiveSMotion); } }
bool CEditableObject::GenerateBoneShape(bool bSelOnly) { R_ASSERT(IsSkeleton()); xr_vector<FvectorVec> bone_points; bone_points.resize (m_Bones.size()); for(EditMeshIt mesh_it=FirstMesh();mesh_it!=LastMesh();mesh_it++){ CEditableMesh* MESH = *mesh_it; // generate vertex offset MESH->GenerateSVertices (1); for (u32 f_id=0; f_id!=MESH->GetFCount(); f_id++){ for (int k=0; k<3; k++){ st_SVert& sv = MESH->m_SVertices[f_id*3+k]; VERIFY (sv.bones.size()==1); u16 b_id = sv.bones[0].id;//(sv.bones.size()>1)?(sv.bones[0].w>sv.bones[1].w?sv.bones[0].id:sv.bones[1].id):sv.bones[0].id; FvectorVec& P = bone_points[b_id]; bool bFound = false; Fvector p; m_Bones[b_id]->_RITransform().transform_tiny(p,sv.offs); for (FvectorIt p_it=P.begin(); p_it!=P.end(); p_it++) if (p_it->similar(p)){ bFound=true; break; } if (!bFound) P.push_back(p); // if (sv.bone1!=BI_NONE) bone_points[sv.bone1].push_back(sv.offs1); } } MESH->UnloadSVertices(); } BoneVec& lst = m_Bones; for(BoneIt b_it=lst.begin(); b_it!=lst.end(); b_it++){ if (bSelOnly&&!(*b_it)->flags.is(CBone::flSelected)) continue; FvectorVec& positions = bone_points[b_it-lst.begin()]; ComputeOBB_WML ((*b_it)->shape.box,positions); ComputeSphere ((*b_it)->shape.sphere,positions); ComputeCylinder ((*b_it)->shape.cylinder,(*b_it)->shape.box,positions); (*b_it)->center_of_mass.set((*b_it)->shape.sphere.P); } return true; }
/* bool CEditableObject::LoadSMotions(const char* fname) { IReader* F = FS.r_open(fname); ClearSMotions(); // object motions m_SMotions.resize(F->r_u32()); SetActiveSMotion(0); for (SMotionIt m_it=m_SMotions.begin(); m_it!=m_SMotions.end(); m_it++){ *m_it = xr_new<CSMotion>(); if (!(*m_it)->Load(*F)){ ELog.DlgMsg(mtError,"Motions has different version. Load failed."); xr_delete(*m_it); m_SMotions.clear(); FS.r_close(F); return false; } if (!CheckBoneCompliance(*m_it)){ ClearSMotions(); ELog.DlgMsg(mtError,"Load failed.",fname); xr_delete(&*m_it); FS.r_close(F); return false; } } FS.r_close(F); return true; } */ bool CEditableObject::AppendSMotion(LPCSTR fname, SMotionVec* inserted) { VERIFY(IsSkeleton()); bool bRes = true; LPCSTR ext = strext(fname); if (0==stricmp(ext,".skl")){ CSMotion* M = xr_new<CSMotion>(); if (!M->LoadMotion(fname)){ ELog.Msg(mtError,"Motion '%s' can't load. Append failed.",fname); xr_delete(M); bRes = false; }else{ string256 name; _splitpath(fname,0,0,name,0); if (CheckBoneCompliance(M)){ M->SortBonesBySkeleton(m_Bones); string256 m_name; GenerateSMotionName (m_name,name,M); M->SetName (m_name); m_SMotions.push_back(M); if (inserted) inserted->push_back(M); // optimize M->Optimize (); }else{ ELog.Msg(mtError,"Append failed.",fname); xr_delete(M); bRes = false; } } }else if (0==stricmp(ext,".skls")){ IReader* F = FS.r_open(fname); if (!F){ ELog.Msg(mtError,"Can't open file '%s'.",fname); bRes = false; } if (bRes){ // object motions int cnt = F->r_u32(); for (int k=0; k<cnt; k++){ CSMotion* M = xr_new<CSMotion>(); if (!M->Load(*F)){ ELog.Msg(mtError,"Motion '%s' has different version. Load failed.",M->Name()); xr_delete(M); bRes = false; break; } if (!CheckBoneCompliance(M)){ xr_delete(M); bRes = false; break; } if (bRes){ M->SortBonesBySkeleton(m_Bones); string256 m_name; GenerateSMotionName (m_name,M->Name(),M); M->SetName (m_name); m_SMotions.push_back(M); if (inserted) inserted->push_back(M); // optimize M->Optimize (); } } } FS.r_close(F); } return bRes; }
void CEditableObject::RenderBones(const Fmatrix& parent) { if (IsSkeleton()){ // render BoneVec& lst = m_Bones; for(BoneIt b_it=lst.begin(); b_it!=lst.end(); b_it++){ Device.SetShader(Device.m_WireShader); RCache.set_xform_world(parent); Fmatrix& M = (*b_it)->_LTransform(); Fvector p1 = M.c; u32 c_joint = (*b_it)->flags.is(CBone::flSelected)?color_bone_sel_color:color_bone_norm_color; if (EPrefs->object_flags.is(epoDrawJoints)) DU_impl.DrawJoint (p1,joint_size,c_joint); // center of mass if ((*b_it)->shape.type!=SBoneShape::stNone){ Fvector cm; M.transform_tiny(cm,(*b_it)->center_of_mass); if ((*b_it)->flags.is(CBone::flSelected)){ float sz = joint_size*2.f; DU_impl.DrawCross (cm, sz,sz,sz, sz,sz,sz, 0xFFFFFFFF, false); DU_impl.DrawRomboid (cm,joint_size*0.7f,color_bone_sel_cm); }else{ DU_impl.DrawRomboid (cm,joint_size*0.7f,color_bone_norm_cm); } } /* if (0){ M.transform_dir (d); p2.mad (p1,d,(*b_it)->_Length()); DU.DrawLine (p1,p2,c_joint); } */ if ((*b_it)->Parent()){ Device.SetShader(Device.m_SelectionShader); Fvector& p2 = (*b_it)->Parent()->_LTransform().c; DU_impl.DrawLine (p1,p2,color_bone_link_color); } if (EPrefs->object_flags.is(epoDrawBoneAxis)){ Fmatrix mat; mat.mul(parent,M); DU_impl.DrawObjectAxis(mat,0.03f,(*b_it)->flags.is(CBone::flSelected)); } if (EPrefs->object_flags.is(epoDrawBoneNames)){ parent.transform_tiny(p1); u32 c = (*b_it)->flags.is(CBone::flSelected)?0xFFFFFFFF:0xFF000000; u32 s = (*b_it)->flags.is(CBone::flSelected)?0xFF000000:0xFF909090; DU_impl.OutText(p1,(*b_it)->Name().c_str(),c,s); } if (EPrefs->object_flags.is(epoDrawBoneShapes)){ Device.SetShader(Device.m_SelectionShader); Fmatrix mat = M; mat.mulA_43 (parent); u32 c = (*b_it)->flags.is(CBone::flSelected)?0x80ffffff:0x300000ff; if ((*b_it)->shape.Valid()){ switch ((*b_it)->shape.type){ case SBoneShape::stBox: DU_impl.DrawOBB (mat,(*b_it)->shape.box,c,c); break; case SBoneShape::stSphere: DU_impl.DrawSphere (mat,(*b_it)->shape.sphere,c,c,TRUE,TRUE);break; case SBoneShape::stCylinder:DU_impl.DrawCylinder (mat,(*b_it)->shape.cylinder.m_center,(*b_it)->shape.cylinder.m_direction,(*b_it)->shape.cylinder.m_height,(*b_it)->shape.cylinder.m_radius,c,c,TRUE,TRUE);break; } } } } } }