void CGameFont::Initialize (LPCSTR cShader, LPCSTR cTextureName) { string_path cTexture; LPCSTR _lang = pSettings->r_string("string_table", "font_prefix"); bool is_di = strstr(cTextureName, "ui_font_hud_01") || strstr(cTextureName, "ui_font_hud_02") || strstr(cTextureName, "ui_font_console_02"); if(_lang && !is_di) strconcat (cTexture, cTextureName, _lang); else strcpy (cTexture, cTextureName); uFlags &=~fsValid; vTS.set (1.f,1.f); // обязательно !!! eCurrentAlignment = alLeft; vInterval.set (1.f,1.f); for (int i=0; i<256; i++) CharMap[i] = i; strings.reserve (128); // check ini exist string256 fn,buf; strcpy (buf,cTexture); if (strext(buf)) *strext(buf)=0; R_ASSERT2 (FS.exist(fn,"$game_textures$",buf,".ini"),fn); CInifile* ini = CInifile::Create(fn); if (ini->section_exist("symbol_coords")){ for (int i=0; i<256; i++){ sprintf (buf,"%03d",i); Fvector v = ini->r_fvector3("symbol_coords",buf); TCMap[i].set (v.x,v.y,v[2]-v[0]); } fHeight = ini->r_float("symbol_coords","height"); }else{ if (ini->section_exist("char widths")){ fHeight = ini->r_float("char widths","height"); int cpl = 16; for (int i=0; i<256; i++){ sprintf (buf,"%d",i); float w = ini->r_float("char widths",buf); TCMap[i].set ((i%cpl)*fHeight,(i/cpl)*fHeight,w); } }else{ R_ASSERT(ini->section_exist("font_size")); fHeight = ini->r_float("font_size","height"); float width = ini->r_float("font_size","width"); const int cpl = ini->r_s32 ("font_size","cpl"); for (int i=0; i<256; i++) TCMap[i].set ((i%cpl)*width,(i/cpl)*fHeight,width); } } fCurrentHeight = fHeight; CInifile::Destroy (ini); // Shading pShader.create (cShader,cTexture); pGeom.create (FVF::F_TL, RCache.Vertex.Buffer(), RCache.QuadIB); }
shared_str ui_core::get_xml_name(LPCSTR fn) { string_path str; if(!is_16_9_mode()){ sprintf_s(str, "%s", fn); if ( NULL==strext(fn) ) strcat(str, ".xml"); }else{ string_path str_; if ( strext(fn) ) { strcpy (str, fn); *strext(str) = 0; strcat (str, "_16.xml"); }else sprintf_s (str, "%s_16", fn); if(NULL==FS.exist(str_, "$game_config$", "ui\\" , str) ) { sprintf_s(str, "%s", fn); if ( NULL==strext(fn) ) strcat(str, ".xml"); } #ifdef DEBUG Msg("[16-9] get_xml_name for[%s] returns [%s]", fn, str); #endif } return str; }
void MeshExpUtility::ExportLWO() { BOOL bResult = FALSE; if( m_Items.empty() ){ ELog.Msg(mtError,"Nothing selected" ); ELog.Msg(mtError,"-------------------------------------------------------" ); return; } m_ObjectFlipFaces = IsDlgButtonChecked( hPanel, IDC_OBJECT_FLIPFACES ); string_path m_ExportName; m_ExportName[0]=0; if( !EFS.GetSaveName("$import$",m_ExportName,0,1) ){ ELog.Msg(mtInformation,"Export cancelled" ); ELog.Msg(mtInformation,"-------------------------------------------------------" ); return; } if (strext(m_ExportName)) *strext(m_ExportName)=0; strcat(m_ExportName,".lwo"); EConsole.StayOnTop(TRUE); bResult = SaveAsLWO(m_ExportName); ELog.Msg (mtInformation,bResult?". Export succesfully completed.":"! Export failed."); ELog.Msg (mtInformation,"-------------------------------------------------------" ); EConsole.StayOnTop(FALSE); }
virtual void Execute(LPCSTR args) { string_path cfg_full_name; xr_strcpy(cfg_full_name, (xr_strlen(args) > 0) ? args : Console->ConfigFile); bool b_abs_name = xr_strlen(cfg_full_name) > 2 && cfg_full_name[1] == ':'; if (!b_abs_name) FS.update_path(cfg_full_name, "$app_data_root$", cfg_full_name); if (strext(cfg_full_name)) *strext(cfg_full_name) = 0; xr_strcat(cfg_full_name, ".ltx"); BOOL b_allow = TRUE; if (FS.exist(cfg_full_name)) b_allow = SetFileAttributes(cfg_full_name, FILE_ATTRIBUTE_NORMAL); if (b_allow) { IWriter* F = FS.w_open(cfg_full_name); CConsole::vecCMD_IT it; for (it = Console->Commands.begin(); it != Console->Commands.end(); it++) it->second->Save(F); FS.w_close(F); Msg("Config-file [%s] saved successfully", cfg_full_name); } else Msg("!Cannot store config file [%s]", cfg_full_name); }
void CSE_Visual::set_visual (LPCSTR name, bool load) { string_path tmp; strcpy (tmp,name); if (strext(tmp)) *strext(tmp) = 0; xr_strlwr (tmp); visual_name = tmp; }
void CLevel::PrefetchSound (LPCSTR name) { // preprocess sound name string_path tmp; strcpy_s (tmp,name); xr_strlwr (tmp); if (strext(tmp)) *strext(tmp)=0; shared_str snd_name = tmp; // find in registry SoundRegistryMapIt it = sound_registry.find(snd_name); // if find failed - preload sound if (it==sound_registry.end()) sound_registry[snd_name].create(snd_name.c_str(),st_Effect,sg_SourceType); }
//////////////////////////////////////////////////////////////////////////// // CSE_Visual //////////////////////////////////////////////////////////////////////////// CSE_Visual::CSE_Visual (LPCSTR name) { if(name) { string_path tmp; strcpy (tmp, name); if(strext(tmp)) *strext(tmp) =0; xr_strlwr (tmp); visual_name = tmp; }else visual_name = NULL; startup_animation = "$editor"; flags.zero (); }
virtual void Execute(LPCSTR arguments) { if (!arguments || !*arguments) { Msg ("! no arguments passed"); return; } string_path name; string_path fn; if (0==strext(arguments)) strconcat (sizeof(name),name,arguments,".ogf"); else strcpy_s (name,sizeof(name),arguments); if (!FS.exist(arguments) && !FS.exist(fn, "$level$", name) && !FS.exist(fn, "$game_meshes$", name)) { Msg ("! Cannot find visual \"%s\"",arguments); return; } IRender_Visual *visual = Render->model_Create(arguments); CKinematics *kinematics = smart_cast<CKinematics*>(visual); if (!kinematics) { Render->model_Delete(visual); Msg ("! Invalid visual type \"%s\" (not a CKinematics)",arguments); return; } Msg ("bones for model \"%s\"",arguments); for (u16 i=0, n=kinematics->LL_BoneCount(); i<n; ++i) Msg ("%s",*kinematics->LL_GetData(i).name); Render->model_Delete (visual); }
void CObjectAnimator::LoadMotions(LPCSTR fname) { string_path full_path; if (!FS.exist( full_path, "$level$", fname )) if (!FS.exist( full_path, "$game_anims$", fname )) Debug.fatal(DEBUG_INFO,"Can't find motion file '%s'.",fname); LPCSTR ext = strext(full_path); if (ext){ Clear (); if (0==xr_strcmp(ext,".anm")){ COMotion* M = xr_new<COMotion> (); if (M->LoadMotion(full_path)) m_Motions.push_back(M); else FATAL("ERROR: Can't load motion. Incorrect file version."); }else if (0==xr_strcmp(ext,".anms")){ IReader* F = FS.r_open(full_path); u32 dwMCnt = F->r_u32(); VERIFY(dwMCnt); for (u32 i=0; i<dwMCnt; i++){ COMotion* M = xr_new<COMotion> (); bool bRes = M->Load(*F); if (!bRes) FATAL("ERROR: Can't load motion. Incorrect file version."); m_Motions.push_back(M); } FS.r_close (F); } std::sort(m_Motions.begin(),m_Motions.end(),motion_sort_pred); } }
CDemoPlay::CDemoPlay(const char *name, float ms, u32 cycles, float life_time) : CEffectorCam(cefDemo,life_time/*,FALSE*/) { Msg ("*** Playing demo: %s",name); Console->Execute ("hud_weapon 0"); if(g_bBenchmark) Console->Execute ("hud_draw 0"); fSpeed = ms; dwCyclesLeft = cycles?cycles:1; m_pMotion = 0; m_MParam = 0; string_path nm, fn; strcpy_s (nm,sizeof(nm),name); if (strext(nm)) strcpy(strext(nm),".anm"); if ( FS.exist(fn,"$level$",nm) || FS.exist(fn,"$game_anims$",nm) ) { m_pMotion = xr_new<COMotion> (); m_pMotion->LoadMotion (fn); m_MParam = xr_new<SAnimParams> (); m_MParam->Set (m_pMotion); m_MParam->Play (); }else{ if (!FS.exist(name)) { g_pGameLevel->Cameras().RemoveCamEffector (cefDemo); return ; } IReader* fs = FS.r_open (name); u32 sz = fs->length(); if (sz%sizeof(Fmatrix) != 0) { FS.r_close (fs); g_pGameLevel->Cameras().RemoveCamEffector (cefDemo); return ; } seq.resize (sz/sizeof(Fmatrix)); m_count = seq.size(); CopyMemory (&*seq.begin(),fs->pointer(),sz); FS.r_close (fs); Log ("~ Total key-frames: ",m_count); } stat_started = FALSE; Device.PreCache (50); }
void FHierrarhyVisual::Load(const char* N, IReader *data, u32 dwFlags) { dxRender_Visual::Load(N,data,dwFlags); if (data->find_chunk(OGF_CHILDREN_L)) { // From Link u32 cnt = data->r_u32 (); children.resize (cnt); for (u32 i=0; i<cnt; i++) { #ifdef _EDITOR THROW; #else u32 ID = data->r_u32(); children[i] = (dxRender_Visual*)::Render->getVisual(ID); #endif } bDontDelete = TRUE; } else { if (data->find_chunk(OGF_CHILDREN)) { // From stream IReader* OBJ = data->open_chunk(OGF_CHILDREN); if (OBJ){ IReader* O = OBJ->open_chunk(0); for (int count=1; O; count++) { string_path name_load,short_name,num; xr_strcpy (short_name,N); if (strext(short_name)) *strext(short_name)=0; strconcat (sizeof(name_load),name_load,short_name,":",itoa(count,num,10)); children.push_back ((dxRender_Visual*)::Render->model_CreateChild(name_load,O)); O->close (); O = OBJ->open_chunk (count); } OBJ->close(); } bDontDelete = FALSE; } else { FATAL ("Invalid visual"); } } }
dxRender_Visual* CModelPool::CreateChild(LPCSTR name, IReader* data) { string256 low_name; VERIFY (xr_strlen(name)<256); strcpy_s(low_name,name); strlwr (low_name); if (strext(low_name)) *strext (low_name) = 0; // 1. Search for already loaded model dxRender_Visual* Base = Instance_Find(low_name); //. if (0==Base) Base = Instance_Load(name,data,FALSE); if(0==Base) { if (data) Base = Instance_Load (low_name,data,FALSE); else Base = Instance_Load (low_name,FALSE); } dxRender_Visual* Model = bAllowChildrenDuplicate?Instance_Duplicate(Base):Base; return Model; }
//----------------------------------------------------------------------------------------- BOOL CEditableObject::ParseMAMaterial(CSurface* dest, SXRShaderData& d) { string1024 tmp; strcpy (tmp,d.tex_name.asChar()); if (strext(tmp)) *strext(tmp)=0; dest->SetTexture (EFS.AppendFolderToName(tmp,1,TRUE)); dest->SetFVF (D3DFVF_XYZ|D3DFVF_NORMAL|(1<<D3DFVF_TEXCOUNT_SHIFT)); dest->SetVMap ("Texture"); dest->m_Flags.set (CSurface::sf2Sided,d.double_side); LPCSTR sh_name = _ChangeSymbol(strcpy(tmp,d.eng_name.asChar()),'/','\\'); if (!sh_name||!sh_name[0]){ Log("! Empty shader name, material: ",d.name.asChar()); return FALSE; } dest->SetShader (sh_name); dest->SetShaderXRLC (_ChangeSymbol(strcpy(tmp,d.comp_name.asChar()),'/','\\')); dest->SetGameMtl (_ChangeSymbol(strcpy(tmp,d.gmat_name.asChar()),'/','\\')); return TRUE; }
void fix_texture_name(LPSTR fn) { LPSTR _ext = strext(fn); if( _ext && (0==stricmp(_ext,".tga") || 0==stricmp(_ext,".dds") || 0==stricmp(_ext,".bmp") || 0==stricmp(_ext,".ogm") ) ) *_ext = 0; }
void CObject::Load (LPCSTR section ) { // Name R_ASSERT (section); cName_set (section); cNameSect_set (section); // Visual and light-track if (pSettings->line_exist(section,"visual")){ string_path tmp; strcpy (tmp, pSettings->r_string(section,"visual")); if(strext(tmp)) *strext(tmp) =0; xr_strlwr (tmp); cNameVisual_set (tmp); } setVisible (false); }
void EFS_Utils::MarkFile(LPCSTR fn, bool bDeleteSource) { xr_string ext = strext(fn); ext.insert (1,"~"); xr_string backup_fn = EFS.ChangeFileExt(fn,ext.c_str()); if (bDeleteSource){ FS.file_rename(fn,backup_fn.c_str(),true); }else{ FS.file_copy(fn,backup_fn.c_str()); } }
void CPartition::load(IKinematics* V, LPCSTR model_name) { string_path fn, fn_full; strcpy_s(fn, sizeof(fn), model_name); if(strext(fn)) *strext(fn) = 0; strcat_s(fn, sizeof(fn), ".ltx"); FS.update_path(fn_full,"$game_meshes$", fn); CInifile ini(fn_full, TRUE, TRUE, FALSE); if(ini.sections().size()==0) return; shared_str part_name = "partition_name"; for(u32 i=0; i<MAX_PARTS; ++i) { string64 buff; sprintf_s (buff,sizeof(buff), "part_%d", i); CInifile::Sect S = ini.r_section(buff); CInifile::SectCIt it = S.Data.begin(); CInifile::SectCIt it_e = S.Data.end(); if(S.Data.size()) { P[i].bones.clear_not_free(); } for(;it!=it_e; ++it) { const CInifile::Item& I = *it; if(I.first==part_name) { P[i].Name = I.second; }else { u32 bid = V->LL_BoneID(I.first.c_str()); P[i].bones.push_back(bid); } } } }
dxRender_Visual* CModelPool::Create(const char* name, IReader* data) { #ifdef _EDITOR if (!name||!name[0]) return 0; #endif string_path low_name; VERIFY (xr_strlen(name)<sizeof(low_name)); strcpy_s(low_name,name); strlwr (low_name); if (strext(low_name)) *strext (low_name)=0; // Msg ("-CREATE %s",low_name); // 0. Search POOL POOL_IT it = Pool.find (low_name); if (it!=Pool.end()) { // 1. Instance found dxRender_Visual* Model = it->second; Model->Spawn (); Pool.erase (it); return Model; } else { // 1. Search for already loaded model (reference, base model) dxRender_Visual* Base = Instance_Find (low_name); if (0==Base){ // 2. If not found bAllowChildrenDuplicate = FALSE; if (data) Base = Instance_Load(low_name,data,TRUE); else Base = Instance_Load(low_name,TRUE); bAllowChildrenDuplicate = TRUE; #ifdef _EDITOR if (!Base) return 0; #endif } // 3. If found - return (cloned) reference dxRender_Visual* Model = Instance_Duplicate(Base); Registry.insert ( mk_pair(Model,low_name) ); return Model; } }
void CCC_LoadCFG::Execute(LPCSTR args) { Msg("Executing config-script \"%s\"...", args); string_path cfg_name; xr_strcpy(cfg_name, args); if (strext(cfg_name)) *strext(cfg_name) = 0; xr_strcat(cfg_name, ".ltx"); string_path cfg_full_name; FS.update_path(cfg_full_name, "$app_data_root$", cfg_name); if (NULL == FS.exist(cfg_full_name)) FS.update_path(cfg_full_name, "$fs_root$", cfg_name); if (NULL == FS.exist(cfg_full_name)) xr_strcpy(cfg_full_name, cfg_name); IReader* F = FS.r_open(cfg_full_name); string1024 str; if (F != NULL) { while (!F->eof()) { F->r_string(str, sizeof(str)); if (allow(str)) Console->Execute(str); } FS.r_close(F); Msg("[%s] successfully loaded.", cfg_full_name); } else { Msg("! Cannot open script file [%s]", cfg_full_name); } }
BOOL MeshExpUtility::SaveAsObject(const char* m_ExportName) { BOOL bResult = TRUE; if (m_ExportName[0]==0) return FALSE; ELog.Msg(mtInformation,"Exporting..." ); ELog.Msg(mtInformation,"-------------------------------------------------------" ); CEditableObject* exp_obj=0; if (bResult=BuildObject(exp_obj,m_ExportName)){ ELog.Msg (mtInformation,"Saving object..."); for (SurfaceIt s_it=exp_obj->FirstSurface(); s_it!=exp_obj->LastSurface(); s_it++){ LPSTR t=(LPSTR)(*s_it)->_Texture(); if (strext(t)) *strext(t)=0; } exp_obj->Optimize (); exp_obj->SaveObject (m_ExportName); } xr_delete(exp_obj); return bResult; }
/* -- open the output file -- */ void open_fout(void) { int i; char fnm[FILENAME_MAX]; strcpy(fnm, outfn); i = strlen(fnm) - 1; if (i < 0) { strcpy(fnm, svg || epsf > 1 ? "Out.xhtml" : OUTPUTFILE); } else if (i != 0 || fnm[0] != '-') { if (fnm[i] == '=' && in_fname) { char *p; if ((p = strrchr(in_fname, DIRSEP)) == NULL) p = in_fname; else p++; strcpy(&fnm[i], p); strext(fnm, svg || epsf > 1 ? "xhtml" : "ps"); } else if (fnm[i] == DIRSEP) { strcpy(&fnm[i + 1], svg || epsf > 1 ? "Out.xhtml" : OUTPUTFILE); } #if 0 /*fixme: fnm may be a directory*/ else ... #endif } if (svg == 1 && (i != 0 || fnm[0] != '-')) { cutext(fnm); i = strlen(fnm) - 1; if (strncmp(fnm, outfnam, i) != 0) nepsf = 0; sprintf(&fnm[i + 1], "%03d.svg", ++nepsf); } else if (strcmp(fnm, outfnam) == 0) { return; /* same output file */ } close_output_file(); strcpy(outfnam, fnm); if (i != 0 || fnm[0] != '-') { if ((fout = fopen(fnm, "w")) == NULL) { error(1, NULL, "Cannot create output file %s - abort", fnm); exit(EXIT_FAILURE); } } else { fout = stdout; } }
void CSoundRender_Source::load(LPCSTR name) { string_path fn,N; strcpy (N,name); strlwr (N); if (strext(N)) *strext(N) = 0; fname = N; strconcat (sizeof(fn),fn,N,".ogg"); if (!FS.exist("$level$",fn)) FS.update_path (fn,"$game_sounds$",fn); #ifdef _EDITOR if (!FS.exist(fn)){ FS.update_path (fn,"$game_sounds$","$no_sound.ogg"); } #endif LoadWave (fn); //.R_ASSERT(wave); SoundRender->cache.cat_create (CAT, dwBytesTotal); // if (dwTimeTotal<100) { // Msg ("! WARNING: Invalid wave length (must be at least 100ms), file: %s",fn); // } }
xr_string EFS_Utils::ChangeFileExt(LPCSTR src, LPCSTR ext) { xr_string tmp; LPSTR src_ext = strext(src); if (src_ext) { size_t ext_pos = src_ext - src; tmp.assign(src, 0, ext_pos); } else { tmp = src; } tmp += ext; return tmp; }
dxRender_Visual* CModelPool::Instance_Load (const char* N, BOOL allow_register) { dxRender_Visual *V; string_path fn; string_path name; // Add default ext if no ext at all if (0==strext(N)) strconcat (sizeof(name),name,N,".ogf"); else strcpy_s (name,sizeof(name),N); // Load data from MESHES or LEVEL if (!FS.exist(N)) { if (!FS.exist(fn, "$level$", name)) if (!FS.exist(fn, "$game_meshes$", name)){ #ifdef _EDITOR Msg("! Can't find model file '%s'.",name); return 0; #else xrDebug::Fatal(DEBUG_INFO,"Can't find model file '%s'.",name); #endif } } else { strcpy_s (fn,N); } // Actual loading #ifdef DEBUG if (bLogging) Msg ("- Uncached model loading: %s",fn); #endif // DEBUG IReader* data = FS.r_open(fn); ogf_header H; data->r_chunk_safe (OGF_HEADER,&H,sizeof(H)); V = Instance_Create (H.type); V->Load (N,data,0); FS.r_close (data); g_pGamePersistent->RegisterModel(V); // Registration if (allow_register) Instance_Register(N,V); return V; }
void CGameFont::Initialize (LPCSTR cShader, LPCSTR cTextureName) { string_path cTexture; LPCSTR _lang = pSettings->r_string("string_table", "font_prefix"); bool is_di = strstr(cTextureName, "ui_font_hud_01") || strstr(cTextureName, "ui_font_hud_02") || strstr(cTextureName, "ui_font_console_02"); if(_lang && !is_di) strconcat (sizeof(cTexture),cTexture, cTextureName, _lang); else strcpy_s (cTexture, sizeof(cTexture), cTextureName); uFlags &=~fsValid; vTS.set (1.f,1.f); // обязательно !!! eCurrentAlignment = alLeft; vInterval.set (1.f,1.f); strings.reserve (128); // check ini exist string_path fn,buf; strcpy_s (buf,cTexture); if (strext(buf)) *strext(buf)=0; R_ASSERT2 (FS.exist(fn,"$game_textures$",buf,".ini"),fn); CInifile* ini = CInifile::Create(fn); nNumChars = 0x100; TCMap = ( Fvector* ) xr_realloc( ( void* ) TCMap , nNumChars * sizeof( Fvector ) ); if ( ini->section_exist( "mb_symbol_coords" ) ) { nNumChars = 0x10000; TCMap = ( Fvector* ) xr_realloc( ( void* ) TCMap , nNumChars * sizeof( Fvector ) ); uFlags |= fsMultibyte; fHeight = ini->r_float( "mb_symbol_coords" , "height" ); fXStep = ceil( fHeight / 2.0f ); // Searching for the first valid character Fvector vFirstValid = {0,0,0}; if ( ini->line_exist( "mb_symbol_coords" , "09608" ) ) { Fvector v = ini->r_fvector3( "mb_symbol_coords" , "09608" ); vFirstValid.set( v.x , v.y , 1 + v[2] - v[0] ); } else for ( u32 i=0 ; i < nNumChars ; i++ ) { sprintf_s( buf ,sizeof(buf), "%05d" , i ); if ( ini->line_exist( "mb_symbol_coords" , buf ) ) { Fvector v = ini->r_fvector3( "mb_symbol_coords" , buf ); vFirstValid.set( v.x , v.y , 1 + v[2] - v[0] ); break; } } // Filling entire character table for ( u32 i=0 ; i < nNumChars ; i++ ) { sprintf_s( buf ,sizeof(buf), "%05d" , i ); if ( ini->line_exist( "mb_symbol_coords" , buf ) ) { Fvector v = ini->r_fvector3( "mb_symbol_coords" , buf ); TCMap[i].set( v.x , v.y , 1 + v[2] - v[0] ); } else TCMap[i] = vFirstValid; // "unassigned" unprintable characters } // Special case for space TCMap[ 0x0020 ].set( 0 , 0 , 0 ); // Special case for ideographic space TCMap[ 0x3000 ].set( 0 , 0 , 0 ); }else if (ini->section_exist("symbol_coords")) { float d = 0.0f; //. if(ini->section_exist("width_correction")) //. d = ini->r_float("width_correction", "value"); fHeight = ini->r_float("symbol_coords","height"); for (u32 i=0; i<nNumChars; i++){ sprintf_s (buf,sizeof(buf),"%03d",i); Fvector v = ini->r_fvector3("symbol_coords",buf); TCMap[i].set (v.x,v.y,v[2]-v[0]+d); } }else{ if (ini->section_exist("char widths")){ fHeight = ini->r_float("char widths","height"); int cpl = 16; for (u32 i=0; i<nNumChars; i++){ sprintf_s (buf,sizeof(buf),"%d",i); float w = ini->r_float("char widths",buf); TCMap[i].set ((i%cpl)*fHeight,(i/cpl)*fHeight,w); } }else{ R_ASSERT(ini->section_exist("font_size")); fHeight = ini->r_float("font_size","height"); float width = ini->r_float("font_size","width"); const int cpl = ini->r_s32 ("font_size","cpl"); for (u32 i=0; i<nNumChars; i++) TCMap[i].set ((i%cpl)*width,(i/cpl)*fHeight,width); } } fCurrentHeight = fHeight; CInifile::Destroy (ini); // Shading pFontRender->Initialize(cShader, cTexture); }
/* * extract2 is the word extractor that is used when its important to us * that 'firstword' get special treatment if it is negative (specifically, * that it refer to the "firstword"th word from the END). This is used * basically by the ${n}{-m} expandos and by function_rightw(). * * Note that because of a lot of flak, if you do an expando that is * a "range" of words, unless you #define STRIP_EXTRANEOUS_SPACES, * the "n"th word will be backed up to the first character after the * first space after the "n-1"th word. That apparantly is what everyone * wants, so thats whatll be the default. Those of us who may not like * that behavior or are at ambivelent can just #define it. */ char * real_extract2 (const char *start, int firstword, int lastword, int extended) { /* * If firstword or lastword is negative, then * we take those values from the end of the string */ const char * mark; const char * mark2; char * booya = NULL; CHECK_EXTENDED_SUPPORT /* If firstword is EOS, then the user wants the last word */ if (firstword == EOS) { mark = start + strlen(start); mark = move_word_rel(start, &mark, -1, extended); #ifndef NO_CHEATING /* * Really. the only case where firstword == EOS is * when the user wants $~, in which case we really * dont need to do all the following crud. Of * course, if there ever comes a time that the * user would want to start from the EOS (when?) * we couldnt make this assumption. */ return m_strdup(mark); #endif } /* * SOS is used when the user does $-n, all leading spaces * are retained */ else if (firstword == SOS) mark = start; /* If the firstword is positive, move to that word */ /* Special treatment for $X-, where X is out of range * added by Colten Edwards, fixes the $1- bug.. */ else if (firstword >= 0) { real_move_to_abs_word(start, &mark, firstword, extended); if (!*mark) return m_strdup(empty_string); } /* Otherwise, move to the firstwords from the end */ else { mark = start + strlen(start); move_word_rel(start, &mark, firstword, extended); } #ifndef STRIP_EXTRANEOUS_SPACES /* IF the user did something like this: * $n- $n-m * then include any leading spaces on the 'n'th word. * this is the "old" behavior that we are attempting * to emulate here. */ #ifndef NO_CHEATING if (lastword == EOS || (lastword > firstword)) #else if (((lastword == EOS) && (firstword != EOS)) || (lastword > firstword)) #endif { while (mark > start && my_isspace(mark[-1])) mark--; if (mark > start) mark++; } #endif /* * When we find the last word, we need to move to the * END of the word, so that word 3 to 3, would include * all of word 3, so we sindex to the space after the word */ if (lastword == EOS) mark2 = mark + strlen(mark); else { if (lastword >= 0) real_move_to_abs_word(start, &mark2, lastword+1, extended); else { mark2 = start + strlen(start); move_word_rel(start, &mark2, lastword, extended); } while (mark2 > start && my_isspace(mark2[-1])) mark2--; } /* * If the end is before the string, then there is nothing * to extract (this is perfectly legal, btw) */ if (mark2 < mark) booya = m_strdup(empty_string); else { /* * This is kind of tricky, because the string we are * copying out of is const. So we cant just null off * the trailing character and m_strdup it. */ booya = strext(mark, mark2); } return booya; }
/* * extract is a simpler version of extract2, it is used when we dont * want special treatment of "firstword" if it is negative. This is * typically used by the word/list functions, which also dont care if * we strip out or leave in any whitespace, we just do what is the * fastest. */ char * real_extract (char *start, int firstword, int lastword, int extended) { /* * firstword and lastword must be zero. If they are not, * then they are assumed to be invalid However, please note * that taking word set (-1,3) is valid and contains the * words 0, 1, 2, 3. But word set (-1, -1) is an empty_string. */ char * mark; char * mark2; char * booya = NULL; CHECK_EXTENDED_SUPPORT /* * Before we do anything, we strip off leading and trailing * spaces. * * ITS OK TO TAKE OUT SPACES HERE, AS THE USER SHOULDNT EXPECT * THAT THE WORD FUNCTIONS WOULD RETAIN ANY SPACES. (That is * to say that since the word/list functions dont pay attention * to the whitespace anyhow, noone should have any problem with * those ops removing bothersome whitespace when needed.) */ while (my_isspace(*start)) start++; remove_trailing_spaces(start); if (firstword == EOS) { mark = start + strlen(start); mark = (char *)move_word_rel(start, (const char **)&mark, -1, extended); } /* If the firstword is positive, move to that word */ else if (firstword >= 0) real_move_to_abs_word(start, (const char **)&mark, firstword, extended); /* Its negative. Hold off right now. */ else mark = start; /* * When we find the last word, we need to move to the * END of the word, so that word 3 to 3, would include * all of word 3, so we sindex to the space after the word */ /* EOS is a #define meaning "end of string" */ if (lastword == EOS) mark2 = start + strlen(start); else { if (lastword >= 0) real_move_to_abs_word(start, (const char **)&mark2, lastword+1, extended); else /* its negative -- thats not valid */ return m_strdup(empty_string); while (mark2 > start && my_isspace(mark2[-1])) mark2--; } /* * Ok.. now if we get to here, then lastword is positive, so * we sanity check firstword. */ if (firstword < 0) firstword = 0; if (firstword > lastword) /* this works even if fw was < 0 */ return m_strdup(empty_string); /* * If the end is before the string, then there is nothing * to extract (this is perfectly legal, btw) */ if (mark2 < mark) return m_strdup(empty_string); booya = strext(mark, mark2); return booya; }
void CKinematics::Load(const char* N, IReader *data, u32 dwFlags) { //Msg ("skeleton: %s",N); inherited::Load (N, data, dwFlags); pUserData = NULL; m_lod = NULL; // loading lods IReader* LD = data->open_chunk(OGF_S_LODS); if (LD) { string_path short_name; strcpy_s (short_name,sizeof(short_name),N); if (strext(short_name)) *strext(short_name)=0; // From stream { string_path lod_name; LD->r_string (lod_name, sizeof(lod_name)); //. strconcat (sizeof(name_load),name_load, short_name, ":lod:", lod_name.c_str()); m_lod = ::Render->model_CreateChild(lod_name, NULL); VERIFY3(m_lod,"Cant create LOD model for", N); //. VERIFY2 (m_lod->Type==MT_HIERRARHY || m_lod->Type==MT_PROGRESSIVE || m_lod->Type==MT_NORMAL,lod_name.c_str()); /* strconcat (name_load, short_name, ":lod:1"); m_lod = ::Render->model_CreateChild(name_load,LD); VERIFY (m_lod->Type==MT_SKELETON_GEOMDEF_PM || m_lod->Type==MT_SKELETON_GEOMDEF_ST); */ } LD->close (); } #ifndef _EDITOR // User data IReader* UD = data->open_chunk(OGF_S_USERDATA); pUserData = UD?xr_new<CInifile>(UD,FS.get_path("$game_config$")->m_Path):0; if (UD) UD->close(); #endif // Globals bone_map_N = xr_new<accel> (); bone_map_P = xr_new<accel> (); bones = xr_new<vecBones> (); bone_instances = NULL; // Load bones #pragma todo("container is created in stack!") xr_vector<shared_str> L_parents; R_ASSERT (data->find_chunk(OGF_S_BONE_NAMES)); visimask.zero (); int dwCount = data->r_u32(); // Msg ("!!! %d bones",dwCount); // if (dwCount >= 64) Msg ("!!! More than 64 bones is a crazy thing! (%d), %s",dwCount,N); VERIFY3 (dwCount < 64, "More than 64 bones is a crazy thing!",N); for (; dwCount; dwCount--) { string256 buf; // Bone u16 ID = u16(bones->size()); data->r_stringZ (buf,sizeof(buf)); strlwr(buf); CBoneData* pBone = CreateBoneData(ID); pBone->name = shared_str(buf); pBone->child_faces.resize (children.size()); bones->push_back (pBone); bone_map_N->push_back (mk_pair(pBone->name,ID)); bone_map_P->push_back (mk_pair(pBone->name,ID)); // It's parent data->r_stringZ (buf,sizeof(buf)); strlwr(buf); L_parents.push_back (buf); data->r (&pBone->obb,sizeof(Fobb)); visimask.set (u64(1)<<ID,TRUE); } std::sort (bone_map_N->begin(),bone_map_N->end(),pred_sort_N); std::sort (bone_map_P->begin(),bone_map_P->end(),pred_sort_P); // Attach bones to their parents iRoot = BI_NONE; for (u32 i=0; i<bones->size(); i++) { shared_str P = L_parents[i]; CBoneData* B = (*bones)[i]; if (!P||!P[0]) { // no parent - this is root bone R_ASSERT (BI_NONE==iRoot); iRoot = u16(i); B->SetParentID(BI_NONE); continue; } else { u16 ID = LL_BoneID(P); R_ASSERT (ID!=BI_NONE); (*bones)[ID]->children.push_back(B); B->SetParentID(ID); } } R_ASSERT (BI_NONE != iRoot); // Free parents L_parents.clear(); // IK data IReader* IKD = data->open_chunk(OGF_S_IKDATA); if (IKD){ for (u32 i=0; i<bones->size(); i++) { CBoneData* B = (*bones)[i]; u16 vers = (u16)IKD->r_u32(); IKD->r_stringZ (B->game_mtl_name); IKD->r (&B->shape,sizeof(SBoneShape)); B->IK_data.Import(*IKD,vers); Fvector vXYZ,vT; IKD->r_fvector3 (vXYZ); IKD->r_fvector3 (vT); B->bind_transform.setXYZi(vXYZ); B->bind_transform.translate_over(vT); B->mass = IKD->r_float(); IKD->r_fvector3 (B->center_of_mass); } // calculate model to bone converting matrix (*bones)[LL_GetBoneRoot()]->CalculateM2B(Fidentity); IKD->close(); } // after load process { for (u16 child_idx=0; child_idx<(u16)children.size(); child_idx++) LL_GetChild(child_idx)->AfterLoad (this,child_idx); } // unique bone faces { for (u32 bone_idx=0; bone_idx<bones->size(); bone_idx++) { CBoneData* B = (*bones)[bone_idx]; for (u32 child_idx=0; child_idx<children.size(); child_idx++){ CBoneData::FacesVec faces = B->child_faces[child_idx]; std::sort (faces.begin(),faces.end()); CBoneData::FacesVecIt new_end = std::unique(faces.begin(),faces.end()); faces.erase (new_end,faces.end()); B->child_faces[child_idx].clear_and_free(); B->child_faces[child_idx] = faces; } } } // reset update_callback Update_Callback = NULL; // reset update frame wm_frame = u32(-1); LL_Validate (); }
/* bool CEditableObject::LoadSMotions(const char* fname) { IReader* F = FS.r_open(fname); ClearSMotions(); // object motions m_SMotions.resize(F->r_u32()); SetActiveSMotion(0); for (SMotionIt m_it=m_SMotions.begin(); m_it!=m_SMotions.end(); m_it++){ *m_it = xr_new<CSMotion>(); if (!(*m_it)->Load(*F)){ ELog.DlgMsg(mtError,"Motions has different version. Load failed."); xr_delete(*m_it); m_SMotions.clear(); FS.r_close(F); return false; } if (!CheckBoneCompliance(*m_it)){ ClearSMotions(); ELog.DlgMsg(mtError,"Load failed.",fname); xr_delete(&*m_it); FS.r_close(F); return false; } } FS.r_close(F); return true; } */ bool CEditableObject::AppendSMotion(LPCSTR fname, SMotionVec* inserted) { VERIFY(IsSkeleton()); bool bRes = true; LPCSTR ext = strext(fname); if (0==stricmp(ext,".skl")){ CSMotion* M = xr_new<CSMotion>(); if (!M->LoadMotion(fname)){ ELog.Msg(mtError,"Motion '%s' can't load. Append failed.",fname); xr_delete(M); bRes = false; }else{ string256 name; _splitpath(fname,0,0,name,0); if (CheckBoneCompliance(M)){ M->SortBonesBySkeleton(m_Bones); string256 m_name; GenerateSMotionName (m_name,name,M); M->SetName (m_name); m_SMotions.push_back(M); if (inserted) inserted->push_back(M); // optimize M->Optimize (); }else{ ELog.Msg(mtError,"Append failed.",fname); xr_delete(M); bRes = false; } } }else if (0==stricmp(ext,".skls")){ IReader* F = FS.r_open(fname); if (!F){ ELog.Msg(mtError,"Can't open file '%s'.",fname); bRes = false; } if (bRes){ // object motions int cnt = F->r_u32(); for (int k=0; k<cnt; k++){ CSMotion* M = xr_new<CSMotion>(); if (!M->Load(*F)){ ELog.Msg(mtError,"Motion '%s' has different version. Load failed.",M->Name()); xr_delete(M); bRes = false; break; } if (!CheckBoneCompliance(M)){ xr_delete(M); bRes = false; break; } if (bRes){ M->SortBonesBySkeleton(m_Bones); string256 m_name; GenerateSMotionName (m_name,M->Name(),M); M->SetName (m_name); m_SMotions.push_back(M); if (inserted) inserted->push_back(M); // optimize M->Optimize (); } } } FS.r_close(F); } return bRes; }
bool CEditableObject::Import_LWO(const char* fn, bool bNeedOptimize) { lwObject *I=0; // UI->SetStatus("Importing..."); // UI->ProgressStart(100,"Read file:"); // UI->ProgressUpdate(1); string512 fname; strcpy(fname,fn); #ifdef _EDITOR I=LWO_ImportObject(fname,I); #else unsigned int failID; int failpos; I = lwGetObject( fname, &failID, &failpos ); #endif // UI->ProgressUpdate(100); if (I){ bool bResult=true; ELog.Msg( mtInformation, "CEditableObject: import lwo %s...", fname ); // parse lwo object { m_Meshes.reserve (I->nlayers); m_Surfaces.reserve (I->nsurfs); // surfaces st_lwSurface* Isf=0; { int i=0; // UI->ProgressStart(I->nsurfs,"Check surf:"); for (Isf=I->surf; Isf; Isf=Isf->next){ // UI->ProgressUpdate(i); Isf->alpha_mode=i; // перетираем для внутренних целей !!! CSurface* Osf = new CSurface(); m_Surfaces.push_back(Osf); if (Isf->name&&Isf->name[0]) Osf->SetName(Isf->name); else Osf->SetName("Default"); Osf->m_Flags.set(CSurface::sf2Sided,(Isf->sideflags==3)?TRUE:FALSE); AnsiString en_name="default", lc_name="default", gm_name="default"; XRShader* sh_info = 0; if (Isf->nshaders&&(stricmp(Isf->shader->name,SH_PLUGIN_NAME)==0)){ sh_info = (XRShader*)Isf->shader->data; en_name = sh_info->en_name; lc_name = sh_info->lc_name; gm_name = sh_info->gm_name; }else ELog.Msg(mtError,"CEditableObject: Shader not found on surface '%s'.",Osf->_Name()); #ifdef _EDITOR if (!Device.Resources->_FindBlender(en_name.c_str())){ ELog.Msg(mtError,"CEditableObject: Render shader '%s' - can't find in library.\nUsing 'default' shader on surface '%s'.", en_name.c_str(), Osf->_Name()); en_name = "default"; } if (!Device.ShaderXRLC.Get(lc_name.c_str())){ ELog.Msg(mtError,"CEditableObject: Compiler shader '%s' - can't find in library.\nUsing 'default' shader on surface '%s'.", lc_name.c_str(), Osf->_Name()); lc_name = "default"; } if (!GMLib.GetMaterial(gm_name.c_str())){ ELog.Msg(mtError,"CEditableObject: Game material '%s' - can't find in library.\nUsing 'default' material on surface '%s'.", lc_name.c_str(), Osf->_Name()); gm_name = "default"; } #endif // fill texture layers int cidx; st_lwClip* Icl; u32 dwNumTextures=0; for (st_lwTexture* Itx=Isf->color.tex; Itx; Itx=Itx->next){ string1024 tname=""; dwNumTextures++; cidx = -1; if (Itx->type==ID_IMAP) cidx=Itx->param.imap.cindex; else{ ELog.DlgMsg(mtError, "Import LWO (Surface '%s'): 'Texture' is not Image Map!",Osf->_Name()); bResult=false; break; } if (cidx!=-1){ // get textures for (Icl=I->clip; Icl; Icl=Icl->next) if ((cidx==Icl->index)&&(Icl->type==ID_STIL)){ strcpy(tname,Icl->source.still.name); break; } if (tname[0]==0){ ELog.DlgMsg(mtError, "Import LWO (Surface '%s'): 'Texture' name is empty or non 'STIL' type!",Osf->_Name()); bResult=false; break; } string256 tex_name; _splitpath( tname, 0, 0, tex_name, 0 ); Osf->SetTexture(EFS.AppendFolderToName(tex_name,1,TRUE)); // get vmap refs Osf->SetVMap(Itx->param.imap.vmap_name); } } if (!bResult) break; if (!Osf->_VMap()||!Osf->_VMap()[0]){ ELog.DlgMsg(mtError, "Invalid surface '%s'. VMap empty.",Osf->_Name()); bResult = false; break; } if (!Osf->_Texture()||!Osf->_Texture()[0]){ ELog.DlgMsg(mtError, "Can't create shader. Invalid surface '%s'. Textures empty.",Osf->_Name()); bResult = false; break; } if (en_name.c_str()==0){ ELog.DlgMsg(mtError, "Can't create shader. Invalid surface '%s'. Shader empty.",Osf->_Name()); bResult = false; break; } Osf->SetShader (en_name.c_str()); Osf->SetShaderXRLC (lc_name.c_str()); Osf->SetGameMtl (gm_name.c_str()); Osf->SetFVF (D3DFVF_XYZ|D3DFVF_NORMAL|(dwNumTextures<<D3DFVF_TEXCOUNT_SHIFT)); i++; } } if (bResult){ // mesh layers st_lwLayer* Ilr=0; int k=0; for (Ilr=I->layer; Ilr; Ilr=Ilr->next){ // create new mesh CEditableMesh* MESH= new CEditableMesh(this); m_Meshes.push_back(MESH); if (Ilr->name) MESH->SetName(Ilr->name); else MESH->SetName(""); MESH->m_Box.set(Ilr->bbox[0],Ilr->bbox[1],Ilr->bbox[2], Ilr->bbox[3],Ilr->bbox[4],Ilr->bbox[5]); // parse mesh(lwo-layer) data // vmaps st_lwVMap* Ivmap=0; int vmap_count=0; if (Ilr->nvmaps==0){ ELog.DlgMsg(mtError, "Import LWO: Mesh layer must contain UV!"); bResult=false; break; } // индексы соответствия импортируемых мап static VMIndexLink VMIndices; VMIndices.clear(); for (Ivmap=Ilr->vmap; Ivmap; Ivmap=Ivmap->next){ switch(Ivmap->type){ case ID_TXUV:{ if (Ivmap->dim!=2){ ELog.DlgMsg(mtError, "Import LWO: 'UV Map' must contain 2 value!"); bResult=false; break; } MESH->m_VMaps.push_back(new st_VMap(Ivmap->name,vmtUV,!!Ivmap->perpoly)); st_VMap* Mvmap=MESH->m_VMaps.back(); int vcnt=Ivmap->nverts; // VMap Mvmap->copyfrom(*Ivmap->val,vcnt); // flip uv for (int k=0; k<Mvmap->size(); k++){ Fvector2& uv = Mvmap->getUV(k); uv.y=1.f-uv.y; } // vmap index VMIndices[Ivmap] = vmap_count++; }break; case ID_WGHT:{ if (Ivmap->dim!=1){ ELog.DlgMsg(mtError, "Import LWO: 'Weight' must contain 1 value!"); bResult=false; break; } MESH->m_VMaps.push_back(new st_VMap(Ivmap->name,vmtWeight,false)); st_VMap* Mvmap=MESH->m_VMaps.back(); int vcnt=Ivmap->nverts; // VMap Mvmap->copyfrom(*Ivmap->val,vcnt); // vmap index VMIndices[Ivmap] = vmap_count++; }break; case ID_PICK: ELog.Msg(mtError,"Found 'PICK' VMAP. Import failed."); bResult = false; break; case ID_MNVW: ELog.Msg(mtError,"Found 'MNVW' VMAP. Import failed."); bResult = false; break; case ID_MORF: ELog.Msg(mtError,"Found 'MORF' VMAP. Import failed."); bResult = false; break; case ID_SPOT: ELog.Msg(mtError,"Found 'SPOT' VMAP. Import failed."); bResult = false; break; case ID_RGB: ELog.Msg(mtError,"Found 'RGB' VMAP. Import failed."); bResult = false; break; case ID_RGBA: ELog.Msg(mtError,"Found 'RGBA' VMAP. Import failed."); bResult = false; break; } if (!bResult) break; } if (!bResult) break; // points // UI->ProgressStart(Ilr->point.count,"Fill points:"); { MESH->m_VertCount = Ilr->point.count; MESH->m_Vertices = xr_alloc<Fvector>(MESH->m_VertCount); int id = Ilr->polygon.count/50; if (id==0) id = 1; for (int i=0; i<Ilr->point.count; ++i) { st_lwPoint& Ipt = Ilr->point.pt[i]; Fvector& Mpt = MESH->m_Vertices[i]; Mpt.set (Ipt.pos); } } if (!bResult) break; // polygons MESH->m_FaceCount = Ilr->polygon.count; MESH->m_Faces = xr_alloc<st_Face>(MESH->m_FaceCount); MESH->m_SmoothGroups = xr_alloc<u32>(MESH->m_FaceCount); Memory.mem_fill32 (MESH->m_SmoothGroups,u32(-1),MESH->m_FaceCount); MESH->m_VMRefs.reserve (Ilr->polygon.count*3); IntVec surf_ids; surf_ids.resize(Ilr->polygon.count); int id = Ilr->polygon.count/50; if (id==0) id = 1; for (int i=0; i<Ilr->polygon.count; ++i) { st_Face& Mpol=MESH->m_Faces[i]; st_lwPolygon& Ipol=Ilr->polygon.pol[i]; if (Ipol.nverts!=3) { ELog.DlgMsg(mtError, "Import LWO: Face must contain only 3 vertices!"); bResult=false; break; } for (int pv_i=0; pv_i<3; ++pv_i) { st_lwPolVert& Ipv=Ipol.v[pv_i]; st_FaceVert& Mpv=Mpol.pv[pv_i]; Mpv.pindex =Ipv.index; MESH->m_VMRefs.push_back(st_VMapPtLst()); st_VMapPtLst& m_vm_lst = MESH->m_VMRefs.back(); DEFINE_VECTOR (st_VMapPt,VMapPtVec,VMapPtIt); VMapPtVec vm_lst; Mpv.vmref = MESH->m_VMRefs.size()-1; // parse uv-map int vmpl_cnt =Ipv.nvmaps; st_lwPoint& Ipt =Ilr->point.pt[Mpv.pindex]; int vmpt_cnt =Ipt.nvmaps; if (!vmpl_cnt&&!vmpt_cnt){ ELog.DlgMsg (mtError,"Found mesh without UV's!",0); bResult = false; break; } AStringVec names; if (vmpl_cnt){ // берем из poly for (int vm_i=0; vm_i<vmpl_cnt; vm_i++){ if (Ipv.vm[vm_i].vmap->type!=ID_TXUV) continue; vm_lst.push_back(st_VMapPt()); st_VMapPt& pt = vm_lst.back(); pt.vmap_index = VMIndices[Ipv.vm[vm_i].vmap];// номер моей VMap names.push_back (Ipv.vm[vm_i].vmap->name); pt.index = Ipv.vm[vm_i].index; } } if (vmpt_cnt){ // берем из points for (int vm_i=0; vm_i<vmpt_cnt; vm_i++){ if (Ipt.vm[vm_i].vmap->type!=ID_TXUV) continue; if (std::find(names.begin(),names.end(),Ipt.vm[vm_i].vmap->name)!=names.end()) continue; vm_lst.push_back(st_VMapPt()); st_VMapPt& pt = vm_lst.back(); pt.vmap_index = VMIndices[Ipt.vm[vm_i].vmap]; // номер моей VMap pt.index = Ipt.vm[vm_i].index; } } std::sort(vm_lst.begin(),vm_lst.end(),CompareFunc); // parse weight-map int vm_cnt =Ipt.nvmaps; for (int vm_i=0; vm_i<vm_cnt; vm_i++){ if (Ipt.vm[vm_i].vmap->type!=ID_WGHT) continue; vm_lst.push_back(st_VMapPt()); st_VMapPt& pt = vm_lst.back(); pt.vmap_index = VMIndices[Ipt.vm[vm_i].vmap]; // номер моей VMap pt.index = Ipt.vm[vm_i].index; } m_vm_lst.count = vm_lst.size(); m_vm_lst.pts = xr_alloc<st_VMapPt>(m_vm_lst.count); Memory.mem_copy (m_vm_lst.pts,&*vm_lst.begin(),m_vm_lst.count*sizeof(st_VMapPt)); } if (!bResult) break; // Ipol.surf->alpha_mode - заполнено как номер моего surface surf_ids[i] = Ipol.surf->alpha_mode; } if (!bResult) break; for (u32 pl_id=0; pl_id<MESH->GetFCount(); pl_id++) MESH->m_SurfFaces[m_Surfaces[surf_ids[pl_id]]].push_back(pl_id); if (!bResult) break; k++; //MESH->DumpAdjacency(); if (bNeedOptimize) MESH->OptimizeMesh(false); //MESH->DumpAdjacency(); MESH->RebuildVMaps(); // !!!!!! } } } #ifdef _EDITOR LWO_CloseFile(I); #else lwFreeObject(I); #endif // UI->ProgressEnd(); // UI->SetStatus(""); if (bResult) VerifyMeshNames(); else ELog.DlgMsg(mtError,"Can't parse LWO object."); if (bResult) m_LoadName = (strext(fname))? strcpy(strext(fname),".object"):strcat(strext(fname),".object"); return bResult; }else ELog.DlgMsg(mtError,"Can't import LWO object file."); // UI->ProgressEnd(); // UI->SetStatus(""); return false; }