//---------------------------------------------------- IC bool build_mesh(const Fmatrix& parent, CEditableMesh* mesh, CGeomPartExtractor* extractor, u32 game_mtl_mask, BOOL ignore_shader) { bool bResult = true; mesh->GenerateVNormals (&parent); // fill faces for (SurfFaces::const_iterator sp_it=mesh->GetSurfFaces().begin(); sp_it!=mesh->GetSurfFaces().end(); sp_it++){ const IntVec& face_lst = sp_it->second; CSurface* surf = sp_it->first; int gm_id = surf->_GameMtl(); if (gm_id==GAMEMTL_NONE_ID){ ELog.DlgMsg (mtError,"Object '%s', surface '%s' contain invalid game material.",mesh->Parent()->m_LibName.c_str(),surf->_Name()); bResult = FALSE; break; } SGameMtl* M = GMLib.GetMaterialByID(gm_id); if (0==M){ ELog.DlgMsg (mtError,"Object '%s', surface '%s' contain undefined game material.",mesh->Parent()->m_LibName.c_str(),surf->_Name()); bResult = FALSE; break; } if (!M->Flags.is(game_mtl_mask)) continue; // check engine shader compatibility if (!ignore_shader){ IBlender* B = EDevice.Resources->_FindBlender(surf->_ShaderName()); if (FALSE==B){ ELog.Msg (mtError,"Can't find engine shader '%s'. Object '%s', surface '%s'. Export interrupted.",surf->_ShaderName(),mesh->Parent()->m_LibName.c_str(),surf->_Name()); bResult = FALSE; break; } if (TRUE==B->canBeLMAPped()){ ELog.Msg (mtError,"Object '%s', surface '%s' contain static engine shader - '%s'. Export interrupted.",mesh->Parent()->m_LibName.c_str(),surf->_Name(),surf->_ShaderName()); bResult = FALSE; break; } } const st_Face* faces = mesh->GetFaces(); VERIFY(faces); const Fvector* vn = mesh->GetVNormals(); VERIFY(vn); const Fvector* pts = mesh->GetVertices(); VERIFY(pts); for (IntVec::const_iterator f_it=face_lst.begin(); f_it!=face_lst.end(); f_it++){ const st_Face& face = faces[*f_it]; Fvector v[3],n[3]; parent.transform_tiny (v[0],pts[face.pv[0].pindex]); parent.transform_tiny (v[1],pts[face.pv[1].pindex]); parent.transform_tiny (v[2],pts[face.pv[2].pindex]); parent.transform_dir (n[0],vn[*f_it*3+0]); n[0].normalize(); parent.transform_dir (n[1],vn[*f_it*3+1]); n[1].normalize(); parent.transform_dir (n[2],vn[*f_it*3+2]); n[2].normalize(); const Fvector2* uv[3]; mesh->GetFaceTC (*f_it,uv); extractor->AppendFace (surf,v,n,uv); } if (!bResult) break; } mesh->UnloadVNormals (); return bResult; }
bool SceneBuilder::BuildSOMModel() { BOOL bResult = TRUE; CMemoryWriter F; F.open_chunk (0); F.w_u32 (0); F.close_chunk (); F.open_chunk (1); ObjectList& lst = Scene->ListObj(OBJCLASS_SCENEOBJECT); for (ObjectIt it=lst.begin(); it!=lst.end(); it++){ CSceneObject* S = (CSceneObject*)(*it); CEditableObject* E = S->GetReference(); R_ASSERT(E); if (E->m_Flags.is(CEditableObject::eoSoundOccluder)){ Fvector v; const Fmatrix& parent = S->_Transform(); for (EditMeshIt m_it=E->FirstMesh(); m_it!=E->LastMesh(); m_it++){ for (SurfFacesPairIt sf_it=(*m_it)->m_SurfFaces.begin(); sf_it!=(*m_it)->m_SurfFaces.end(); sf_it++){ CSurface* surf = sf_it->first; int gm_id = surf->_GameMtl(); if (gm_id==GAMEMTL_NONE_ID){ ELog.DlgMsg (mtError,"Object '%s', surface '%s' contain invalid game material.",(*m_it)->Parent()->m_LibName.c_str(),surf->_Name()); bResult = FALSE; break; } SGameMtl* mtl = GMLib.GetMaterialByID(gm_id); if (0==mtl){ ELog.DlgMsg (mtError,"Object '%s', surface '%s' contain undefined game material.",(*m_it)->Parent()->m_LibName.c_str(),surf->_Name()); bResult = FALSE; break; } BOOL b2Sided = surf->m_Flags.is(CSurface::sf2Sided); IntVec& i_lst = sf_it->second; for (IntIt i_it=i_lst.begin(); i_it!=i_lst.end(); i_it++){ st_Face& face = (*m_it)->m_Faces[*i_it]; for (int k=0; k<3; k++){ parent.transform_tiny(v,(*m_it)->m_Verts[face.pv[k].pindex]); F.w_fvector3(v); } F.w_u32 (b2Sided); F.w_float (mtl->fSndOcclusionFactor); } } } } } BOOL bValid = !!F.chunk_size()&&bResult; F.close_chunk(); if (bValid){ xr_string som_name = MakeLevelPath("level.som"); bValid = F.save_to(som_name.c_str()); } return bValid; }
bool ESceneAIMapTool::GenerateMap(bool bFromSelectedOnly) { std::sort(m_ignored_materials.begin(),m_ignored_materials.end()); bool bRes = false; if (!GetSnapList()->empty()){ if (!RealUpdateSnapList()) return false; if (m_Nodes.empty()){ ELog.DlgMsg(mtError,"Append at least one node."); return false; } if (!m_Flags.is(flSlowCalculate)){ // evict resources ExecCommand (COMMAND_EVICT_OBJECTS); ExecCommand (COMMAND_EVICT_TEXTURES); // prepare collision model u32 avg_face_cnt = 0; u32 avg_vert_cnt = 0; u32 mesh_cnt = 0; Fbox snap_bb; { snap_bb.invalidate (); for (ObjectIt o_it=m_SnapObjects.begin(); o_it!=m_SnapObjects.end(); o_it++){ CSceneObject* S = dynamic_cast<CSceneObject*>(*o_it); VERIFY(S); avg_face_cnt += S->GetFaceCount(); avg_vert_cnt += S->GetVertexCount(); mesh_cnt += S->Meshes()->size(); Fbox bb; S->GetBox (bb); snap_bb.merge (bb); } } SPBItem* pb = UI->ProgressStart(mesh_cnt,"Prepare collision model..."); CDB::Collector* CL = ETOOLS::create_collector(); Fvector verts[3]; for (ObjectIt o_it=m_SnapObjects.begin(); o_it!=m_SnapObjects.end(); o_it++) { CSceneObject* S = dynamic_cast<CSceneObject*>(*o_it); VERIFY(S); CEditableObject* E = S->GetReference(); VERIFY(E); EditMeshVec& _meshes = E->Meshes(); for (EditMeshIt m_it=_meshes.begin(); m_it!=_meshes.end(); m_it++) { pb->Inc(AnsiString().sprintf("%s [%s]",S->Name,(*m_it)->Name().c_str()).c_str()); const SurfFaces& _sfaces = (*m_it)->GetSurfFaces(); for (SurfFaces::const_iterator sp_it=_sfaces.begin(); sp_it!=_sfaces.end(); sp_it++) { CSurface* surf = sp_it->first; // test passable //. SGameMtl* mtl = GMLib.GetMaterialByID(surf->_GameMtl()); //. if (mtl->Flags.is(SGameMtl::flPassable))continue; Shader_xrLC* c_sh = Device.ShaderXRLC.Get(surf->_ShaderXRLCName()); if (!c_sh->flags.bCollision) continue; // collect tris const IntVec& face_lst = sp_it->second; for (IntVec::const_iterator it=face_lst.begin(); it!=face_lst.end(); it++) { E->GetFaceWorld (S->_Transform(),*m_it,*it,verts); ETOOLS::collector_add_face_d(CL,verts[0],verts[1],verts[2], surf->_GameMtl() /* *it */); if (surf->m_Flags.is(CSurface::sf2Sided)) ETOOLS::collector_add_face_d(CL,verts[2],verts[1],verts[0], surf->_GameMtl() /* *it */); } } } } UI->ProgressEnd(pb); UI->SetStatus ("Building collision model..."); // create CFModel m_CFModel = ETOOLS::create_model_cl(CL); ETOOLS::destroy_collector(CL); } // building Scene->lock (); CTimer tm; tm.Start(); BuildNodes (bFromSelectedOnly); tm.GetElapsed_sec(); Scene->unlock (); //. Log("-test time: ", g_tm.GetElapsed_sec()); Log("-building time: ",tm.GetElapsed_sec()); //. Msg("-Rate: %3.2f Count: %d",(g_tm.GetElapsed_sec()/tm.GetElapsed_sec())*100.f,g_tm.count); // unload CFModel ETOOLS::destroy_model(m_CFModel); Scene->UndoSave (); bRes = true; UI->SetStatus (""); }else{ ELog.DlgMsg(mtError,"Fill snap list before generating slots!"); } return bRes; }