resourceselect.cpp 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493
  1. #include "resourceselect.h"
  2. #include "..\..\common_h\fileservice.h"
  3. #include "..\..\common_h\mission.h"
  4. #include "..\NodesPool.h"
  5. #define DEF_WIN_WIDTH 640
  6. #define DEF_WIN_HEIGHT 480
  7. extern string StartDirectory;
  8. extern IRender * pRS; // Рендер
  9. extern TreeNodesPool* globalNodesPool;
  10. string BrowserCurrentSelectedDir = "";
  11. IGMXService* GMXService = NULL;
  12. extern IMission* miss;
  13. TResourceSelectorWindow::TResourceSelectorWindow () : GUIWindow (null, 0, 0, DEF_WIN_WIDTH, DEF_WIN_HEIGHT),
  14. ExtInfo(_FL_),
  15. SubstratedPath(_FL_)
  16. {
  17. dwWinWidth = pRS->GetScreenInfo3D().dwWidth - 10;
  18. dwWinHeight = pRS->GetScreenInfo3D().dwHeight - 10;
  19. SetWidth(dwWinWidth);
  20. SetHeight(dwWinHeight);
  21. string PakPath;
  22. #ifndef NO_TOOLS
  23. miss->EditorGetPackPath(PakPath);
  24. #endif
  25. if (PakPath.Size() > 0)
  26. {
  27. if (PakPath[PakPath.Size()-1] == '\\') PakPath.Delete(PakPath.Size()-1, 1);
  28. for (dword n = PakPath.Size()-1; n >= 0; n--)
  29. {
  30. if (PakPath[n] == '\\')
  31. {
  32. PakPath.Delete(0, n+1);
  33. break;
  34. }
  35. }
  36. }
  37. //PakPath = string ("Resource\\Missions\\") + PakPath;
  38. IParticleService* pService = (IParticleService*)api->GetService("ParticleService");
  39. pParticleManager = pService->CreateManager(PakPath.GetBuffer());
  40. IAnimationService * as = (IAnimationService *)api->GetService("AnimationService");
  41. anims = as->CreateScene(_FL_);
  42. angle = 0.0f;
  43. bPopupStyle = true;
  44. previewname = "";
  45. GMXService = (IGMXService*)api->GetService ("GMXService");
  46. PreviewTexture = NULL;
  47. PreviewScene = NULL;
  48. PreviewSystem = NULL;
  49. ObjectName = "";
  50. Caption = "Resource browser";
  51. pFont->SetName("arialcyrsmall");
  52. bAlwaysOnTop = true;
  53. SetScreenCenter();
  54. TreeView1 = NEW GUITreeView (this, 10, 5, 250, dwWinHeight-45);
  55. TreeView1->FontColor = 0xFF000000;
  56. TreeView1->pFont->SetName("arialcyrsmall");
  57. TreeView1->SetImagesArray ("gtree");
  58. TreeView1->bDragAndDrop = false;
  59. TreeView1->OnChange = (CONTROL_EVENT)&TResourceSelectorWindow::OnSelectResource;
  60. TreeView1->OnDblClick = (CONTROL_EVENT)&TResourceSelectorWindow::OnOpenResource;
  61. t_OnSelect = NEW GUIEventHandler;
  62. Preview = NEW GUIPanel (this, 270, 5, dwWinWidth-280, dwWinHeight-45);
  63. Preview->OnBeforeDraw = (CONTROL_EVENT)&TResourceSelectorWindow::RenderPreview;
  64. btnOK = NEW GUIButton (this, 10, dwWinHeight-30, 100, 22);
  65. btnOK->pFont->SetName("arialcyrsmall");
  66. btnOK->Caption = "Ok";
  67. btnOK->Glyph->Load("ok");
  68. btnOK->OnMousePressed = (CONTROL_EVENT)&TResourceSelectorWindow::OnOpenResource;
  69. btnOK->FlatButton = true;
  70. btnCANCEL = NEW GUIButton (this, 120, dwWinHeight-30, 100, 22);
  71. btnCANCEL->pFont->SetName("arialcyrsmall");
  72. btnCANCEL->Caption = "Cancel";
  73. btnCANCEL->Glyph->Load("cancel");
  74. btnCANCEL->OnMousePressed = (CONTROL_EVENT)&TResourceSelectorWindow::Close;
  75. btnCANCEL->FlatButton = true;
  76. ReadExtInfo ();
  77. ScanForResources ();
  78. if (!BrowserCurrentSelectedDir.IsEmpty())
  79. {
  80. GUITreeNode* my_sel_node = TreeView1->FindItem(BrowserCurrentSelectedDir);
  81. if (my_sel_node)
  82. {
  83. ExpandAndGoToParent (my_sel_node);
  84. TreeView1->SetSelectedNode(my_sel_node);
  85. }
  86. }
  87. }
  88. void TResourceSelectorWindow::ExpandAndGoToParent (GUITreeNode* node)
  89. {
  90. node->Expanded = true;
  91. if (node->Parent) ExpandAndGoToParent (node->Parent);
  92. }
  93. TResourceSelectorWindow::~TResourceSelectorWindow ()
  94. {
  95. delete t_OnSelect;
  96. if (PreviewTexture)
  97. {
  98. PreviewTexture->Release();
  99. PreviewTexture = NULL;
  100. }
  101. if (PreviewScene)
  102. {
  103. PreviewScene->Release();
  104. PreviewScene = NULL;
  105. }
  106. if (PreviewSystem)
  107. {
  108. PreviewSystem->Release();
  109. PreviewSystem = NULL;
  110. }
  111. if (pParticleManager) pParticleManager->Release();
  112. pParticleManager = NULL;
  113. if(anims) anims->Release();
  114. anims = null;
  115. }
  116. bool TResourceSelectorWindow::FuncCompare (GUITreeNode* const &a1, GUITreeNode* const &a2)
  117. {
  118. if (a1->Tag > a2->Tag) return true;
  119. if (a1->Tag == a2->Tag)
  120. {
  121. if (crt_stricmp(a1->GetText(), a2->GetText()) < 0) return true;
  122. }
  123. return false;
  124. }
  125. void TResourceSelectorWindow::AddScanDir (const char* dirName)
  126. {
  127. GUITreeNode* NewNode = globalNodesPool->CreateNode();
  128. // NewNode->Text = ;
  129. NewNode->SetText(dirName);
  130. TreeView1->Items->Add(NewNode);
  131. NewNode->Tag = 1;
  132. NewNode->Image->Load("folder");
  133. string sDir = "resource\\";
  134. sDir += dirName;
  135. sDir += "\\";
  136. string croped;
  137. string filename;
  138. string name, path, ext;
  139. IFileService* fs = (IFileService*)api->GetService("FileService");
  140. Assert(fs);
  141. IFinder* finder = fs->CreateFinder(sDir.c_str(), "*.*", find_all_files_folder | find_no_files_from_packs, _FL_);
  142. Assert(finder);
  143. string resourcesFullPath;
  144. fs->BuildPath("resource\\", resourcesFullPath);
  145. for (dword n = 0; n < finder->Count(); n++)
  146. {
  147. filename = string(finder->FilePath(n)).GetRelativePath (resourcesFullPath);
  148. path.GetFilePath(filename);
  149. ext.GetFileExt(filename);
  150. name.GetFileName(filename);
  151. croped = filename;
  152. for (dword i = 0; i < croped.Size(); i++)
  153. {
  154. if (croped[i] == '\\')
  155. {
  156. croped.Delete (i, croped.Size()-i);
  157. break;
  158. }
  159. }
  160. GUITreeNodes* nodestoadd = TreeView1->Items;
  161. //if (crt_stricmp (croped.GetBuffer(), "missions") == 0) continue;
  162. if (!path.IsEmpty())
  163. {
  164. path.Delete(path.Size()-1, 1);
  165. GUITreeNode* node = TreeView1->FindItem(path.GetBuffer());
  166. Assert (node != NULL);
  167. nodestoadd = &node->Childs;
  168. }
  169. GUITreeNode* already_exist_node = TreeView1->FindItem(filename);
  170. if (already_exist_node) continue;
  171. GUITreeNode* NewNode = globalNodesPool->CreateNode();
  172. NewNode->SetText(name);
  173. //NewNode->Text = ;
  174. nodestoadd->Add(NewNode);
  175. if (finder->IsMirror(n) && !finder->IsFolder(n))
  176. {
  177. NewNode->bUseCustomColor = true;
  178. NewNode->Color = 0xFF0000FF;
  179. }
  180. if (finder->IsFolder(n))
  181. {
  182. NewNode->Tag = 1;
  183. NewNode->Image->Load("folder");
  184. } else
  185. {
  186. if (!ext.IsEmpty())
  187. {
  188. ExtensionInfo* info = GetExtInfo (ext);
  189. if (info)
  190. {
  191. NewNode->Image->Load(info->image);
  192. } else
  193. {
  194. NewNode->Image->Load("icon");
  195. }
  196. }
  197. NewNode->Tag = 0;
  198. }
  199. }
  200. finder->Release();
  201. }
  202. void TResourceSelectorWindow::ScanForResources ()
  203. {
  204. AddScanDir("Animation");
  205. AddScanDir("Models");
  206. AddScanDir("Particles");
  207. AddScanDir("Textures");
  208. AddScanDir("Cameras");
  209. AddScanDir("Videos");
  210. TreeView1->Sort(FuncCompare);
  211. }
  212. void TResourceSelectorWindow::ReadExtInfo ()
  213. {
  214. static char TempSection[64];
  215. IFileService * fs = (IFileService *)api->GetService("FileService");
  216. IIniFile * EngineIni = fs->SystemIni();
  217. for (int n = 0; n < 100; n++)
  218. {
  219. crt_snprintf (TempSection, 64, "Ext %02d", n);
  220. const char * tmpExt = EngineIni->GetString("mission_editor", TempSection, null);
  221. if (!tmpExt) break;
  222. crt_snprintf (TempSection, 64, "Img %02d", n);
  223. const char * tmpIcon = EngineIni->GetString("mission_editor", TempSection, "icon");
  224. ExtensionInfo NewExt;
  225. NewExt.ext = tmpExt;
  226. NewExt.image = tmpIcon;
  227. ExtInfo.Add(NewExt);
  228. }
  229. for (n = 0; n < 100; n++)
  230. {
  231. crt_snprintf (TempSection, 64, "SubPath %02d", n);
  232. const char * _spath = EngineIni->GetString("substracted_path", TempSection, null);
  233. if (!_spath) break;
  234. string spath = _spath;
  235. spath.Lower();
  236. if (spath[spath.Size() - 1] != '\\') spath += "\\";
  237. SubstratedPath.Add(spath);
  238. }
  239. EngineIni->Release(); EngineIni = null;
  240. }
  241. TResourceSelectorWindow::ExtensionInfo* TResourceSelectorWindow::GetExtInfo (const char* ext)
  242. {
  243. for (int n = 0; n < ExtInfo; n++)
  244. {
  245. if (ExtInfo[n].ext == ext) return &ExtInfo[n];
  246. }
  247. return NULL;
  248. }
  249. void _cdecl TResourceSelectorWindow::OnSelectResource (GUIControl* sender)
  250. {
  251. GUITreeNode* sNode = TreeView1->GetSelectedNode();
  252. if (!sNode) return;
  253. ObjectName = sNode->GetFullPath();
  254. if (sNode->Tag == 0)
  255. {
  256. if (ObjectName[ObjectName.Size() - 1] == '\\') ObjectName.Delete(ObjectName.Size() - 1, 1);
  257. }
  258. SubstractPath (ObjectName);
  259. BeginPreview ();
  260. }
  261. void TResourceSelectorWindow::SubstractPath (string& fullname)
  262. {
  263. fullname.Lower();
  264. for (int n = 0; n < SubstratedPath; n++)
  265. {
  266. long res = fullname.FindSubStr(SubstratedPath[n]);
  267. if (res == 0)
  268. {
  269. fullname.Delete(0, SubstratedPath[n].Size());
  270. }
  271. }
  272. }
  273. void _cdecl TResourceSelectorWindow::OnOpenResource (GUIControl* sender)
  274. {
  275. GUITreeNode* sNode = TreeView1->GetSelectedNode();
  276. if (!sNode) return;
  277. BrowserCurrentSelectedDir = sNode->GetFullPath();
  278. t_OnSelect->Execute(this);
  279. Close (this);
  280. }
  281. void TResourceSelectorWindow::BeginPreview ()
  282. {
  283. angle = 0.0f;
  284. if (previewname == ObjectName) return;
  285. previewname = ObjectName;
  286. if (PreviewTexture)
  287. {
  288. PreviewTexture->Release();
  289. PreviewTexture = NULL;
  290. }
  291. if (PreviewScene)
  292. {
  293. PreviewScene->Release();
  294. PreviewScene = NULL;
  295. }
  296. if (PreviewSystem)
  297. {
  298. PreviewSystem->Release();
  299. PreviewSystem = NULL;
  300. }
  301. string ext;
  302. ext.GetFileExt(ObjectName);
  303. if (ext == "gmx")
  304. {
  305. PreviewScene = GMXService->CreateGMX(ObjectName, anims, pParticleManager, NULL);
  306. }
  307. if (ext == "txx")
  308. {
  309. PreviewTexture = pRS->CreateTexture(_FL_, ObjectName);
  310. }
  311. if (ext == "xps")
  312. {
  313. string sParticleName;;
  314. sParticleName.GetFileName(ObjectName);
  315. PreviewSystem = pParticleManager->CreateParticleSystemEx(sParticleName.c_str(), _FL_);
  316. //if (!PreviewSystem) api->Trace("Can't preview psys '%s'", ObjectName.GetBuffer());
  317. }
  318. }
  319. void _cdecl TResourceSelectorWindow::RenderPreview (GUIControl* sender)
  320. {
  321. if ((!PreviewScene) && (!PreviewTexture) && (!PreviewSystem)) return;
  322. angle += 1.6f * api->GetDeltaTime();
  323. cliper.Push();
  324. RENDERVIEWPORT saved_vp = pRS->GetViewport();
  325. GUIRectangle rect = Preview->GetScreenRect();
  326. RENDERVIEWPORT ViewPort;
  327. ViewPort.X = rect.x;
  328. ViewPort.Y = rect.y;
  329. ViewPort.Width = rect.w;
  330. ViewPort.Height = rect.h;
  331. ViewPort.MinZ = 0.0f;
  332. ViewPort.MaxZ = 1.0f;
  333. pRS->SetViewport(ViewPort);
  334. pRS->SetPerspective(1.0f, (float)ViewPort.Width, (float)ViewPort.Height);
  335. pRS->Clear(0, NULL, CLEAR_STENCIL | CLEAR_TARGET |CLEAR_ZBUFFER, 0xFF878787, 1.0f, 0);
  336. if (PreviewScene)
  337. {
  338. Vector center = PreviewScene->GetBoundSphere().vCenter;
  339. float rad = PreviewScene->GetBoundSphere().fRadius;
  340. float camposx = sin(angle) * rad * 1.5f;
  341. float camposz = cos(angle) * rad * 1.5f;
  342. pRS->SetCamera(center-Vector (camposx, -rad, camposz), center, Vector (0.0f, 1.0f, 0.0f));
  343. PreviewScene->Draw();
  344. }
  345. if (PreviewTexture)
  346. {
  347. pRS->Clear(0, NULL, CLEAR_STENCIL | CLEAR_TARGET |CLEAR_ZBUFFER, 0x00000030, 1.0f, 0);
  348. pRS->SetCamera(Vector (2.0f, 0.0f, 0.0f), Vector (0.0f), Vector (0.0f, 1.0f, 0.0f));
  349. RS_RECT Rect;
  350. Rect.vPos = Vector (0.0f);
  351. Rect.fSizeX = 1.0f;
  352. Rect.fSizeY = 1.0f;
  353. Rect.fAngle = 0.0f;
  354. Rect.dwColor = 0xFFFFFFFF;
  355. Rect.dwSubTexture = 0;
  356. pRS->DrawRects(PreviewTexture,&Rect, 1);
  357. }
  358. if (PreviewSystem)
  359. {
  360. pRS->SetCamera(Vector (15.0f, 2.0f, 15.0f), Vector (0.0f), Vector (0.0f, 1.0f, 0.0f));
  361. PreviewSystem->SetTransform(Matrix());
  362. pParticleManager->Execute(api->GetDeltaTime());
  363. pRS->SetWorld(Matrix());
  364. pParticleManager->Execute(api->GetDeltaTime());
  365. pParticleManager->DrawAllParticles();
  366. //pRS->DrawSphere(Vector(0.0f), 1.0f);
  367. }
  368. pRS->SetViewport(saved_vp);
  369. cliper.Pop();
  370. }