Пример #1
0
//------------------------------------------------------------------------------
 bool CPSLibrary::Save2()
{
	FS.dir_delete("$game_particles$","",TRUE);
	string_path				fn;
    SPBItem* pb 		= UI->ProgressStart(m_PEDs.size()+m_PGDs.size(),"Saving particles...");
    for (PS::PEDIt it=m_PEDs.begin(); it!=m_PEDs.end(); ++it)
    {
       pb->Inc				();
    	PS::CPEDef*	pe 		= (*it);
        FS.update_path		(fn, "$game_particles$", pe->m_Name.c_str());
        strcat				(fn,".pe");
		CInifile 			ini(fn,FALSE,FALSE,FALSE);
		pe->Save2			(ini);
		ini.save_as			(fn);
    }

    for (PS::PGDIt g_it=m_PGDs.begin(); g_it!=m_PGDs.end(); ++g_it)
    {
       pb->Inc				();
    	PS::CPGDef*	pg 		= (*g_it);
        FS.update_path		(fn, "$game_particles$", pg->m_Name.c_str());
        strcat				(fn,".pg");
		CInifile 			ini(fn,FALSE,FALSE,FALSE);
        pg->Save2			(ini);
		ini.save_as			(fn);
    }
    UI->ProgressEnd		(pb);
    return true;
}
Пример #2
0
bool EDetailManager::UpdateObjects(bool bUpdateTex, bool bUpdateSelectedOnly)
{
	m_Base.ReloadImage();
	if (!m_Base.Valid()){ 
    	ELog.DlgMsg(mtError,"Invalid base texture!");
    	return false;
    }
	if (objects.empty()){
    	ELog.DlgMsg(mtError,"Object list empty!");
     	return false;
    }
    // update objects
    SPBItem* pb = UI->ProgressStart(dtH.size_x*dtH.size_z,"Updating objects...");
    for (u32 z=0; z<dtH.size_z; z++)
        for (u32 x=0; x<dtH.size_x; x++){
        	if (!bUpdateSelectedOnly||(bUpdateSelectedOnly&&m_Selected[z*dtH.size_x+x]))
	        	UpdateSlotObjects(x,z);
	        pb->Inc();
        }
    UI->ProgressEnd(pb);

    InvalidateCache		();

    return true;
}
Пример #3
0
void TfraBottomBar::RedrawBar()
{
	SPBItem* pbi 	= UI->ProgressLast();
	if (pbi){
        AnsiString 	txt;
        float 		p,m;
        pbi->GetInfo(txt,p,m);
        // status line
        if (paStatus->Caption!=txt){
	        paStatus->Caption		= txt;
    	    paStatus->Repaint		();
        }
        // progress
    	int val = fis_zero(m)?0:(int)((p/m)*100);
        if (val!=cgProgress->Progress){
			cgProgress->Progress	= val;
	        cgProgress->Repaint	();
        }
    	if (false==cgProgress->Visible) 
        	cgProgress->Visible 	= true;
    }else{
    	if (cgProgress->Visible){
            // status line
            paStatus->Caption		= "";
            paStatus->Repaint		();
	        // progress
        	cgProgress->Visible 	= false;
	        cgProgress->Progress	= 0;
        }
    }
}
Пример #4
0
void TfrmImageLib::InitItemsList()
{
    if (!form->bImportMode)  ImageLib.GetTexturesRaw(texture_map);
    
	ListItemsVec 		items;
/*
	xr_string 		ltx_nm;
        FS.update_path		(ltx_nm,_game_textures_,"textures.ltx");
	CInifile* ltx_ini 	= xr_new<CInifile>		(ltx_nm.c_str(),FALSE,TRUE,FALSE);
*/
	SPBItem* pb		= UI->ProgressStart		(texture_map.size(),"Fill list...");
    // fill
	FS_FileSetIt it         = texture_map.begin();
	FS_FileSetIt _E         = texture_map.end();
    for (; it!=_E; it++)
    {
	pb->Inc			();
    	ListItem* I		= LHelper().CreateItem(items,it->name.c_str(),0);
//.     I->tag			= ltx_ini->line_exist("types",it->name.c_str())?ltx_ini->r_u32("types",it->name.c_str()):-1;
        I->tag                  = Device.Resources->m_textures_description.GetTextureType(it->name.c_str());
        Msg("%s-%d",it->name.c_str(),I->tag);
    }
    UI->ProgressEnd		(pb);
    m_ItemList->AssignItems     (items,false,true);
//.    xr_delete			(ltx_ini);
}
Пример #5
0
void CSoundManager::CleanupSounds()
{
	FS_FileSet 	M_BASE;
	FS_FileSet 	M_THUM;
    FS_FileSet 	M_GAME;
    FS_FileSet 	M_GAME_DEL;
    FS_FileSet 	M_THM_DEL;

    FS.file_list	(M_BASE,_sounds_,		FS_ListFiles|FS_ClampExt,"*.wav");
    FS.file_list	(M_THUM,_sounds_,		FS_ListFiles|FS_ClampExt,"*.thm");
    FS.file_list	(M_GAME,_game_sounds_,	FS_ListFiles|FS_ClampExt,"*.ogg");

    FS_FileSetIt it;
	FS_FileSetIt _E;
    // check source exist
    it	= M_GAME.begin();
	_E 	= M_GAME.end();
	for (; it!=_E; it++){
        xr_string base_name	= EFS.ChangeFileExt(it->name,""); xr_strlwr(base_name);
		FS_FileSetIt bs 		= M_BASE.find(base_name);
    	if (bs==M_BASE.end())
        	M_GAME_DEL.insert	(*it);
    }
    it	= M_THUM.begin();
	_E 	= M_THUM.end();
	for (; it!=_E; it++){
        xr_string base_name	= EFS.ChangeFileExt(it->name,""); xr_strlwr(base_name);
		FS_FileSetIt bs 		= M_BASE.find(base_name);
    	if (bs==M_BASE.end())
        	M_THM_DEL.insert	(*it);
    }

    SPBItem* pb = UI->ProgressStart(M_GAME_DEL.size()+M_THM_DEL.size(),"Cleanup sounds...");
    // mark game del sounds
    it	= M_GAME_DEL.begin();
	_E 	= M_GAME_DEL.end();
	for (; it!=_E; it++){
        xr_string base_name	= EFS.ChangeFileExt(it->name,""); xr_strlwr(base_name);
        string_path 			fn;
        FS.update_path			(fn,_game_sounds_,EFS.ChangeFileExt(base_name,".ogg").c_str());
        EFS.MarkFile			(fn,true);
        pb->Inc					();
    }
    // mark thm sounds
    it	= M_THM_DEL.begin();
	_E 	= M_THM_DEL.end();
	for (; it!=_E; it++){
        xr_string base_name	= EFS.ChangeFileExt(it->name,""); xr_strlwr(base_name);
        string_path 			fn;
        FS.update_path			(fn,_sounds_,EFS.ChangeFileExt(base_name,".thm").c_str());
        EFS.MarkFile			(fn,true);
        pb->Inc					();
    }
    UI->ProgressEnd				(pb);
}
Пример #6
0
void CEditableObject::OptimizeSMotions()
{
#ifdef _EDITOR
	SPBItem* pb				= UI->ProgressStart(m_SMotions.size(),"Motions optimizing...");
#endif
	for (SMotionIt s_it=m_SMotions.begin(); s_it!=m_SMotions.end(); s_it++){
        (*s_it)->Optimize	();
#ifdef _EDITOR
		pb->Inc				();
#endif
	}
#ifdef _EDITOR
    UI->ProgressEnd				(pb);
#endif
}
Пример #7
0
bool EDetailManager::UpdateSlots()
{
	// clear previous slots
    xr_free				(dtSlots);
    dtSlots				= xr_alloc<DetailSlot>(dtH.size_x*dtH.size_z);

    SPBItem* pb = UI->ProgressStart(dtH.size_x*dtH.size_z,"Updating bounding boxes...");
    for (u32 z=0; z<dtH.size_z; z++){
        for (u32 x=0; x<dtH.size_x; x++){
        	DetailSlot* slot = dtSlots+z*dtH.size_x+x;
        	UpdateSlotBBox	(x,z,*slot);
	        pb->Inc();
        }
    }
    UI->ProgressEnd(pb);

    m_Selected.resize	(dtH.size_x*dtH.size_z);

    return true;
}
Пример #8
0
void __fastcall TfrmImageLib::ebRebuildAssociationClick(TObject *)
{
	if (ELog.DlgMsg(mtConfirmation,TMsgDlgButtons()<<mbYes<<mbNo,"Are you sure to export association?")==mrNo) return;

    if (!modif_map.empty()){
        int res = ELog.DlgMsg(mtConfirmation,TMsgDlgButtons()<<mbYes<<mbNo<<mbCancel,"Save modified properties?");
        switch (res){
        case mrYes: 	UpdateLib();	break;
        case mrNo: 			  			break;
        case mrCancel: 		  			return;
        }
    }

	string_path nm;
    FS.update_path			(nm,_game_textures_,"textures.ltx");
	CInifile* ini 			= xr_new<CInifile>(nm, FALSE, FALSE, TRUE);

	LockForm				();

    FS_FileSetIt it		= texture_map.begin();
    FS_FileSetIt _E		= texture_map.end();
	SPBItem* pb = UI->ProgressStart(texture_map.size(),"Export association");
    bool bRes=true;
    for (;it!=_E; it++){
        ETextureThumbnail* m_Thm = xr_new<ETextureThumbnail>(it->name.c_str());
	    pb->Inc				(it->name.c_str());
        AnsiString base_name= ChangeFileExt(it->name.c_str(),"");
        ImageLib.WriteAssociation	(ini,base_name.c_str(),m_Thm->_Format());
        xr_delete			(m_Thm);
		if (UI->NeedAbort()){ bRes=false; break; }
    }
	UI->ProgressEnd(pb);

	UnlockForm();

    if (!bRes) ini->bSaveAtEnd = false;
	xr_delete(ini);
}
Пример #9
0
void ESceneAIMapTool::RemoveSelection()
{
    switch (LTools->GetSubTarget()){
    case estAIMapNode:{
    	if (m_Nodes.size()==(u32)SelectionCount(true)){
        	Clear	(true);
        }else{
        	SPBItem* pb = UI->ProgressStart(3,"Removing nodes...");
        	// remove link to sel nodes
	        pb->Inc("erasing nodes");
            // remove sel nodes
           	AINodeIt result		= std::remove_if(m_Nodes.begin(), m_Nodes.end(), delete_sel_node_pred());
            m_Nodes.erase		(result,m_Nodes.end());
	        pb->Inc("updating hash");
            hash_Clear		   	();
		    hash_FillFromNodes 	();
	        pb->Inc("end");
            UI->ProgressEnd(pb);
        }
    }break;
    }
    UpdateHLSelected	();
    UI->RedrawScene		();
}
Пример #10
0
void ESceneAIMapTool::BuildNodes(bool bFromSelectedOnly)
{
	// begin
	m_Nodes.reserve	(1024*1024);

	// Initialize hash
//	hash_Initialize ();

    R_ASSERT(!m_Nodes.empty());
    // Estimate nodes
    Fvector	Pos,LevelSize;
    m_AIBBox.getsize	(LevelSize);
    float estimated_nodes	= (LevelSize.x/m_Params.fPatchSize)*(LevelSize.z/m_Params.fPatchSize);

    SPBItem* pb = UI->ProgressStart(1, "Building nodes...");
    // General cycle
    for (int k=0; k<(int)m_Nodes.size(); k++){
        SAINode* N 			= m_Nodes[k];
    	if (bFromSelectedOnly && !N->flags.is(SAINode::flSelected)) continue;
        // left 
        if (0==N->n1){
            Pos.set			(N->Pos);
            Pos.x			-=	m_Params.fPatchSize;
            N->n1			=	BuildNode(N->Pos,Pos,false);
        }
        // fwd
        if (0==N->n2){
            Pos.set			(N->Pos);
            Pos.z			+=	m_Params.fPatchSize;
            N->n2			=	BuildNode(N->Pos,Pos,false);
        }
        // right
        if (0==N->n3){
            Pos.set			(N->Pos);
            Pos.x			+=	m_Params.fPatchSize;
            N->n3			=	BuildNode(N->Pos,Pos,false);
        }
        // back
        if (0==N->n4){
            Pos.set			(N->Pos);
            Pos.z			-=	m_Params.fPatchSize;
            N->n4			=	BuildNode(N->Pos,Pos,false);
        }
    	if (bFromSelectedOnly){
	        // select neighbour nodes
            if (N->n1) N->n1->flags.set(SAINode::flSelected,TRUE);
            if (N->n2) N->n2->flags.set(SAINode::flSelected,TRUE);
            if (N->n3) N->n3->flags.set(SAINode::flSelected,TRUE);
            if (N->n4) N->n4->flags.set(SAINode::flSelected,TRUE);
        }
        
        if (k%512==0) {
            float	p1	= float(k)/float(m_Nodes.size());
            float	p2	= float(m_Nodes.size())/estimated_nodes;
            float	p	= 0.1f*p1+0.9f*p2;

            clamp	(p,0.f,1.f);
            pb->Update(p);
            // check need abort && redraw
            if (k%32768==0) UI->RedrawScene(true);
            if (UI->NeedAbort()) break;
        }
    }
    UI->ProgressEnd(pb);
}
Пример #11
0
//------------------------------------------------------------------------------
// возвращает список не синхронизированных (модифицированных) текстур
// source_list - содержит список текстур с расширениями
// sync_list - реально сохраненные файлы (после использования освободить)
//------------------------------------------------------------------------------
void CSoundManager::SynchronizeSounds(bool sync_thm, bool sync_game, bool bForceGame, FS_FileSet* source_list, AStringVec* sync_list, FS_FileSet* modif_map)
{        
	FS_FileSet M_BASE;
	FS_FileSet M_THUM;
    FS_FileSet M_GAME;

    if (source_list) M_BASE = *source_list;
    else FS.file_list(M_BASE,_sounds_,FS_ListFiles|FS_ClampExt,"*.wav");
    if (M_BASE.empty()) return;
    if (sync_thm) 	FS.file_list(M_THUM,_sounds_,FS_ListFiles|FS_ClampExt,"*.thm");
    if (sync_game) 	FS.file_list(M_GAME,_game_sounds_,FS_ListFiles|FS_ClampExt,"*.ogg");

    bool bProgress = M_BASE.size()>1;
    
    int m_age					= time(NULL);
    
    SPBItem* pb = 0;
    if (bProgress) pb = UI->ProgressStart(M_BASE.size(),"Synchronize sounds...");
    FS_FileSetIt it=M_BASE.begin();
	FS_FileSetIt _E = M_BASE.end();
	for (; it!=_E; it++){
	    BOOL bUpdated = FALSE;
        xr_string base_name		= EFS.ChangeFileExt(it->name,""); xr_strlwr(base_name);
        string_path				fn;
        FS.update_path			(fn,_sounds_,EFS.ChangeFileExt(base_name,".wav").c_str());
    	if (!FS.exist(fn)) continue;

		FS_FileSetIt th 		= M_THUM.find(base_name);
    	bool bThm 				= ((th==M_THUM.end()) || ((th!=M_THUM.end())&&(th->time_write!=it->time_write)));
  		FS_FileSetIt gm 		= M_GAME.find(base_name);
    	bool bGame				= bThm || ((gm==M_GAME.end()) || ((gm!=M_GAME.end())&&(gm->time_write!=it->time_write)));

		ESoundThumbnail* THM	= 0;

        // backup base sound
    	// check thumbnail
    	if (sync_thm&&bThm){
        	THM 				= xr_new<ESoundThumbnail>(it->name.c_str());
            THM->Save			(m_age);
            bUpdated 			= TRUE;
        }
        // check game sounds
    	if (bForceGame||(sync_game&&bGame)){
        	if (!THM) THM 			= xr_new<ESoundThumbnail>(it->name.c_str()); 
            R_ASSERT(THM);
            string_path 			src_name;
            strconcat				(sizeof(src_name),src_name, base_name.c_str(), ".wav");

            FS.update_path			(src_name,_sounds_,src_name);
            string_path 			game_name;
            strconcat				(sizeof(game_name),game_name, base_name.c_str(), ".ogg");
            FS.update_path			(game_name,_game_sounds_,game_name);
            MakeGameSound			(THM,src_name,game_name);
            if (sync_list) 			sync_list->push_back(base_name.c_str());
            if (modif_map) 			modif_map->insert(*it);
            bUpdated = TRUE;
		}
        
		if (THM) xr_delete(THM);
		if (UI->NeedAbort()) 	break;
        if (bProgress) 
		    pb->Inc		(bUpdated?xr_string(base_name+" - UPDATED.").c_str():"",bUpdated);
        if (bUpdated){
            string_path				wav_fn,thm_fn,ogg_fn;
            FS.update_path			(wav_fn,_sounds_,		EFS.ChangeFileExt(base_name,".wav").c_str());
            FS.update_path			(thm_fn,_sounds_,		EFS.ChangeFileExt(base_name,".thm").c_str());
            FS.update_path			(ogg_fn,_game_sounds_,	EFS.ChangeFileExt(base_name,".ogg").c_str());
            FS.set_file_age			(wav_fn,m_age);
            FS.set_file_age			(thm_fn,m_age);
            FS.set_file_age			(ogg_fn,m_age);
        }
    }
    if (bProgress) UI->ProgressEnd(pb);
}
bool ESceneObjectTool::ExportBreakableObjects(SExportStreams* F)
{
	bool bResult = true;
    CGeomPartExtractor* extractor=0;

    Fbox 		bb;
    if (!GetBox(bb)) return false;

    extractor	= xr_new<CGeomPartExtractor>();
    extractor->Initialize(bb,EPS_L,2);

    UI->SetStatus	("Export breakable objects...");
	// collect verts&&faces
    {
	    SPBItem* pb = UI->ProgressStart(m_Objects.size(),"Prepare geometry...");
        for (ObjectIt it=m_Objects.begin(); it!=m_Objects.end(); it++){
	        pb->Inc();
            CSceneObject* obj 		= dynamic_cast<CSceneObject*>(*it); VERIFY(obj);
            if (obj->IsStatic()){
                CEditableObject *O 	= obj->GetReference();
                const Fmatrix& T 	= obj->_Transform();
                for(EditMeshIt M=O->FirstMesh();M!=O->LastMesh();M++)
                    if (!build_mesh	(T,*M,extractor,SGameMtl::flBreakable,FALSE)){bResult=false;break;}
            }
        }
	    UI->ProgressEnd(pb);
    }
    if (!extractor->Process())		bResult = false;
    // export parts
    if (bResult){
    	SBPartVec& parts			= extractor->GetParts();
	    SPBItem* pb = UI->ProgressStart(parts.size(),"Export Parts...");
        for (SBPartVecIt p_it=parts.begin(); p_it!=parts.end(); p_it++){
	        pb->Inc();
            SBPart*	P				= *p_it;
        	if (P->Valid()){
                // export visual
                AnsiString sn		= AnsiString().sprintf("meshes\\brkbl#%d.ogf",(p_it-parts.begin()));
                xr_string fn		= Scene->LevelPath()+sn.c_str();
                IWriter* W			= FS.w_open(fn.c_str()); R_ASSERT(W);
                if (!P->Export(*W,1)){
                    ELog.DlgMsg		(mtError,"Invalid breakable object.");
                    bResult 		= false;
                    break;
                }
                FS.w_close			(W);
                // export spawn object
                {
                    AnsiString entity_ref		= "breakable_object";
                    ISE_Abstract*	m_Data		= create_entity(entity_ref.c_str()); 	VERIFY(m_Data);
                    CSE_Visual* m_Visual		= m_Data->visual();	VERIFY(m_Visual);
                    // set params
                    m_Data->set_name			(entity_ref.c_str());
                    m_Data->set_name_replace	(sn.c_str());
                    m_Data->position().set		(P->m_RefOffset);
                    m_Data->angle().set			(P->m_RefRotate);
                    m_Visual->set_visual		(sn.c_str(),false);

					if (s_draw_dbg){
                        Fmatrix MX;
                        MX.setXYZi				(P->m_RefRotate);
                        MX.translate_over		(P->m_RefOffset);
                        Fvector DR				= {0,0,1};
                        MX.transform_dir		(DR);
                        Tools->m_DebugDraw.AppendLine(P->m_RefOffset,Fvector().mad(P->m_RefOffset,MX.k,1.f),0xFF0000FF,false,false);
                    }

                    NET_Packet					Packet;
                    m_Data->Spawn_Write			(Packet,TRUE);

                    F->spawn.stream.open_chunk	(F->spawn.chunk++);
                    F->spawn.stream.w			(Packet.B.data,Packet.B.count);
                    F->spawn.stream.close_chunk	();
                    destroy_entity				(m_Data);
                }
            }else{
            	ELog.Msg(mtError,"Can't export invalid part #%d",p_it-parts.begin());
            }
        }
	    UI->ProgressEnd(pb);
    }
    // clean up
    xr_delete(extractor);

    return bResult;
}
bool ESceneObjectTool::ExportClimableObjects(SExportStreams* F)
{
	bool bResult                    = true;
    CGeomPartExtractor* extractor   = 0;

    Fbox 		bb;
    if (!GetBox(bb))
        return  false;

    extractor	                    = xr_new<CGeomPartExtractor>();
    extractor->Initialize           (bb,EPS_L,int_max);

    UI->SetStatus	("Export climable objects...");
	// collect verts&&faces
    {
	    SPBItem* pb                 = UI->ProgressStart(m_Objects.size(), "Prepare geometry...");
        for (ObjectIt it=m_Objects.begin(); it!=m_Objects.end(); it++)
        {
	        pb->Inc();
            CSceneObject* obj 		= dynamic_cast<CSceneObject*>(*it);
            VERIFY                  (obj);
            if (obj->IsStatic())
            {
                CEditableObject *O 	= obj->GetReference();
                const Fmatrix& T 	= obj->_Transform();
                
                for(EditMeshIt M =O->FirstMesh(); M!=O->LastMesh(); M++)
                    if (!build_mesh	(T, *M, extractor, SGameMtl::flClimable, TRUE))
                    {
                      bResult       = false;
                      break;
                    }
            }
        }
	    UI->ProgressEnd(pb);
    }
    if (!extractor->Process())
        bResult                     = false;

    // export parts
    if (bResult)
    {
    	SBPartVec& parts			= extractor->GetParts();
	    SPBItem* pb                 = UI->ProgressStart(parts.size(),"Export Parts...");
        for (SBPartVecIt p_it=parts.begin(); p_it!=parts.end(); p_it++)
        {
	        pb->Inc                 ();
            SBPart*	P				= *p_it;
        	if (P->Valid())
            {
                // export visual
                AnsiString sn		            = AnsiString().sprintf("clmbl#%d",(p_it-parts.begin()));

				Fvector local_normal	        = {0,0,0};

                LPCSTR mat_name = NULL;
                for (SBFaceVecIt it=P->m_Faces.begin(); it!=P->m_Faces.end(); it++)
                {
                	for (u32 k=0; k<3; k++)
                        local_normal.add	        ((*it)->n[k]);

                    mat_name     = (*it)->surf->_GameMtlName();
                }

                local_normal.normalize_safe		();
                
                // export spawn object
                {
                    AnsiString entity_ref		= "climable_object";
                    ISE_Abstract*	m_Data		= create_entity(entity_ref.c_str()); 	VERIFY(m_Data);
                    ISE_Shape* m_Shape			= m_Data->shape();                      VERIFY(m_Shape);
//					CSE_Visual* m_Visual		= m_Data->visual();	VERIFY(m_Visual);
                    // set params
                    m_Data->set_name			(entity_ref.c_str());
                    m_Data->set_name_replace	(sn.c_str());
                    // set shape
                    CShapeData::shape_def		shape;
                    shape.type					= CShapeData::cfBox;
                    shape.data.box.scale		((P->m_BBox.max.x-P->m_BBox.min.x)*0.5f,
                    							(P->m_BBox.max.y-P->m_BBox.min.y)*0.5f,
                                                (P->m_BBox.max.z-P->m_BBox.min.z)*0.5f);
                    m_Shape->assign_shapes		(&shape,1);
					// orientate object
	          		if (!OrientToNorm(local_normal,P->m_OBB.m_rotate,P->m_OBB.m_halfsize))
                    {
                    	ELog.Msg(mtError,"Invalid climable object found. [%3.2f, %3.2f, %3.2f]",VPUSH(P->m_RefOffset));
					}
                    else
                    {
                        Fmatrix M; M.set			(P->m_OBB.m_rotate.i,P->m_OBB.m_rotate.j,P->m_OBB.m_rotate.k,P->m_OBB.m_translate);
                        M.getXYZ					(P->m_RefRotate); // не i потому что в движке так
                        m_Data->position().set		(P->m_RefOffset); 
                        m_Data->angle().set			(P->m_RefRotate);

                        m_Data->set_additional_info((void*)mat_name);
                        NET_Packet					Packet;
                        m_Data->Spawn_Write			(Packet,TRUE);

                        F->spawn.stream.open_chunk	(F->spawn.chunk++);
                        F->spawn.stream.w			(Packet.B.data,Packet.B.count);
                        F->spawn.stream.close_chunk	();

						if (s_draw_dbg)
                        {
                            Tools->m_DebugDraw.AppendOBB(P->m_OBB);
                            M.transform_dir				(local_normal);
                            Tools->m_DebugDraw.AppendLine(P->m_RefOffset,Fvector().mad(P->m_RefOffset,local_normal,1.f));
                        }
                    }
                    destroy_entity				(m_Data);
                }
            }else
            {
            	ELog.Msg(mtError,"Can't export invalid part #%d",p_it-parts.begin());
            }
        }
	    UI->ProgressEnd     (pb);
    }
    // clean up
    xr_delete               (extractor);

    return                  bResult;
}
Пример #14
0
void ESceneAIMapTool::SmoothNodes()
{
    SPBItem* pb = UI->ProgressStart(m_Nodes.size(), "Smoothing nodes...");

	AINodeVec	smoothed;	smoothed.reserve(m_Nodes.size());
	U8Vec		mark;		mark.assign		(m_Nodes.size(),0);

    int	sm_nodes=0;
    
    EnumerateNodes			();
	for (AINodeIt it=m_Nodes.begin(); it!=m_Nodes.end(); it++){
		SAINode& 	N 		= **it;
        Fvector		P1,P2,P3,P4,P,REF;
        int			c;

		if (N.flags.is(SAINode::flSelected)){
        	sm_nodes++;
        
            // smooth point LF
            {
                bool	bCorner	= false;

                c=1;	N.PointLF(REF,m_Params.fPatchSize);	P1.set(REF);
                if (N.nLeft()) {
                    SAINode& L = *N.nLeft();

                    L.PointFR(P,m_Params.fPatchSize);	merge(P1);
                    if (L.nForward()) {
                        bCorner = true;
                        SAINode& C = *L.nForward();

                        C.PointRB(P,m_Params.fPatchSize);	merge(P1);
                    }
                }
                if (N.nForward()) {
                    SAINode& F = *N.nForward();

                    F.PointBL(P,m_Params.fPatchSize);	merge(P1);
                    if ((!bCorner) && F.nLeft()) {
                        bCorner = true;

                        SAINode& C = *F.nLeft();
                        C.PointRB(P,m_Params.fPatchSize);	merge(P1);
                    }
                }
                R_ASSERT(c<=4);
                P1.div(float(c));
            }

            // smooth point FR
            {
                bool	bCorner = false;

                c=1;	N.PointFR(REF,m_Params.fPatchSize); P2.set(REF);
                if (N.nForward()) {
                    SAINode& F = *N.nForward();

                    F.PointRB(P,m_Params.fPatchSize);	merge(P2);
                    if (F.nRight()) {
                        bCorner = true;
                        SAINode& C = *F.nRight();

                        C.PointBL(P,m_Params.fPatchSize);	merge(P2);
                    }
                }
                if (N.nRight()) {
                    SAINode& R = *N.nRight();

                    R.PointLF(P,m_Params.fPatchSize);	merge(P2);
                    if ((!bCorner) && R.nForward()) {
                        bCorner = true;

                        SAINode& C = *R.nForward();
                        C.PointBL(P,m_Params.fPatchSize);	merge(P2);
                    }
                }
                R_ASSERT(c<=4);
                P2.div(float(c));
            }

            // smooth point RB
            {
                bool	bCorner = false;

                c=1;	N.PointRB(REF,m_Params.fPatchSize); P3.set(REF);
                if (N.nRight()) {
                    SAINode& R = *N.nRight();

                    R.PointBL(P,m_Params.fPatchSize);	merge(P3);
                    if (R.nBack()) {
                        bCorner = true;
                        SAINode& C = *R.nBack();

                        C.PointLF(P,m_Params.fPatchSize);	merge(P3);
                    }
                }
                if (N.nBack()) {
                    SAINode& B = *N.nBack();

                    B.PointFR(P,m_Params.fPatchSize);	merge(P3);
                    if ((!bCorner) && B.nRight()) {
                        bCorner = true;

                        SAINode& C = *B.nRight();
                        C.PointLF(P,m_Params.fPatchSize);	merge(P3);
                    }
                }
                R_ASSERT(c<=4);
                P3.div(float(c));
            }

            // smooth point BL
            {
                bool	bCorner = false;

                c=1;	N.PointBL(REF,m_Params.fPatchSize); P4.set(REF);
                if (N.nBack()) {
                    SAINode& B = *N.nBack();

                    B.PointLF(P,m_Params.fPatchSize);	merge(P4);
                    if (B.nLeft()) {
                        bCorner = true;
                        SAINode& C = *B.nLeft();

                        C.PointFR(P,m_Params.fPatchSize);	merge(P4);
                    }
                }
                if (N.nLeft()) {
                    SAINode& L = *N.nLeft();

                    L.PointRB(P,m_Params.fPatchSize);	merge(P4);
                    if ((!bCorner) && L.nBack()) {
                        bCorner = true;

                        SAINode& C = *L.nBack();
                        C.PointFR(P,m_Params.fPatchSize);	merge(P4);
                    }
                }
                R_ASSERT(c<=4);
                P4.div(float(c));
            }

            // align plane
            Fvector data[4]; data[0]=P1; data[1]=P2; data[2]=P3; data[3]=P4;
            Fvector vOffs,vNorm,D;
            vNorm.set(N.Plane.n);
            vOffs.set(N.Pos);
            Mgc::OrthogonalPlaneFit(
                4,(Mgc::Vector3*)data,
                *((Mgc::Vector3*)&vOffs),
                *((Mgc::Vector3*)&vNorm)
            );
            if (vNorm.y<0) vNorm.invert();
            // create _new node
            SAINode* NEW 	= xr_new<SAINode>(N);
            NEW->n1 		= (SAINode*)(N.n1?N.n1->idx:InvalidNode);
            NEW->n2 		= (SAINode*)(N.n2?N.n2->idx:InvalidNode);
            NEW->n3 		= (SAINode*)(N.n3?N.n3->idx:InvalidNode);
            NEW->n4 		= (SAINode*)(N.n4?N.n4->idx:InvalidNode);
            NEW->Plane.build(vOffs,vNorm);
            D.set			(0,1,0);
            N.Plane.intersectRayPoint(N.Pos,D,NEW->Pos);	// "project" position
            smoothed.push_back	(NEW);
        }else{
            // create _new node
            SAINode* NEW 	= xr_new<SAINode>(N);
            NEW->n1 		= (SAINode*)(N.n1?N.n1->idx:InvalidNode);
            NEW->n2 		= (SAINode*)(N.n2?N.n2->idx:InvalidNode);
            NEW->n3 		= (SAINode*)(N.n3?N.n3->idx:InvalidNode);
            NEW->n4 		= (SAINode*)(N.n4?N.n4->idx:InvalidNode);
            smoothed.push_back	(NEW);
        }

        int k = it-m_Nodes.begin();
        if (k%128==0) {
            pb->Update(k);
            if (UI->NeedAbort()) break;
        }
    }
    UI->ProgressEnd(pb);
    Clear				(true);
    m_Nodes 			= smoothed;
	DenumerateNodes		();
    hash_FillFromNodes	();

    UpdateHLSelected	();
    
	if (sm_nodes) 		Scene->UndoSave();
}
Пример #15
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;
}
Пример #16
0
int ESceneAIMapTool::BuildNodes(const Fvector& pos, int sz, bool bIC)
{
    // Align emitter
    Fvector			Pos = pos;
    SnapXZ			(Pos,m_Params.fPatchSize);
    Pos.y			+= 1;
    Fvector			Dir; Dir.set(0,-1,0);

	int cnt			= 0;		
    if (m_CFModel)
    	cnt=Scene->RayQuery(PQ,Pos,Dir,3,CDB::OPT_ONLYNEAREST|CDB::OPT_CULL,m_CFModel);
    else
    	cnt=Scene->RayQuery(PQ,Pos,Dir,3,CDB::OPT_ONLYNEAREST|CDB::OPT_CULL,GetSnapList());

    if (0==cnt) {
        ELog.Msg	(mtInformation,"Can't align position.");
        return		0;
    } else {
        Pos.y 		= Pos.y - PQ.r_begin()->range;
    }
		
    // Build first node
    int oldcount 	= m_Nodes.size();
    SAINode* start 	= BuildNode(Pos,Pos,bIC);
    if (!start)		return 0;

    // Estimate nodes
    float estimated_nodes	= (2*sz-1)*(2*sz-1);

	SPBItem* pb 	= 0;
    if (estimated_nodes>1024) pb = UI->ProgressStart(1, "Building nodes...");
    float radius			= sz*m_Params.fPatchSize-EPS_L;
    // General cycle
    for (int k=0; k<(int)m_Nodes.size(); k++){
        SAINode* N 			= m_Nodes[k];
        // left 
        if (0==N->n1){
            Pos.set			(N->Pos);
            Pos.x			-=	m_Params.fPatchSize;
            if (Pos.distance_to(start->Pos)<=radius)
	            N->n1		=	BuildNode(N->Pos,Pos,bIC);
        }
        // fwd
        if (0==N->n2){
            Pos.set			(N->Pos);
            Pos.z			+=	m_Params.fPatchSize;
            if (Pos.distance_to(start->Pos)<=radius)
	            N->n2		=	BuildNode(N->Pos,Pos,bIC);
        }
        // right
        if (0==N->n3){
            Pos.set			(N->Pos);
            Pos.x			+=	m_Params.fPatchSize;
            if (Pos.distance_to(start->Pos)<=radius)
	            N->n3		=	BuildNode(N->Pos,Pos,bIC);
        }
        // back
        if (0==N->n4){
            Pos.set			(N->Pos);
            Pos.z			-=	m_Params.fPatchSize;
            if (Pos.distance_to(start->Pos)<=radius)
	            N->n4		=	BuildNode(N->Pos,Pos,bIC);
        }
        if (estimated_nodes>1024){
            if (k%128==0) {
                float	p1	= float(k)/float(m_Nodes.size());
                float	p2	= float(m_Nodes.size())/estimated_nodes;
                float	p	= 0.1f*p1+0.9f*p2;

                clamp	(p,0.f,1.f);
                pb->Update(p);
                // check need abort && redraw
                if (UI->NeedAbort()) break;
            }
        }
    }
	if (estimated_nodes>1024) UI->ProgressEnd(pb);
    return oldcount-m_Nodes.size();
}
Пример #17
0
bool EDetailManager::Export(LPCSTR path) 
{
    AnsiString fn		= AnsiString(path)+"build.details";
    bool bRes=true;

    SPBItem* pb = UI->ProgressStart(5,"Making details...");
	CMemoryWriter F;

    pb->Inc				("merge textures");
    Fvector2Vec			offsets;
    Fvector2Vec			scales;
    boolVec				rotated;
    RStringSet 			textures_set;
    RStringVec 			textures;
    U32Vec				remap;
    U8Vec remap_object	(objects.size(),u8(-1));

    int slot_cnt		= dtH.size_x*dtH.size_z;
	for (int slot_idx=0; slot_idx<slot_cnt; slot_idx++){
    	DetailSlot* it 	= &dtSlots[slot_idx];
        for (int part=0; part<4; part++){
        	u8 id		= it->r_id(part);
        	if (id!=DetailSlot::ID_Empty) {
            	textures_set.insert(((EDetail*)(objects[id]))->GetTextureName());
                remap_object[id] = 1;
            }
        }
    }
    textures.assign		(textures_set.begin(),textures_set.end());

    U8It remap_object_it= remap_object.begin();

    u32 new_idx			= 0;
    for (DetailIt d_it=objects.begin(); d_it!=objects.end(); d_it++,remap_object_it++)
    	if ((*remap_object_it==1)&&(textures_set.find(((EDetail*)(*d_it))->GetTextureName())!=textures_set.end()))
	    	*remap_object_it	= (u8)new_idx++;

    AnsiString 			do_tex_name = ChangeFileExt(fn,"_details");
    int res				= ImageLib.CreateMergedTexture(textures,do_tex_name.c_str(),STextureParams::tfADXT1,256,1024,256,1024,offsets,scales,rotated,remap);
    if (1!=res)			bRes=FALSE;

    pb->Inc				("export geometry");
    // objects
    int object_idx		= 0;
    if (bRes){
	    do_tex_name 	= ExtractFileName(do_tex_name);
        F.open_chunk	(DETMGR_CHUNK_OBJECTS);
        for (DetailIt it=objects.begin(); it!=objects.end(); it++){
        	if (remap_object[it-objects.begin()]!=u8(-1)){
                F.open_chunk	(object_idx++);
                if (!((EDetail*)(*it))->m_pRefs){
                    ELog.DlgMsg(mtError, "Bad object or object not found '%s'.", ((EDetail*)(*it))->m_sRefs.c_str());
                    bRes=false;
                }else{
                    LPCSTR tex_name = ((EDetail*)(*it))->GetTextureName();
                    for (u32 t_idx=0; t_idx<textures.size(); t_idx++) 
                        if (textures[t_idx]==tex_name) break;
                    VERIFY(t_idx<textures.size());
                    t_idx = remap[t_idx];
                    ((EDetail*)(*it))->Export	(F,do_tex_name.c_str(),offsets[t_idx],scales[t_idx],rotated[t_idx]);
                }
                F.close_chunk	();
                if (!bRes) break;
            }
        }
        F.close_chunk		();
    }
    
    pb->Inc	("export slots");
    // slots
    if (bRes){
    	xr_vector<DetailSlot> dt_slots(slot_cnt); dt_slots.assign(dtSlots,dtSlots+slot_cnt);
        for (slot_idx=0; slot_idx<slot_cnt; slot_idx++){
            DetailSlot& it 	= dt_slots[slot_idx];
            // zero colors need lighting
	        it.c_dir		= 0;
	        it.c_hemi		= 0;
	        it.c_r			= 0;
	        it.c_g			= 0;
	        it.c_b			= 0;
            for (int part=0; part<4; part++){
                u8 id		= it.r_id(part);
                if (id!=DetailSlot::ID_Empty) it.w_id(part,remap_object[id]);
            }
        }
		F.open_chunk	(DETMGR_CHUNK_SLOTS);
		F.w				(dt_slots.begin(),dtH.size_x*dtH.size_z*sizeof(DetailSlot));
	    F.close_chunk	();
        pb->Inc();

        // write header
        dtH.version		= DETAIL_VERSION;
        dtH.object_count= object_idx;

        F.w_chunk		(DETMGR_CHUNK_HEADER,&dtH,sizeof(DetailHeader));

    	bRes 			= F.save_to(fn.c_str());
    }

    pb->Inc();
    UI->ProgressEnd(pb);
    return bRes;
}