DataTreeView.cpp 43 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517
  1. /*
  2. ** Command & Conquer Renegade(tm)
  3. ** Copyright 2025 Electronic Arts Inc.
  4. **
  5. ** This program is free software: you can redistribute it and/or modify
  6. ** it under the terms of the GNU General Public License as published by
  7. ** the Free Software Foundation, either version 3 of the License, or
  8. ** (at your option) any later version.
  9. **
  10. ** This program is distributed in the hope that it will be useful,
  11. ** but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  13. ** GNU General Public License for more details.
  14. **
  15. ** You should have received a copy of the GNU General Public License
  16. ** along with this program. If not, see <http://www.gnu.org/licenses/>.
  17. */
  18. /***********************************************************************************************
  19. *** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S ***
  20. ***********************************************************************************************
  21. * *
  22. * Project Name : W3DView *
  23. * *
  24. * $Archive:: /Commando/Code/Tools/W3DView/DataTreeView.cpp $*
  25. * *
  26. * Author:: Patrick Smith *
  27. * *
  28. * $Modtime:: 6/18/01 9:11a $*
  29. * *
  30. * $Revision:: 35 $*
  31. * *
  32. *---------------------------------------------------------------------------------------------*
  33. * Functions: *
  34. * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
  35. #include "StdAfx.H"
  36. #include "W3DView.H"
  37. #include "DataTreeView.H"
  38. #include "RendObj.H"
  39. #include "ViewerAssetMgr.H"
  40. #include "Globals.h"
  41. #include "W3DViewDoc.H"
  42. #include "MainFrm.H"
  43. #include "DistLod.H"
  44. #include "AnimObj.H"
  45. #include "HcAnim.H"
  46. #include "AssetInfo.H"
  47. #include "Utils.H"
  48. #include "Vector.H"
  49. #include "Part_Emt.H"
  50. #include "Agg_Def.H"
  51. #include "BMP2D.H"
  52. #include "HLod.H"
  53. #include "ViewerScene.h"
  54. #include "texture.h"
  55. #ifdef _DEBUG
  56. #define new DEBUG_NEW
  57. #undef THIS_FILE
  58. static char THIS_FILE[] = __FILE__;
  59. #endif
  60. ////////////////////////////////////////////////////////////////////////////
  61. // Local Prototypes
  62. ////////////////////////////////////////////////////////////////////////////
  63. void Set_Highest_LOD (RenderObjClass *render_obj);
  64. ////////////////////////////////////////////////////////////////////////////
  65. // MFC Stuff
  66. ////////////////////////////////////////////////////////////////////////////
  67. IMPLEMENT_DYNCREATE(CDataTreeView, CTreeView)
  68. ////////////////////////////////////////////////////////////////////////////
  69. //
  70. // CDataTreeView
  71. //
  72. ////////////////////////////////////////////////////////////////////////////
  73. CDataTreeView::CDataTreeView (void)
  74. : m_hMaterialsRoot (NULL),
  75. m_hMeshRoot (NULL),
  76. m_hMeshCollectionRoot (NULL),
  77. m_hAggregateRoot (NULL),
  78. m_hPrimitivesRoot (NULL),
  79. m_hEmitterRoot (NULL),
  80. m_hLODRoot (NULL),
  81. m_hSoundRoot (NULL),
  82. m_iPrimitivesIcon (-1),
  83. m_iAnimationIcon (-1),
  84. m_iTCAnimationIcon(-1),
  85. m_iADAnimationIcon(-1),
  86. m_iMeshIcon (-1),
  87. m_iMaterialIcon (-1),
  88. m_iLODIcon (-1),
  89. m_iAggregateIcon (-1),
  90. m_iEmitterIcon (-1),
  91. m_iSoundIcon (-1),
  92. m_RestrictAnims (true)
  93. {
  94. return ;
  95. }
  96. ////////////////////////////////////////////////////////////////////////////
  97. //
  98. // ~CDataTreeView
  99. //
  100. CDataTreeView::~CDataTreeView (void)
  101. {
  102. return ;
  103. }
  104. BEGIN_MESSAGE_MAP(CDataTreeView, CTreeView)
  105. //{{AFX_MSG_MAP(CDataTreeView)
  106. ON_WM_CREATE()
  107. ON_NOTIFY_REFLECT(TVN_SELCHANGED, OnSelChanged)
  108. ON_NOTIFY_REFLECT(TVN_DELETEITEM, OnDeleteItem)
  109. ON_NOTIFY_REFLECT(NM_DBLCLK, OnDblclk)
  110. //}}AFX_MSG_MAP
  111. END_MESSAGE_MAP()
  112. ////////////////////////////////////////////////////////////////////////////
  113. //
  114. // OnDraw
  115. //
  116. void
  117. CDataTreeView::OnDraw (CDC *pDC)
  118. {
  119. return ;
  120. }
  121. /////////////////////////////////////////////////////////////////////////////
  122. // CDataTreeView diagnostics
  123. #ifdef _DEBUG
  124. void CDataTreeView::AssertValid() const
  125. {
  126. CTreeView::AssertValid();
  127. }
  128. void CDataTreeView::Dump(CDumpContext& dc) const
  129. {
  130. CTreeView::Dump(dc);
  131. }
  132. #endif //_DEBUG
  133. /////////////////////////////////////////////////////////////////////////////
  134. // CDataTreeView message handlers
  135. ////////////////////////////////////////////////////////////////////////////
  136. //
  137. // PreCreateWindow
  138. //
  139. BOOL
  140. CDataTreeView::PreCreateWindow (CREATESTRUCT& cs)
  141. {
  142. // Modify the style bits for the window so it will
  143. // have buttons and lines between nodes.
  144. cs.style |= TVS_HASBUTTONS | TVS_HASLINES | TVS_LINESATROOT | TVS_SHOWSELALWAYS;
  145. // Allow the base class to process this message
  146. return CTreeView::PreCreateWindow(cs);
  147. }
  148. ////////////////////////////////////////////////////////////////////////////
  149. //
  150. // OnInitialUpdate
  151. //
  152. void
  153. CDataTreeView::OnInitialUpdate (void)
  154. {
  155. // Allow the base class to process this message
  156. CTreeView::OnInitialUpdate ();
  157. // TODO: Add your specialized code here and/or call the base class
  158. return ;
  159. }
  160. ////////////////////////////////////////////////////////////////////////////
  161. //
  162. // CreateRootNodes
  163. //
  164. void
  165. CDataTreeView::CreateRootNodes (void)
  166. {
  167. // Insert all the root nodes
  168. m_hMaterialsRoot = GetTreeCtrl ().InsertItem ("Materials", m_iMaterialIcon, m_iMaterialIcon);
  169. m_hMeshRoot = GetTreeCtrl ().InsertItem ("Mesh", m_iMeshIcon, m_iMeshIcon);
  170. m_hHierarchyRoot = GetTreeCtrl ().InsertItem ("Hierarchy", m_iHierarchyIcon, m_iHierarchyIcon);
  171. m_hLODRoot = GetTreeCtrl ().InsertItem ("H-LOD", m_iLODIcon, m_iLODIcon);
  172. m_hMeshCollectionRoot = GetTreeCtrl ().InsertItem ("Mesh Collection", m_iMeshIcon, m_iMeshIcon);
  173. m_hAggregateRoot = GetTreeCtrl ().InsertItem ("Aggregate", m_iAggregateIcon, m_iAggregateIcon);
  174. m_hEmitterRoot = GetTreeCtrl ().InsertItem ("Emitter", m_iEmitterIcon, m_iEmitterIcon);
  175. m_hPrimitivesRoot = GetTreeCtrl ().InsertItem ("Primitives", m_iPrimitivesIcon, m_iPrimitivesIcon);
  176. m_hSoundRoot = GetTreeCtrl ().InsertItem ("Sounds", m_iSoundIcon, m_iSoundIcon);
  177. return ;
  178. }
  179. ////////////////////////////////////////////////////////////////////////////
  180. //
  181. // OnCreate
  182. //
  183. int
  184. CDataTreeView::OnCreate (LPCREATESTRUCT lpCreateStruct)
  185. {
  186. if (CTreeView::OnCreate(lpCreateStruct) == -1)
  187. return -1;
  188. CImageList imageList;
  189. imageList.Create (16, 18, ILC_COLOR | ILC_MASK, 5, 10);
  190. // Add the icons to the imagelist
  191. m_iAnimationIcon = imageList.Add (::LoadIcon (::AfxGetResourceHandle (), MAKEINTRESOURCE (IDI_ANIMATION)));
  192. m_iTCAnimationIcon = imageList.Add (::LoadIcon (::AfxGetResourceHandle (), MAKEINTRESOURCE (IDI_ANIMATION_COMPRESSED)));
  193. m_iADAnimationIcon = imageList.Add (::LoadIcon (::AfxGetResourceHandle (), MAKEINTRESOURCE (IDI_ANIMATION_COMPRESSED_DELTA)));
  194. m_iMeshIcon = imageList.Add (::LoadIcon (::AfxGetResourceHandle (), MAKEINTRESOURCE (IDI_MESH)));
  195. m_iMaterialIcon = imageList.Add (::LoadIcon (::AfxGetResourceHandle (), MAKEINTRESOURCE (IDI_MATERIAL)));
  196. m_iLODIcon = imageList.Add (::LoadIcon (::AfxGetResourceHandle (), MAKEINTRESOURCE (IDI_LOD)));
  197. m_iAggregateIcon = imageList.Add (::LoadIcon (::AfxGetResourceHandle (), MAKEINTRESOURCE (IDI_HIERARCHY)));
  198. m_iEmitterIcon = imageList.Add (::LoadIcon (::AfxGetResourceHandle (), MAKEINTRESOURCE (IDI_HIERARCHY)));
  199. m_iHierarchyIcon = imageList.Add (::LoadIcon (::AfxGetResourceHandle (), MAKEINTRESOURCE (IDI_HIERARCHY)));
  200. m_iPrimitivesIcon = imageList.Add (::LoadIcon (::AfxGetResourceHandle (), MAKEINTRESOURCE (IDI_PRIMITIVES)));
  201. m_iSoundIcon = imageList.Add (::LoadIcon (::AfxGetResourceHandle (), MAKEINTRESOURCE (IDI_SOUND)));
  202. // Pass the imagelist onto the tree control
  203. GetTreeCtrl ().SetImageList (&imageList, TVSIL_NORMAL);
  204. imageList.Detach ();
  205. // Create the root nodes that will hold the contain
  206. // asset types.
  207. CreateRootNodes ();
  208. return 0;
  209. }
  210. ////////////////////////////////////////////////////////////////////////////
  211. //
  212. // Load_Materials_Into_Tree
  213. //
  214. void
  215. CDataTreeView::Load_Materials_Into_Tree (void)
  216. {
  217. // Get an iterator from the asset manager that we can
  218. // use to enumerate the currently loaded textures
  219. HashTemplateIterator<StringClass,TextureClass*> ite(WW3DAssetManager::Get_Instance()->Texture_Hash());
  220. // Loop through all the textures in the manager
  221. for (ite.First ();
  222. !ite.Is_Done ();
  223. ite.Next ()) {
  224. // Get the current texture name
  225. TextureClass* ptexture=ite.Peek_Value();
  226. LPCTSTR texture_name = ptexture->Get_Texture_Name();
  227. if ((ptexture != NULL) &&
  228. FindChildItem (m_hMaterialsRoot, texture_name) == NULL) {
  229. // Add this entry to the tree
  230. HTREEITEM tree_item = GetTreeCtrl ().InsertItem (texture_name, m_iMaterialIcon, m_iMaterialIcon, m_hMaterialsRoot, TVI_SORT);
  231. ASSERT (tree_item != NULL);
  232. // Allocate a new asset information class to associate with this entry
  233. ptexture->Add_Ref ();
  234. AssetInfoClass *asset_info = new AssetInfoClass (texture_name, TypeMaterial, NULL, (DWORD)ptexture);
  235. GetTreeCtrl ().SetItemData (tree_item, (ULONG)asset_info);
  236. }
  237. }
  238. return ;
  239. }
  240. ////////////////////////////////////////////////////////////////////////////
  241. //
  242. // LoadAssetsIntoTree
  243. //
  244. void
  245. CDataTreeView::LoadAssetsIntoTree (void)
  246. {
  247. // Turn off repainting
  248. GetTreeCtrl ().SetRedraw (FALSE);
  249. DynamicVectorClass<CString> dist_lod_list;
  250. // Get an iterator from the asset manager that we can
  251. // use to enumerate the currently loaded assets
  252. RenderObjIterator *pObjEnum = WW3DAssetManager::Get_Instance()->Create_Render_Obj_Iterator ();
  253. ASSERT (pObjEnum);
  254. if (pObjEnum) {
  255. // Loop through all the assets in the manager
  256. for (pObjEnum->First ();
  257. pObjEnum->Is_Done () == FALSE;
  258. pObjEnum->Next ()) {
  259. // Does this render obj really exist?
  260. LPCTSTR pszItemName = pObjEnum->Current_Item_Name ();
  261. if (WW3DAssetManager::Get_Instance()->Render_Obj_Exists (pszItemName)) {
  262. BOOL bInsert = FALSE;
  263. HTREEITEM hParentNode = NULL;
  264. ASSET_TYPE assetType = TypeUnknown;
  265. int iIconIndex = -1;
  266. // What type of asset is this?
  267. switch (pObjEnum->Current_Item_Class_ID ()) {
  268. case RenderObjClass::CLASSID_COLLECTION:
  269. // This is a 'mesh collection', we want to add this under the 'collection' node.
  270. bInsert = TRUE;
  271. hParentNode = m_hMeshCollectionRoot;
  272. assetType = TypeMesh;
  273. iIconIndex = m_iMeshIcon;
  274. break;
  275. //
  276. // This is a mesh render object, we want to add this under the mesh node.
  277. //
  278. case RenderObjClass::CLASSID_MESH:
  279. bInsert = TRUE;
  280. hParentNode = m_hMeshRoot;
  281. assetType = TypeMesh;
  282. iIconIndex = m_iMeshIcon;
  283. break;
  284. //
  285. // This is a sound render obj, we want to add this under the sound node.
  286. //
  287. case RenderObjClass::CLASSID_SOUND:
  288. bInsert = TRUE;
  289. hParentNode = m_hSoundRoot;
  290. assetType = TypeSound;
  291. iIconIndex = m_iSoundIcon;
  292. break;
  293. case RenderObjClass::CLASSID_HMODEL:
  294. // Shouldn't happen
  295. ASSERT (0);
  296. break;
  297. case RenderObjClass::CLASSID_PARTICLEEMITTER:
  298. // This is an 'emitter', we want to add this under the 'emitter' node.
  299. bInsert = TRUE;
  300. hParentNode = m_hEmitterRoot;
  301. assetType = TypeEmitter;
  302. iIconIndex = m_iEmitterIcon;
  303. break;
  304. case RenderObjClass::CLASSID_SPHERE:
  305. case RenderObjClass::CLASSID_RING:
  306. bInsert = TRUE;
  307. hParentNode = m_hPrimitivesRoot;
  308. assetType = TypePrimitives;
  309. iIconIndex = m_iPrimitivesIcon;
  310. break;
  311. case RenderObjClass::CLASSID_DISTLOD:
  312. dist_lod_list.Add (pszItemName);
  313. case RenderObjClass::CLASSID_HLOD:
  314. // Assume this is a simple hierarchy LOD, we want to add this under the hierarchy node.
  315. bInsert = TRUE;
  316. hParentNode = m_hHierarchyRoot;
  317. assetType = TypeHierarchy;
  318. iIconIndex = m_iHierarchyIcon;
  319. // Test this HLOD to see if its a true LOD or a simple hierarchy
  320. if (::Is_Real_LOD (pszItemName)) {
  321. hParentNode = m_hLODRoot;
  322. assetType = TypeLOD;
  323. iIconIndex = m_iLODIcon;
  324. }
  325. break;
  326. }
  327. if (bInsert) {
  328. // Check to see if this object is an aggregate
  329. if (::Is_Aggregate (pszItemName)) {
  330. hParentNode = m_hAggregateRoot;
  331. assetType = TypeAggregate;
  332. iIconIndex = m_iAggregateIcon;
  333. }
  334. // If this object isn't already in the tree then add it
  335. if (FindChildItem (hParentNode, pszItemName) == NULL) {
  336. // Add this entry to the tree
  337. HTREEITEM hItem = GetTreeCtrl ().InsertItem (pszItemName, iIconIndex, iIconIndex, hParentNode, TVI_SORT);
  338. ASSERT (hItem != NULL);
  339. // Allocate a new asset information class to associate with this entry
  340. AssetInfoClass *asset_info = new AssetInfoClass (pszItemName, assetType);
  341. GetTreeCtrl ().SetItemData (hItem, (ULONG)asset_info);
  342. }
  343. }
  344. }
  345. }
  346. // Free the enumerator object we created earlier
  347. SAFE_DELETE (pObjEnum);
  348. }
  349. // Loop through all the old-style dist lod's and convert their prototypes
  350. // to the new HLOD format
  351. for (int index = 0; index < dist_lod_list.Count (); index ++) {
  352. HLodClass *plod = (HLodClass *)WW3DAssetManager::Get_Instance ()->Create_Render_Obj (dist_lod_list[index]);
  353. if (plod != NULL) {
  354. HLodDefClass *definition = new HLodDefClass (*plod);
  355. HLodPrototypeClass *prototype = new HLodPrototypeClass (definition);
  356. WW3DAssetManager::Get_Instance ()->Remove_Prototype (dist_lod_list[index]);
  357. WW3DAssetManager::Get_Instance ()->Add_Prototype (prototype);
  358. }
  359. }
  360. // Now that we've added all the hierarchies to the tree, add their animations
  361. // as well.
  362. LoadAnimationsIntoTree ();
  363. Load_Materials_Into_Tree ();
  364. // Turn;repainting back on
  365. GetTreeCtrl ().SetRedraw (TRUE);
  366. // Force the window to be repainted
  367. Invalidate (FALSE);
  368. UpdateWindow ();
  369. return ;
  370. }
  371. ////////////////////////////////////////////////////////////////////////////
  372. //
  373. // LoadAnimationsIntoTree
  374. //
  375. void
  376. CDataTreeView::LoadAnimationsIntoTree (void)
  377. {
  378. // Get an iterator from the asset manager that we can
  379. // use to enumerate the currently loaded assets
  380. AssetIterator *pAnimEnum = WW3DAssetManager::Get_Instance()->Create_HAnim_Iterator ();
  381. ASSERT (pAnimEnum);
  382. if (pAnimEnum)
  383. {
  384. // Loop through all the animations in the manager
  385. for (pAnimEnum->First ();
  386. (pAnimEnum->Is_Done () == FALSE);
  387. pAnimEnum->Next ())
  388. {
  389. LPCTSTR pszAnimName = pAnimEnum->Current_Item_Name ();
  390. // Get an instance of the animation object
  391. HAnimClass *pHierarchyAnim = WW3DAssetManager::Get_Instance()->Get_HAnim (pszAnimName);
  392. ASSERT (pHierarchyAnim);
  393. if (pHierarchyAnim)
  394. {
  395. // Get the name of the hierarchy that this animation belongs to
  396. LPCTSTR pszHierarchyName = pHierarchyAnim->Get_HName ();
  397. // Loop through all the hierarchies and add this animation to any pertinent ones
  398. for (HTREEITEM hNode = FindFirstChildItemBasedOnHierarchyName (m_hHierarchyRoot, pszHierarchyName);
  399. (hNode != NULL);
  400. hNode = FindSiblingItemBasedOnHierarchyName (hNode, pszHierarchyName))
  401. {
  402. // Is this animation already loaded into the tree?
  403. HTREEITEM hAnimationNode = FindChildItem (hNode, pszAnimName);
  404. if (hAnimationNode == NULL)
  405. {
  406. // Add this animation as a child of the hierarchy
  407. hAnimationNode = GetTreeCtrl ().InsertItem (pszAnimName, m_iAnimationIcon, m_iAnimationIcon, hNode, TVI_SORT);
  408. ASSERT (hAnimationNode != NULL);
  409. // Associate the items name with its entry
  410. GetTreeCtrl ().SetItemData (hAnimationNode, (ULONG)new AssetInfoClass (pszAnimName, TypeAnimation));
  411. }
  412. }
  413. // Loop through all the aggregates and add this animation to any pertinent ones
  414. for (hNode = FindFirstChildItemBasedOnHierarchyName (m_hAggregateRoot, pszHierarchyName);
  415. (hNode != NULL);
  416. hNode = FindSiblingItemBasedOnHierarchyName (hNode, pszHierarchyName))
  417. {
  418. // Is this animation already loaded into the tree?
  419. HTREEITEM hAnimationNode = FindChildItem (hNode, pszAnimName);
  420. if (hAnimationNode == NULL)
  421. {
  422. // Add this animation as a child of the hierarchy
  423. hAnimationNode = GetTreeCtrl ().InsertItem (pszAnimName, m_iAnimationIcon, m_iAnimationIcon, hNode, TVI_SORT);
  424. ASSERT (hAnimationNode != NULL);
  425. // Associate the items name with its entry
  426. GetTreeCtrl ().SetItemData (hAnimationNode, (ULONG)new AssetInfoClass (pszAnimName, TypeAnimation));
  427. }
  428. }
  429. // Loop through all the hierarchies and add this animation to any pertinent ones
  430. for (hNode = FindFirstChildItemBasedOnHierarchyName (m_hLODRoot, pszHierarchyName);
  431. (hNode != NULL);
  432. hNode = FindSiblingItemBasedOnHierarchyName (hNode, pszHierarchyName))
  433. {
  434. // Is this animation already loaded into the tree?
  435. HTREEITEM hAnimationNode = FindChildItem (hNode, pszAnimName);
  436. if (hAnimationNode == NULL)
  437. {
  438. // Add this animation as a child of the hierarchy
  439. hAnimationNode = GetTreeCtrl ().InsertItem (pszAnimName, m_iAnimationIcon, m_iAnimationIcon, hNode, TVI_SORT);
  440. ASSERT (hAnimationNode != NULL);
  441. // Associate the items name with its entry
  442. GetTreeCtrl ().SetItemData (hAnimationNode, (ULONG)new AssetInfoClass (pszAnimName, TypeAnimation));
  443. }
  444. }
  445. // Release our hold on this animation...
  446. MEMBER_RELEASE (pHierarchyAnim);
  447. }
  448. }
  449. // Free the object
  450. delete pAnimEnum;
  451. pAnimEnum = NULL;
  452. }
  453. return ;
  454. }
  455. ////////////////////////////////////////////////////////////////////////////
  456. //
  457. // LoadAnimationsIntoTree
  458. //
  459. void
  460. CDataTreeView::LoadAnimationsIntoTree (HTREEITEM hItem)
  461. {
  462. // Get the data associated with this item
  463. AssetInfoClass *asset_info = (AssetInfoClass *)GetTreeCtrl ().GetItemData (hItem);
  464. ASSERT (asset_info != NULL);
  465. // Get an iterator from the asset manager that we can
  466. // use to enumerate the currently loaded assets
  467. AssetIterator *pAnimEnum = WW3DAssetManager::Get_Instance()->Create_HAnim_Iterator ();
  468. ASSERT (pAnimEnum);
  469. if (pAnimEnum)
  470. {
  471. // Loop through all the animations in the manager
  472. for (pAnimEnum->First ();
  473. (pAnimEnum->Is_Done () == FALSE);
  474. pAnimEnum->Next ())
  475. {
  476. LPCTSTR pszAnimName = pAnimEnum->Current_Item_Name ();
  477. // Get an instance of the animation object
  478. HAnimClass *pHierarchyAnim = WW3DAssetManager::Get_Instance()->Get_HAnim (pszAnimName);
  479. ASSERT (pHierarchyAnim);
  480. if (pHierarchyAnim)
  481. {
  482. // Get the name of the hierarchy that this animation belongs to
  483. LPCTSTR pszHierarchyName = pHierarchyAnim->Get_HName ();
  484. // Does the item match the hierarchy name?
  485. if (::lstrcmp (asset_info->Get_Hierarchy_Name (), pszHierarchyName) == 0)
  486. {
  487. // Is this animation already loaded into the tree?
  488. HTREEITEM hAnimationNode = FindChildItem (hItem, pszAnimName);
  489. if (hAnimationNode == NULL)
  490. {
  491. // Add this animation as a child of the hierarchy
  492. hAnimationNode = GetTreeCtrl ().InsertItem (pszAnimName, m_iAnimationIcon, m_iAnimationIcon, hItem, TVI_SORT);
  493. ASSERT (hAnimationNode != NULL);
  494. // Associate the items name with its entry
  495. GetTreeCtrl ().SetItemData (hAnimationNode, (ULONG)new AssetInfoClass (pszAnimName, TypeAnimation));
  496. }
  497. }
  498. // Release our hold on the animation object
  499. MEMBER_RELEASE (pHierarchyAnim);
  500. }
  501. }
  502. // Free the object
  503. delete pAnimEnum;
  504. pAnimEnum = NULL;
  505. }
  506. return ;
  507. }
  508. ////////////////////////////////////////////////////////////////////////////
  509. //
  510. // Determine_Tree_Location
  511. //
  512. ASSET_TYPE
  513. CDataTreeView::Determine_Tree_Location
  514. (
  515. RenderObjClass &render_obj,
  516. HTREEITEM &hroot,
  517. int &icon_index
  518. )
  519. {
  520. ASSET_TYPE type = TypeUnknown;
  521. // What class does this render object belong to?
  522. switch (render_obj.Class_ID ()) {
  523. case RenderObjClass::CLASSID_COLLECTION:
  524. hroot = m_hMeshCollectionRoot;
  525. type = TypeMesh;
  526. icon_index = m_iMeshIcon;
  527. break;
  528. case RenderObjClass::CLASSID_MESH:
  529. hroot = m_hMeshRoot;
  530. type = TypeMesh;
  531. icon_index = m_iMeshIcon;
  532. break;
  533. case RenderObjClass::CLASSID_SOUND:
  534. hroot = m_hSoundRoot;
  535. type = TypeSound;
  536. icon_index = m_iSoundIcon;
  537. break;
  538. case RenderObjClass::CLASSID_HMODEL:
  539. // Shouldn't happen
  540. ASSERT (0);
  541. break;
  542. case RenderObjClass::CLASSID_PARTICLEEMITTER:
  543. hroot = m_hEmitterRoot;
  544. type = TypeEmitter;
  545. icon_index = m_iEmitterIcon;
  546. break;
  547. case RenderObjClass::CLASSID_SPHERE:
  548. case RenderObjClass::CLASSID_RING:
  549. hroot = m_hPrimitivesRoot;
  550. type = TypePrimitives;
  551. icon_index = m_iPrimitivesIcon;
  552. break;
  553. case RenderObjClass::CLASSID_DISTLOD:
  554. case RenderObjClass::CLASSID_HLOD:
  555. hroot = m_hHierarchyRoot;
  556. type = TypeHierarchy;
  557. icon_index = m_iHierarchyIcon;
  558. //
  559. // Determine if this is a true LOD or a simple hierarchy
  560. //
  561. if (((HLodClass &)render_obj).Get_LOD_Count () > 1) {
  562. hroot = m_hLODRoot;
  563. type = TypeLOD;
  564. icon_index = m_iLODIcon;
  565. }
  566. break;
  567. }
  568. //
  569. // Is this an aggregate?
  570. //
  571. if (render_obj.Get_Base_Model_Name () != NULL) {
  572. hroot = m_hAggregateRoot;
  573. type = TypeAggregate;
  574. icon_index = m_iAggregateIcon;
  575. }
  576. // Return the type of node
  577. return type;
  578. }
  579. ////////////////////////////////////////////////////////////////////////////
  580. //
  581. // Determine_Tree_Location
  582. //
  583. void
  584. CDataTreeView::Determine_Tree_Location
  585. (
  586. ASSET_TYPE type,
  587. HTREEITEM &hroot,
  588. int &icon_index
  589. )
  590. {
  591. // What type of asset is this?
  592. switch (type) {
  593. case TypeMesh:
  594. hroot = m_hMeshRoot;
  595. icon_index = m_iMeshIcon;
  596. break;
  597. case TypeSound:
  598. hroot = m_hSoundRoot;
  599. icon_index = m_iSoundIcon;
  600. break;
  601. case TypeAggregate:
  602. hroot = m_hAggregateRoot;
  603. icon_index = m_iAggregateIcon;
  604. break;
  605. case TypeHierarchy:
  606. // Shouldn't happen
  607. ASSERT (0);
  608. break;
  609. case TypeEmitter:
  610. hroot = m_hEmitterRoot;
  611. icon_index = m_iEmitterIcon;
  612. break;
  613. case TypePrimitives:
  614. hroot = m_hPrimitivesRoot;
  615. icon_index = m_iPrimitivesIcon;
  616. break;
  617. case TypeLOD:
  618. hroot = m_hLODRoot;
  619. icon_index = m_iLODIcon;
  620. break;
  621. }
  622. return ;
  623. }
  624. ////////////////////////////////////////////////////////////////////////////
  625. //
  626. // Add_Asset_To_Tree
  627. //
  628. bool
  629. CDataTreeView::Add_Asset_To_Tree
  630. (
  631. LPCTSTR name,
  632. ASSET_TYPE type,
  633. bool bselect
  634. )
  635. {
  636. // Assume failure
  637. bool retval = false;
  638. // Param OK?
  639. ASSERT (name != NULL);
  640. if (name != NULL) {
  641. // Turn off repainting
  642. GetTreeCtrl ().SetRedraw (FALSE);
  643. // Determime where this asset should go
  644. HTREEITEM hparent = NULL;
  645. int icon_index = 0;
  646. Determine_Tree_Location (type, hparent, icon_index);
  647. // Is this asset already in the tree?
  648. HTREEITEM htree_item = FindChildItem (hparent, name);
  649. if (htree_item == NULL) {
  650. // Add this object to the tree
  651. htree_item = GetTreeCtrl ().InsertItem (name,
  652. icon_index,
  653. icon_index,
  654. hparent,
  655. TVI_SORT);
  656. // Associate the render object with its entry in the tree
  657. AssetInfoClass *asset_info = new AssetInfoClass (name, type);
  658. GetTreeCtrl ().SetItemData (htree_item, (ULONG)asset_info);
  659. // Load the object's animations into the tree (if necessary)
  660. if (asset_info->Can_Asset_Have_Animations ()) {
  661. LoadAnimationsIntoTree (htree_item);
  662. }
  663. // Success!
  664. retval = (htree_item != NULL);
  665. }
  666. // Select the instance (if requested)
  667. if (bselect) {
  668. GetTreeCtrl ().SelectItem (htree_item);
  669. GetTreeCtrl ().EnsureVisible (htree_item);
  670. }
  671. // Turn painting back on
  672. GetTreeCtrl ().SetRedraw (TRUE);
  673. // Force the window to be repainted
  674. Invalidate (FALSE);
  675. UpdateWindow ();
  676. }
  677. // Return the true/false result code
  678. return retval;
  679. }
  680. ////////////////////////////////////////////////////////////////////////////
  681. //
  682. // FindChildItem
  683. //
  684. HTREEITEM
  685. CDataTreeView::FindChildItem
  686. (
  687. HTREEITEM hParentItem,
  688. RenderObjClass *prender_obj
  689. )
  690. {
  691. // Assume we won't find the item
  692. HTREEITEM hchild_item = NULL;
  693. // Loop through all the children of this node
  694. for (HTREEITEM htree_item = GetTreeCtrl ().GetChildItem (hParentItem);
  695. (htree_item != NULL) && (hchild_item == NULL);
  696. htree_item = GetTreeCtrl ().GetNextSiblingItem (htree_item)) {
  697. // Get the data associated with this item
  698. AssetInfoClass *asset_info = (AssetInfoClass *)GetTreeCtrl ().GetItemData (htree_item);
  699. // Is this the item we were looking for?
  700. if (asset_info &&
  701. asset_info->Peek_Render_Obj () == prender_obj) {
  702. // This was the item we were looking for, return
  703. // its handle to the caller
  704. hchild_item = htree_item;
  705. }
  706. }
  707. // Return the child item handle
  708. return hchild_item;
  709. }
  710. ////////////////////////////////////////////////////////////////////////////
  711. //
  712. // FindChildItem
  713. //
  714. HTREEITEM
  715. CDataTreeView::FindChildItem
  716. (
  717. HTREEITEM hParentItem,
  718. LPCTSTR pszChildItemName
  719. )
  720. {
  721. // Assume we won't find the item
  722. HTREEITEM hChildItem = NULL;
  723. // Loop through all the children of this node
  724. for (HTREEITEM hTreeItem = GetTreeCtrl ().GetChildItem (hParentItem);
  725. (hTreeItem != NULL) && (hChildItem == NULL);
  726. hTreeItem = GetTreeCtrl ().GetNextSiblingItem (hTreeItem))
  727. {
  728. // Is this the child item we were looking for?
  729. if (::lstrcmp (GetTreeCtrl ().GetItemText (hTreeItem), pszChildItemName) == 0)
  730. {
  731. // This was the child item we were looking for, return
  732. // its handle to the caller
  733. hChildItem = hTreeItem;
  734. }
  735. }
  736. // Return the child item handle
  737. return hChildItem;
  738. }
  739. ////////////////////////////////////////////////////////////////////////////
  740. //
  741. // FindSiblingItemBasedOnHierarchyName
  742. //
  743. HTREEITEM
  744. CDataTreeView::FindSiblingItemBasedOnHierarchyName
  745. (
  746. HTREEITEM hCurrentItem,
  747. LPCTSTR pszHierarchyName
  748. )
  749. {
  750. // Assume we won't find the item
  751. HTREEITEM hSiblingItem = NULL;
  752. // Loop through all the siblings of this node
  753. HTREEITEM hTreeItem = hCurrentItem;
  754. while (((hTreeItem = GetTreeCtrl ().GetNextSiblingItem (hTreeItem)) != NULL) &&
  755. (hSiblingItem == NULL))
  756. {
  757. // Get the data associated with this item
  758. AssetInfoClass *asset_info = (AssetInfoClass *)GetTreeCtrl ().GetItemData (hTreeItem);
  759. // Is this the item we were looking for?
  760. if (m_RestrictAnims == false ||
  761. (asset_info && ::lstrcmp (asset_info->Get_Hierarchy_Name (), pszHierarchyName) == 0))
  762. {
  763. // This was the item we were looking for, return
  764. // its handle to the caller
  765. hSiblingItem = hTreeItem;
  766. }
  767. }
  768. // Return the sibling item handle
  769. return hSiblingItem;
  770. }
  771. ////////////////////////////////////////////////////////////////////////////
  772. //
  773. // FindFirstChildItemBasedOnHierarchyName
  774. //
  775. HTREEITEM
  776. CDataTreeView::FindFirstChildItemBasedOnHierarchyName
  777. (
  778. HTREEITEM hParentItem,
  779. LPCTSTR pszHierarchyName
  780. )
  781. {
  782. // Assume we won't find the item
  783. HTREEITEM hChildItem = NULL;
  784. // Loop through all the children of this node
  785. for (HTREEITEM hTreeItem = GetTreeCtrl ().GetChildItem (hParentItem);
  786. (hTreeItem != NULL) && (hChildItem == NULL);
  787. hTreeItem = GetTreeCtrl ().GetNextSiblingItem (hTreeItem))
  788. {
  789. // Get the data associated with this item
  790. AssetInfoClass *asset_info = (AssetInfoClass *)GetTreeCtrl ().GetItemData (hTreeItem);
  791. //
  792. // Is this the item we were looking for?
  793. //
  794. if (m_RestrictAnims == false ||
  795. (asset_info && ::lstrcmp (asset_info->Get_Hierarchy_Name (), pszHierarchyName) == 0))
  796. {
  797. // This was the child item we were looking for, return
  798. // its handle to the caller
  799. hChildItem = hTreeItem;
  800. }
  801. }
  802. // Return the child item handle
  803. return hChildItem;
  804. }
  805. ////////////////////////////////////////////////////////////////////////////
  806. //
  807. // OnSelChanged
  808. //
  809. void
  810. CDataTreeView::OnSelChanged
  811. (
  812. NMHDR* pNMHDR,
  813. LRESULT* pResult
  814. )
  815. {
  816. // Display the new selection
  817. NM_TREEVIEW* pNMTreeView = (NM_TREEVIEW*)pNMHDR;
  818. Display_Asset (pNMTreeView->itemNew.hItem);
  819. (*pResult) = 0;
  820. return ;
  821. }
  822. ////////////////////////////////////////////////////////////////////////////
  823. //
  824. // Display_Asset
  825. //
  826. void
  827. CDataTreeView::Display_Asset (HTREEITEM htree_item)
  828. {
  829. if (htree_item == NULL) {
  830. htree_item = GetTreeCtrl ().GetSelectedItem ();
  831. }
  832. //
  833. // Get the object associated with this entry
  834. //
  835. AssetInfoClass *asset_info = NULL;
  836. if (htree_item != NULL) {
  837. asset_info = (AssetInfoClass *)GetTreeCtrl ().GetItemData (htree_item);
  838. }
  839. if (asset_info != NULL) {
  840. // Get the current document, so we can get a pointer to the scene
  841. CW3DViewDoc *pdoc = (CW3DViewDoc *)GetDocument ();
  842. ASSERT (pdoc != NULL);
  843. if (pdoc != NULL) {
  844. // What type of asset is it?
  845. switch (asset_info->Get_Type ())
  846. {
  847. case TypeCompressedAnimation:
  848. case TypeAnimation:
  849. {
  850. HTREEITEM hParentItem = GetTreeCtrl ().GetParentItem (htree_item);
  851. if (hParentItem != NULL) {
  852. // Ask the document to start playing the animation for this object
  853. RenderObjClass *prender_obj = Create_Render_Obj_To_Display (hParentItem);
  854. pdoc->PlayAnimation (prender_obj,
  855. asset_info->Get_Name ());
  856. MEMBER_RELEASE (prender_obj);
  857. }
  858. }
  859. break;
  860. case TypeEmitter:
  861. {
  862. // Ask the document to display this object
  863. ParticleEmitterClass *emitter = (ParticleEmitterClass *)Create_Render_Obj_To_Display (htree_item);
  864. pdoc->Display_Emitter (emitter);
  865. MEMBER_RELEASE (emitter);
  866. }
  867. break;
  868. case TypeHierarchy:
  869. {
  870. // If the advanced animation option is turned on, display a dialog
  871. // where the user can choose which animations to play together.
  872. }
  873. default:
  874. {
  875. // Ask the document to display this object
  876. RenderObjClass *prender_obj = Create_Render_Obj_To_Display (htree_item);
  877. pdoc->DisplayObject (prender_obj);
  878. MEMBER_RELEASE (prender_obj);
  879. }
  880. break;
  881. }
  882. // Get the main window of our app
  883. CMainFrame *pCMainWnd = (CMainFrame *)::AfxGetMainWnd ();
  884. if (pCMainWnd != NULL) {
  885. // Let the main window know our selection type has changed
  886. pCMainWnd->OnSelectionChanged (asset_info->Get_Type ());
  887. if (asset_info->Get_Type () == TypeAggregate) {
  888. pCMainWnd->Update_Emitters_List ();
  889. } else {
  890. ::EnableMenuItem (::GetSubMenu (::GetMenu (*pCMainWnd), 3), 3, MF_BYPOSITION | MF_DISABLED | MF_GRAYED);
  891. HMENU hsub_menu = pCMainWnd->Get_Emitters_List_Menu ();
  892. int index = 0;
  893. while (::RemoveMenu (hsub_menu, index, MF_BYPOSITION)) {
  894. //index ++;
  895. }
  896. }
  897. }
  898. }
  899. } else {
  900. // Reset the display
  901. CW3DViewDoc* pdoc = (CW3DViewDoc *)GetDocument ();
  902. ASSERT (pdoc != NULL);
  903. if (pdoc != NULL) {
  904. pdoc->DisplayObject ((RenderObjClass *)NULL);
  905. CMainFrame *main_wnd = (CMainFrame *)::AfxGetMainWnd ();
  906. if (main_wnd != NULL) {
  907. main_wnd->OnSelectionChanged (TypeUnknown);
  908. }
  909. }
  910. }
  911. return ;
  912. }
  913. ////////////////////////////////////////////////////////////////////////////
  914. //
  915. // OnDeleteItem
  916. //
  917. void
  918. CDataTreeView::OnDeleteItem
  919. (
  920. NMHDR *pNMHDR,
  921. LRESULT *pResult
  922. )
  923. {
  924. // Get the information object for this asset
  925. NM_TREEVIEW* pNMTreeView = (NM_TREEVIEW*)pNMHDR;
  926. AssetInfoClass *asset_info = (AssetInfoClass *)pNMTreeView->itemOld.lParam;
  927. // If this is a texture, then free our hold on its interface
  928. if (asset_info && (asset_info->Get_Type () == TypeMaterial)) {
  929. TextureClass *ptexture = (TextureClass *)asset_info->Get_User_Number ();
  930. REF_PTR_RELEASE (ptexture);
  931. }
  932. // Free the asset information object
  933. SAFE_DELETE (asset_info);
  934. // Reset the data associated with this entry
  935. GetTreeCtrl ().SetItemData (pNMTreeView->itemOld.hItem, NULL);
  936. (*pResult) = 0;
  937. return ;
  938. }
  939. ////////////////////////////////////////////////////////////////////////////
  940. //
  941. // Get_Current_Asset_Info
  942. //
  943. AssetInfoClass *
  944. CDataTreeView::Get_Current_Asset_Info (void) const
  945. {
  946. AssetInfoClass *asset_info = NULL;
  947. // Get the currently selected node from the tree control
  948. HTREEITEM htree_item = GetTreeCtrl ().GetSelectedItem ();
  949. if (htree_item != NULL) {
  950. // Get the data associated with this item
  951. asset_info = (AssetInfoClass *)GetTreeCtrl ().GetItemData (htree_item);
  952. }
  953. // Return the asset information associated with the current item
  954. return asset_info;
  955. }
  956. ////////////////////////////////////////////////////////////////////////////
  957. //
  958. // Get_Current_Render_Obj
  959. //
  960. RenderObjClass *
  961. CDataTreeView::Get_Current_Render_Obj (void) const
  962. {
  963. RenderObjClass *prender_obj = NULL;
  964. // Get the currently selected node from the tree control
  965. HTREEITEM htree_item = GetTreeCtrl ().GetSelectedItem ();
  966. if (htree_item != NULL) {
  967. // Get the data associated with this item
  968. AssetInfoClass *asset_info = (AssetInfoClass *)GetTreeCtrl ().GetItemData (htree_item);
  969. if (asset_info != NULL) {
  970. // Return the render object pointer
  971. prender_obj = asset_info->Peek_Render_Obj ();
  972. }
  973. }
  974. // Return the render object pointer
  975. return prender_obj;
  976. }
  977. ////////////////////////////////////////////////////////////////////////////
  978. //
  979. // GetCurrentSelectionName
  980. //
  981. LPCTSTR
  982. CDataTreeView::GetCurrentSelectionName (void)
  983. {
  984. LPCTSTR pname = NULL;
  985. // Get the currently selected node from the tree control
  986. HTREEITEM htree_item = GetTreeCtrl ().GetSelectedItem ();
  987. if (htree_item != NULL) {
  988. // Get the data associated with this item
  989. AssetInfoClass *asset_info = (AssetInfoClass *)GetTreeCtrl ().GetItemData (htree_item);
  990. if (asset_info != NULL) {
  991. // Return the name of the asset to the caller
  992. pname = asset_info->Get_Name ();
  993. }
  994. }
  995. // Return the name of the selected node
  996. return pname;
  997. }
  998. ////////////////////////////////////////////////////////////////////////////
  999. //
  1000. // GetCurrentSelectionType
  1001. //
  1002. ASSET_TYPE
  1003. CDataTreeView::GetCurrentSelectionType (void)
  1004. {
  1005. ASSET_TYPE type = TypeUnknown;
  1006. // Get the currently selected node from the tree control
  1007. HTREEITEM htree_item = GetTreeCtrl ().GetSelectedItem ();
  1008. if (htree_item != NULL) {
  1009. // Get the associated asset information for this node.
  1010. AssetInfoClass *asset_info = (AssetInfoClass *)GetTreeCtrl ().GetItemData (htree_item);
  1011. if (asset_info != NULL) {
  1012. type = asset_info->Get_Type ();
  1013. }
  1014. }
  1015. // Return the type of the selected node
  1016. return type;
  1017. }
  1018. ////////////////////////////////////////////////////////////////////////////
  1019. //
  1020. // OnDblclk
  1021. //
  1022. void
  1023. CDataTreeView::OnDblclk
  1024. (
  1025. NMHDR* pNMHDR,
  1026. LRESULT* pResult
  1027. )
  1028. {
  1029. // Get the main window of our app
  1030. CMainFrame *pCMainWnd = (CMainFrame *)::AfxGetMainWnd ();
  1031. if (pCMainWnd != NULL)
  1032. {
  1033. // Display the properties for the currently selected object
  1034. //pCMainWnd->ShowObjectProperties ();
  1035. }
  1036. (*pResult) = 0;
  1037. return ;
  1038. }
  1039. ////////////////////////////////////////////////////////////////////////////
  1040. //
  1041. // Build_Render_Object_List
  1042. //
  1043. void
  1044. CDataTreeView::Build_Render_Object_List
  1045. (
  1046. DynamicVectorClass <CString> &asset_list,
  1047. HTREEITEM hparent
  1048. )
  1049. {
  1050. // Loop through all the children of this node
  1051. for (HTREEITEM htree_item = GetTreeCtrl ().GetChildItem (hparent);
  1052. (htree_item != NULL);
  1053. htree_item = GetTreeCtrl ().GetNextSiblingItem (htree_item)) {
  1054. // Determine if this is an asset type we want to add to the list
  1055. AssetInfoClass *asset_info = (AssetInfoClass *)GetTreeCtrl ().GetItemData (htree_item);
  1056. if ((asset_info != NULL) &&
  1057. (asset_info->Get_Type () != TypeAnimation) &&
  1058. (asset_info->Get_Type () != TypeCompressedAnimation) &&
  1059. (asset_info->Get_Type () != TypeMaterial))
  1060. {
  1061. asset_list.Add (GetTreeCtrl ().GetItemText (htree_item));
  1062. }
  1063. // If this item has children, then add the children recursively
  1064. if (GetTreeCtrl ().ItemHasChildren (htree_item)) {
  1065. Build_Render_Object_List (asset_list, htree_item);
  1066. }
  1067. }
  1068. return ;
  1069. }
  1070. ////////////////////////////////////////////////////////////////////////////
  1071. //
  1072. // Create_Render_Obj_To_Display
  1073. //
  1074. ////////////////////////////////////////////////////////////////////////////
  1075. RenderObjClass *
  1076. CDataTreeView::Create_Render_Obj_To_Display (HTREEITEM htree_item)
  1077. {
  1078. // Lookup the information object associated with this asset
  1079. RenderObjClass *render_obj = NULL;
  1080. AssetInfoClass *asset_info = (AssetInfoClass *)GetTreeCtrl ().GetItemData (htree_item);
  1081. if (asset_info != NULL) {
  1082. // Use the asset's instance if there is one, otherwise attempt to create one
  1083. render_obj = asset_info->Get_Render_Obj ();
  1084. if (render_obj == NULL) {
  1085. // If this is a texture, then create a special BMP obj from it
  1086. if (asset_info->Get_Type () == TypeMaterial) {
  1087. TextureClass *ptexture = (TextureClass *)asset_info->Get_User_Number ();
  1088. if (ptexture != NULL) {
  1089. render_obj = new Bitmap2DObjClass (ptexture, 0.5F, 0.5F, true, false, false, true);
  1090. }
  1091. }
  1092. //
  1093. // Finally, if we aren't successful, create a new instance based on its name
  1094. //
  1095. if (render_obj == NULL) {
  1096. render_obj = WW3DAssetManager::Get_Instance()->Create_Render_Obj (asset_info->Get_Name ());
  1097. }
  1098. }
  1099. }
  1100. //
  1101. // Force the highest level LOD
  1102. //
  1103. if ( render_obj != NULL &&
  1104. ::GetCurrentDocument ()->GetScene ()->Are_LODs_Switching () == false)
  1105. {
  1106. Set_Highest_LOD (render_obj);
  1107. }
  1108. return render_obj;
  1109. }
  1110. ////////////////////////////////////////////////////////////////////////////
  1111. //
  1112. // Refresh_Asset
  1113. //
  1114. void
  1115. CDataTreeView::Refresh_Asset
  1116. (
  1117. LPCTSTR new_name,
  1118. LPCTSTR old_name,
  1119. ASSET_TYPE type
  1120. )
  1121. {
  1122. // Params OK?
  1123. if ((new_name != NULL) && (old_name != NULL)) {
  1124. // Turn off repainting
  1125. GetTreeCtrl ().SetRedraw (FALSE);
  1126. // Determime where this asset should go
  1127. HTREEITEM hparent = NULL;
  1128. int icon_index = 0;
  1129. Determine_Tree_Location (type, hparent, icon_index);
  1130. // Can we find the item we are supposed to refresh?
  1131. HTREEITEM htree_item = FindChildItem (hparent, old_name);
  1132. if (htree_item != NULL) {
  1133. // Refresh the item's text in the tree control
  1134. GetTreeCtrl ().SetItemText (htree_item, new_name);
  1135. // Refresh the associated asset info structure
  1136. AssetInfoClass *asset_info = (AssetInfoClass *)GetTreeCtrl ().GetItemData (htree_item);
  1137. if (asset_info != NULL) {
  1138. asset_info->Set_Name (new_name);
  1139. }
  1140. } else {
  1141. // This asset wasn't already in the tree, so add it...
  1142. Add_Asset_To_Tree (new_name, type, true);
  1143. }
  1144. // Turn painting back on
  1145. GetTreeCtrl ().SetRedraw (TRUE);
  1146. // Force the window to be repainted
  1147. Invalidate (FALSE);
  1148. UpdateWindow ();
  1149. }
  1150. return ;
  1151. }
  1152. ////////////////////////////////////////////////////////////////////////////
  1153. //
  1154. // Select_Next
  1155. //
  1156. void
  1157. CDataTreeView::Select_Next (void)
  1158. {
  1159. //
  1160. // Get the selected entry in the tree control
  1161. //
  1162. HTREEITEM hselected = GetTreeCtrl ().GetSelectedItem ();
  1163. if (hselected != NULL) {
  1164. //
  1165. // Select the item that follows the currently selected item
  1166. //
  1167. HTREEITEM hitem = GetTreeCtrl ().GetNextItem (hselected, TVGN_NEXT);
  1168. if (hitem != NULL) {
  1169. GetTreeCtrl ().SelectItem (hitem);
  1170. }
  1171. }
  1172. return ;
  1173. }
  1174. ////////////////////////////////////////////////////////////////////////////
  1175. //
  1176. // Select_Prev
  1177. //
  1178. void
  1179. CDataTreeView::Select_Prev (void)
  1180. {
  1181. //
  1182. // Get the selected entry in the tree control
  1183. //
  1184. HTREEITEM hselected = GetTreeCtrl ().GetSelectedItem ();
  1185. if (hselected != NULL) {
  1186. //
  1187. // Select the item that follows the currently selected item
  1188. //
  1189. HTREEITEM hitem = GetTreeCtrl ().GetNextItem (hselected, TVGN_PREVIOUS);
  1190. if (hitem != NULL) {
  1191. GetTreeCtrl ().SelectItem (hitem);
  1192. }
  1193. }
  1194. return ;
  1195. }
  1196. ////////////////////////////////////////////////////////////////////////////
  1197. //
  1198. // Reload_Lightmap_Models
  1199. //
  1200. ////////////////////////////////////////////////////////////////////////////
  1201. void
  1202. CDataTreeView::Reload_Lightmap_Models (void)
  1203. {
  1204. Free_Child_Models (m_hMeshCollectionRoot);
  1205. Free_Child_Models (m_hHierarchyRoot);
  1206. Free_Child_Models (m_hMeshRoot);
  1207. return ;
  1208. }
  1209. ////////////////////////////////////////////////////////////////////////////
  1210. //
  1211. // Free_Child_Models
  1212. //
  1213. ////////////////////////////////////////////////////////////////////////////
  1214. void
  1215. CDataTreeView::Free_Child_Models (HTREEITEM parent_item)
  1216. {
  1217. //
  1218. // Loop through all the children of this node
  1219. //
  1220. for ( HTREEITEM tree_item = GetTreeCtrl ().GetChildItem (parent_item);
  1221. tree_item != NULL;
  1222. tree_item = GetTreeCtrl ().GetNextSiblingItem (tree_item))
  1223. {
  1224. //
  1225. // Get the data associated with this item
  1226. //
  1227. AssetInfoClass *asset_info = (AssetInfoClass *)GetTreeCtrl ().GetItemData (tree_item);
  1228. if (asset_info != NULL) {
  1229. WW3DAssetManager::Get_Instance ()->Remove_Prototype (asset_info->Get_Name ());
  1230. }
  1231. }
  1232. return ;
  1233. }
  1234. ////////////////////////////////////////////////////////////////////////////
  1235. //
  1236. // Set_Highest_LOD
  1237. //
  1238. ////////////////////////////////////////////////////////////////////////////
  1239. void
  1240. Set_Highest_LOD (RenderObjClass *render_obj)
  1241. {
  1242. if (render_obj != NULL) {
  1243. for (int index = 0; index < render_obj->Get_Num_Sub_Objects (); index ++) {
  1244. RenderObjClass *sub_obj = render_obj->Get_Sub_Object (index);
  1245. if (sub_obj != NULL) {
  1246. Set_Highest_LOD (sub_obj);
  1247. }
  1248. MEMBER_RELEASE (sub_obj);
  1249. }
  1250. //
  1251. // Switcht this LOD to its highest level
  1252. //
  1253. if (render_obj->Class_ID () == RenderObjClass::CLASSID_HLOD) {
  1254. ((HLodClass *)render_obj)->Set_LOD_Level (((HLodClass *)render_obj)->Get_Lod_Count () - 1);
  1255. }
  1256. }
  1257. return ;
  1258. }
  1259. ////////////////////////////////////////////////////////////////////////////
  1260. //
  1261. // Restrict_Anims
  1262. //
  1263. ////////////////////////////////////////////////////////////////////////////
  1264. void
  1265. CDataTreeView::Restrict_Anims (bool onoff)
  1266. {
  1267. if (m_RestrictAnims != onoff) {
  1268. m_RestrictAnims = onoff;
  1269. //
  1270. // Reload the tree
  1271. //
  1272. GetTreeCtrl ().DeleteAllItems ();
  1273. CreateRootNodes ();
  1274. LoadAssetsIntoTree ();
  1275. }
  1276. return ;
  1277. }