void CEditableMesh::GenerateSVertices(u32 influence) { if (!m_Parent->IsSkeleton())return; m_SVertRefs++; if (m_SVertInfl!=influence) UnloadSVertices(true); if (m_SVertices) return; m_SVertices = xr_alloc<st_SVert>(m_FaceCount*3); m_SVertInfl = influence; // CSMotion* active_motion=m_Parent->ResetSAnimation(); m_Parent->CalculateAnimation(0); // generate normals GenerateFNormals (); GenerateVNormals (); for (u32 f_id=0; f_id<m_FaceCount; f_id++){ st_Face& F = m_Faces[f_id]; for (int k=0; k<3; k++){ st_SVert& SV = m_SVertices[f_id*3+k]; Fvector& N = m_VNormals[f_id*3+k]; st_FaceVert& fv = F.pv[k]; Fvector& P = m_Verts[fv.pindex]; st_VMapPtLst& vmpt_lst = m_VMRefs[fv.vmref]; st_VertexWB wb; for (u8 vmpt_id=0; vmpt_id!=vmpt_lst.count; vmpt_id++){ st_VMap& VM = *m_VMaps[vmpt_lst.pts[vmpt_id].vmap_index]; if (VM.type==vmtWeight){ wb.push_back(st_WB(m_Parent->GetBoneIndexByWMap(VM.name.c_str()),VM.getW(vmpt_lst.pts[vmpt_id].index))); if (wb.back().bone==BI_NONE){ ELog.DlgMsg (mtError,"Can't find bone assigned to weight map %s",*VM.name); FATAL("Editor crashed."); return; } }else if(VM.type==vmtUV){ // R_ASSERT2(!uv,"More than 1 uv per vertex found."); SV.uv.set(VM.getUV(vmpt_lst.pts[vmpt_id].index)); } } VERIFY(m_SVertInfl<=4); wb.prepare_weights(m_SVertInfl); SV.offs = P; SV.norm = N; SV.bones.resize(wb.size()); for (u8 k=0; k<(u8)SV.bones.size(); k++){ SV.bones[k].id=wb[k].bone; SV.bones[k].w=wb[k].weight; } } } // restore active motion UnloadFNormals (); UnloadVNormals (); }
bool CEditableMesh::LoadMesh(IReader& F){ u32 version=0; R_ASSERT(F.r_chunk(EMESH_CHUNK_VERSION,&version)); if (version!=EMESH_CURRENT_VERSION){ ELog.DlgMsg( mtError, "CEditableMesh: unsuported file version. Mesh can't load."); return false; } R_ASSERT(F.find_chunk(EMESH_CHUNK_MESHNAME)); F.r_stringZ (m_Name); R_ASSERT(F.r_chunk(EMESH_CHUNK_BBOX,&m_Box)); R_ASSERT(F.r_chunk(EMESH_CHUNK_FLAGS,&m_Flags)); F.r_chunk(EMESH_CHUNK_BOP,&m_Ops); R_ASSERT(F.find_chunk(EMESH_CHUNK_VERTS)); m_VertCount = F.r_u32(); if (m_VertCount<3){ Log ("!CEditableMesh: Vertices<3."); return false; } m_Verts = xr_alloc<Fvector>(m_VertCount); F.r (m_Verts, m_VertCount*sizeof(Fvector)); R_ASSERT(F.find_chunk(EMESH_CHUNK_FACES)); m_FaceCount = F.r_u32(); m_Faces = xr_alloc<st_Face>(m_FaceCount); if (m_FaceCount==0){ Log ("!CEditableMesh: Faces==0."); return false; } F.r (m_Faces, m_FaceCount*sizeof(st_Face)); m_SGs = xr_alloc<u32>(m_FaceCount); Memory.mem_fill32 (m_SGs,m_Flags.is(flSGMask)?0:u32(-1),m_FaceCount); u32 sg_chunk_size = F.find_chunk(EMESH_CHUNK_SG); if (sg_chunk_size){ VERIFY (m_FaceCount*sizeof(u32)==sg_chunk_size); F.r (m_SGs, m_FaceCount*sizeof(u32)); } R_ASSERT(F.find_chunk(EMESH_CHUNK_VMREFS)); m_VMRefs.resize (F.r_u32()); int sz_vmpt = sizeof(st_VMapPt); for (VMRefsIt r_it=m_VMRefs.begin(); r_it!=m_VMRefs.end(); r_it++){ r_it->count = F.r_u8(); r_it->pts = xr_alloc<st_VMapPt>(r_it->count); F.r (r_it->pts, sz_vmpt*r_it->count); } R_ASSERT(F.find_chunk(EMESH_CHUNK_SFACE)); string128 surf_name; u32 sface_cnt = F.r_u16(); // surface-face count for (u32 sp_i=0; sp_i<sface_cnt; sp_i++){ F.r_stringZ (surf_name,sizeof(surf_name)); int surf_id; CSurface* surf = m_Parent->FindSurfaceByName(surf_name, &surf_id); VERIFY(surf); IntVec& face_lst = m_SurfFaces[surf]; face_lst.resize (F.r_u32()); if (face_lst.empty()){ Log ("!Empty surface found: %s",surf->_Name()); return false; } F.r (&*face_lst.begin(), face_lst.size()*sizeof(int)); std::sort (face_lst.begin(),face_lst.end()); } if(F.find_chunk(EMESH_CHUNK_VMAPS_2)){ m_VMaps.resize (F.r_u32()); for (VMapIt vm_it=m_VMaps.begin(); vm_it!=m_VMaps.end(); vm_it++){ *vm_it = xr_new<st_VMap>(); F.r_stringZ ((*vm_it)->name); (*vm_it)->dim = F.r_u8(); (*vm_it)->polymap=F.r_u8(); (*vm_it)->type = F.r_u8(); (*vm_it)->resize(F.r_u32()); F.r ((*vm_it)->getVMdata(), (*vm_it)->VMdatasize()); F.r ((*vm_it)->getVIdata(), (*vm_it)->VIdatasize()); if ((*vm_it)->polymap) F.r ((*vm_it)->getPIdata(), (*vm_it)->PIdatasize()); } }else{ if(F.find_chunk(EMESH_CHUNK_VMAPS_1)){ m_VMaps.resize (F.r_u32()); for (VMapIt vm_it=m_VMaps.begin(); vm_it!=m_VMaps.end(); vm_it++){ *vm_it = xr_new<st_VMap>(); F.r_stringZ ((*vm_it)->name); (*vm_it)->dim = F.r_u8(); (*vm_it)->type = F.r_u8(); (*vm_it)->resize(F.r_u32()); F.r ((*vm_it)->getVMdata(), (*vm_it)->VMdatasize() ); } }else{ R_ASSERT(F.find_chunk(EMESH_CHUNK_VMAPS_0)); m_VMaps.resize (F.r_u32()); for (VMapIt vm_it=m_VMaps.begin(); vm_it!=m_VMaps.end(); vm_it++){ *vm_it = xr_new<st_VMap>(); F.r_stringZ ((*vm_it)->name); (*vm_it)->dim = 2; (*vm_it)->type = vmtUV; (*vm_it)->resize(F.r_u32()); F.r ((*vm_it)->getVMdata(), (*vm_it)->VMdatasize() ); } } // update vmaps RebuildVMaps(); } #ifdef _EDITOR if (!EPrefs->object_flags.is(epoDeffLoadRB)){ GenerateFNormals (); GenerateAdjacency (); GenerateVNormals (); GenerateRenderBuffers(); UnloadFNormals (); UnloadAdjacency (); UnloadVNormals (); } if (!EPrefs->object_flags.is(epoDeffLoadCF)) GenerateCFModel(); #endif Optimize(false); RebuildVMaps(); return true; }