//----------------------------------------------------
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;
}
예제 #2
0
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;
}
예제 #3
0
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;
}