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; }
BOOL SceneBuilder::BuildGame() { SExportStreams F; F.envmodif.stream.open_chunk (F.envmodif.chunk++); F.envmodif.stream.w_u32 (u32(SPAWNPOINT_VERSION)); F.envmodif.stream.close_chunk (); if (!Scene->ExportGame(&F)) return FALSE; BOOL bRes = TRUE; // save spawn { xr_string lev_spawn = MakeLevelPath("level.spawn"); EFS.MarkFile (lev_spawn.c_str(),true); if (F.spawn.chunk) if (!F.spawn.stream.save_to (lev_spawn.c_str())) bRes = FALSE; lev_spawn = MakeLevelPath("level_rs.spawn"); EFS.MarkFile (lev_spawn.c_str(),true); if (F.spawn_rs.chunk) if (!F.spawn_rs.stream.save_to (lev_spawn.c_str())) bRes = FALSE; } // save game { CMemoryWriter GAME; GAME.w_chunk(WAY_PATROLPATH_CHUNK, F.patrolpath.stream.pointer(), F.patrolpath.stream.size()); GAME.w_chunk(RPOINT_CHUNK, F.rpoint.stream.pointer(), F.rpoint.stream.size()); xr_string lev_game = MakeLevelPath("level.game"); EFS.MarkFile (lev_game.c_str(),true); if (GAME.size()) if (!GAME.save_to (lev_game.c_str())) bRes = FALSE; } // save weather env modificator { xr_string lev_env_mod = MakeLevelPath("level.env_mod"); EFS.MarkFile (lev_env_mod.c_str(),true); if (F.envmodif.chunk) if (!F.envmodif.stream.save_to (lev_env_mod.c_str())) bRes = FALSE; } // save static sounds { xr_string lev_sound_static = MakeLevelPath("level.snd_static"); EFS.MarkFile (lev_sound_static.c_str(),true); if (F.sound_static.chunk) if (!F.sound_static.stream.save_to (lev_sound_static.c_str())) bRes = FALSE; } /* // save sound envs { xr_string lev_sound_env = MakeLevelPath("level.snd_env"); EFS.MarkFile (lev_sound_env.c_str(),true); if (LSndLib->MakeEnvGeometry (F.sound_env_geom.stream,false)) if (!F.sound_env_geom.stream.save_to(lev_sound_env.c_str())) bRes = FALSE; } */ // save static PG { xr_string lev_pe_static = MakeLevelPath("level.ps_static"); EFS.MarkFile (lev_pe_static.c_str(),true); if (F.pe_static.chunk) if (!F.pe_static.stream.save_to (lev_pe_static.c_str())) bRes = FALSE; } // save fog volumes if(1) { xr_string lev_fog_vol = MakeLevelPath("level.fog_vol"); EFS.MarkFile (lev_fog_vol.c_str(),true); F.fog_vol.stream.w_u16 (3); //version ObjectList& fogs = Scene->ListObj(OBJCLASS_FOG_VOL); typedef xr_vector<EFogVolume*> tfog_group; typedef xr_map<u32, tfog_group> tfog_groups; tfog_groups fog_groups; for (ObjectIt oit=fogs.begin(); oit!=fogs.end(); ++oit) { EFogVolume* E = dynamic_cast<EFogVolume*>(*oit); R_ASSERT (E); u32 grp_id = E->m_group_id; fog_groups[grp_id].push_back(E); } F.fog_vol.stream.w_u32 (fog_groups.size()); tfog_groups::iterator git = fog_groups.begin(); tfog_groups::iterator git_e = fog_groups.end(); for(; git!=git_e; ++git) { tfog_group& one_group = git->second; std::sort(one_group.begin(), one_group.end(), sort_fog_vol); tfog_group::iterator fgit = one_group.begin(); tfog_group::iterator fgit_e = one_group.end(); for(; fgit!=fgit_e; ++fgit) { EFogVolume* E = *fgit; if(fgit==one_group.begin()) { if(E->m_volumeType!=fvEmitter) { bRes = FALSE; Msg("! incorrect fog volumes grouping"); break; } F.fog_vol.stream.w_string (E->m_volume_profile.c_str()); } Fmatrix M = E->_Transform(); F.fog_vol.stream.w (&M, sizeof(M)); if(fgit==one_group.begin()) { if(E->m_volumeType!=fvEmitter) { bRes = FALSE; Msg("! incorrect fog volumes grouping"); break; } F.fog_vol.stream.w_u32 (one_group.size()-1); }else { if(E->m_volumeType!=fvOcclusion) { bRes = FALSE; Msg("! incorrect fog volumes grouping"); break; } } if(!bRes) break; } if(!bRes) break; } if (!F.fog_vol.stream.save_to(lev_fog_vol.c_str())) bRes = FALSE; } return bRes; }