efapp.cpp 22 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808
  1. #include "pch.h"
  2. //////////////////////////////////////////////////////////////////////////////
  3. //
  4. // Trek Resources
  5. //
  6. //////////////////////////////////////////////////////////////////////////////
  7. TRef<IEngineFont> g_pfontSmall;
  8. TRef<IEngineFont> g_pfontSmallBold;
  9. TRef<IEngineFont> g_pfontLarge;
  10. TRef<IEngineFont> g_pfontLargeBold;
  11. TRef<IEngineFont> g_pfontHuge;
  12. TRef<IEngineFont> g_pfontHugeBold;
  13. IEngineFont* TrekResources::SmallFont()
  14. {
  15. return g_pfontSmall;
  16. }
  17. IEngineFont* TrekResources::SmallBoldFont()
  18. {
  19. return g_pfontSmallBold;
  20. }
  21. IEngineFont* TrekResources::LargeFont()
  22. {
  23. return g_pfontLarge;
  24. }
  25. IEngineFont* TrekResources::LargeBoldFont()
  26. {
  27. return g_pfontLargeBold;
  28. }
  29. IEngineFont* TrekResources::HugeFont()
  30. {
  31. return g_pfontHuge;
  32. }
  33. IEngineFont* TrekResources::HugeBoldFont()
  34. {
  35. return g_pfontHugeBold;
  36. }
  37. void TrekResources::Initialize(Modeler* pmodeler)
  38. {
  39. TRef<INameSpace> pns = pmodeler->GetNameSpace("font");
  40. g_pfontSmall = pns->FindFont("smallFont");
  41. g_pfontSmallBold = pns->FindFont("smallBoldFont");
  42. g_pfontLarge = pns->FindFont("largeFont");
  43. g_pfontLargeBold = pns->FindFont("largeBoldFont");
  44. g_pfontHuge = pns->FindFont("hugeFont");
  45. g_pfontHugeBold = pns->FindFont("hugeBoldFont");
  46. }
  47. //////////////////////////////////////////////////////////////////////////////
  48. //
  49. // Lights Geo
  50. //
  51. //////////////////////////////////////////////////////////////////////////////
  52. class LightData {
  53. public:
  54. LightData()
  55. {
  56. }
  57. Color m_color;
  58. Vector m_vec;
  59. float m_period;
  60. float m_phase;
  61. float m_rampUp;
  62. float m_hold;
  63. float m_rampDown;
  64. };
  65. class LightsGeo : public Geo {
  66. private:
  67. typedef TList<LightData, DefaultNoEquals> LightDataList;
  68. TRef<Image> m_pimage;
  69. LightDataList m_list;
  70. float m_time;
  71. Number* GetTime() { return Number::Cast(GetChild(0)); }
  72. public:
  73. LightsGeo(Modeler* pmodeler, Number* ptime) :
  74. Geo(ptime)
  75. {
  76. m_pimage = pmodeler->LoadImage(AWF_EFFECT_STROBE, true);
  77. }
  78. void AddLight(const LightData& data)
  79. {
  80. m_list.PushFront();
  81. m_list.GetFront() = data;
  82. }
  83. void AddLight(
  84. const Color& color,
  85. const Vector& vec,
  86. float period,
  87. float phase,
  88. float rampUp,
  89. float hold,
  90. float rampDown
  91. ) {
  92. m_list.PushFront();
  93. m_list.GetFront().m_color = color;
  94. m_list.GetFront().m_vec = vec;
  95. m_list.GetFront().m_period = period;
  96. m_list.GetFront().m_phase = phase;
  97. m_list.GetFront().m_rampUp = rampUp;
  98. m_list.GetFront().m_hold = hold;
  99. m_list.GetFront().m_rampDown = rampDown;
  100. }
  101. int GetCount()
  102. {
  103. return m_list.GetCount();
  104. }
  105. //
  106. // Geo members
  107. //
  108. float GetRadius(const Matrix& mat)
  109. {
  110. return 1;
  111. }
  112. void Render(Context* pcontext)
  113. {
  114. TRef<Surface> psurface = m_pimage->GetSurface();
  115. LightDataList::Iterator iter(m_list);
  116. while (!iter.End()) {
  117. LightData& data = iter.Value();
  118. float value;
  119. while (true) {
  120. value = m_time - data.m_phase;
  121. if (value < data.m_period) {
  122. break;
  123. }
  124. data.m_phase += data.m_period;
  125. }
  126. if (value < data.m_rampUp) {
  127. value /= data.m_rampUp;
  128. } else {
  129. value -= data.m_rampUp;
  130. if (value < data.m_hold) {
  131. value = 1;
  132. } else {
  133. value -= data.m_hold;
  134. if (value < data.m_rampDown) {
  135. value = 1 - (value / data.m_rampDown);
  136. } else {
  137. value = 0;
  138. }
  139. }
  140. }
  141. if (value > 0) {
  142. pcontext->DrawDecal(
  143. psurface,
  144. data.m_color,
  145. data.m_vec,
  146. Vector::GetZero(),
  147. Vector::GetZero(),
  148. 0.5f * value,
  149. 0
  150. );
  151. }
  152. iter.Next();
  153. }
  154. }
  155. //
  156. // Value members
  157. //
  158. void Evaluate()
  159. {
  160. m_time = GetTime()->GetValue();
  161. }
  162. ZString GetFunctionName()
  163. {
  164. return "LightsGeo";
  165. }
  166. ZString GetString(int indent)
  167. {
  168. ZString str = "Lights([\n";
  169. LightDataList::Iterator iter(m_list);
  170. while (!iter.End()) {
  171. LightData& data = iter.Value();
  172. str +=
  173. Indent(indent + 1)
  174. + "( " + ::GetString(indent, data.m_color)
  175. + ", " + ::GetString(indent, data.m_vec)
  176. + ", " + ZString(data.m_period)
  177. + ", " + ZString(data.m_phase)
  178. + ", " + ZString(data.m_rampUp)
  179. + ", " + ZString(data.m_hold)
  180. + ", " + ZString(data.m_rampDown)
  181. + ")";
  182. iter.Next();
  183. if (iter.End()) {
  184. str += "\n";
  185. } else {
  186. str += ",\n";
  187. }
  188. }
  189. return str + Indent(indent) + "])";
  190. }
  191. void Write(IMDLBinaryFile* pmdlFile)
  192. {
  193. pmdlFile->WriteReference("LightsGeo");
  194. TRef<ZFile> pfile = pmdlFile->WriteBinary();
  195. pfile->Write(m_list.GetCount());
  196. LightDataList::Iterator iter(m_list);
  197. while (!iter.End()) {
  198. LightData& data = iter.Value();
  199. pfile->Write((void*)&data, sizeof(LightData));
  200. iter.Next();
  201. }
  202. }
  203. };
  204. //////////////////////////////////////////////////////////////////////////////
  205. //
  206. // Lights
  207. //
  208. //////////////////////////////////////////////////////////////////////////////
  209. class LightsFactory : public IFunction {
  210. private:
  211. TRef<Modeler> m_pmodeler;
  212. TRef<Number> m_ptime;
  213. public:
  214. LightsFactory(Modeler* pmodeler, Number* ptime) :
  215. m_pmodeler(pmodeler),
  216. m_ptime(ptime)
  217. {
  218. }
  219. TRef<IObject> Apply(ObjectStack& stack)
  220. {
  221. TRef<LightsGeo> plights = new LightsGeo(m_pmodeler, m_ptime);
  222. TRef<IObjectList> plist; CastTo(plist, (IObject*)stack.Pop());
  223. while (plist->GetCurrent() != NULL) {
  224. IObjectPair* ppair; CastTo(ppair, plist->GetCurrent());
  225. Color color = GetColor(ppair->GetNth(0));
  226. Vector vector = GetVector(ppair->GetNth(1));
  227. float period = GetNumber(ppair->GetNth(2));
  228. float phase = GetNumber(ppair->GetNth(3));
  229. float rampUp = GetNumber(ppair->GetNth(4));
  230. float hold = GetNumber(ppair->GetNth(5));
  231. float rampDown = GetNumber(ppair->GetLastNth(6));
  232. plights->AddLight(color, vector, period, phase, rampUp, hold, rampDown);
  233. plist->GetNext();
  234. }
  235. return plights;
  236. }
  237. TRef<IObject> Read(IBinaryReaderSite* psite, ObjectStack& stack)
  238. {
  239. TRef<LightsGeo> plights = new LightsGeo(m_pmodeler, m_ptime);
  240. DWORD count = psite->GetDWORD();
  241. for(DWORD index = 0; index < count; index++) {
  242. #ifdef DREAMCAST
  243. LightData data; psite->CopyStructure(&data);
  244. plights->AddLight(data);
  245. #else
  246. LightData* pdata = (LightData*)psite->GetPointer();
  247. psite->MovePointer(sizeof(LightData));
  248. plights->AddLight(*pdata);
  249. #endif
  250. }
  251. return plights;
  252. }
  253. };
  254. //////////////////////////////////////////////////////////////////////////////
  255. //
  256. // FrameData
  257. //
  258. //////////////////////////////////////////////////////////////////////////////
  259. class FrameDataFactory : public IFunction {
  260. public:
  261. TRef<IObject> Apply(ObjectStack& stack)
  262. {
  263. TRef<FrameDataListValue> plistValue = new FrameDataListValue();
  264. TRef<IObjectList> plist; CastTo(plist, (IObject*)stack.Pop());
  265. while (plist->GetCurrent()) {
  266. IObjectPair* ppair; CastTo(ppair, plist->GetCurrent());
  267. ZString strName = GetString(ppair->GetNth(0));
  268. Vector vecPosition = GetVector(ppair->GetNth(1));
  269. Vector vecForward = GetVector(ppair->GetNth(2));
  270. Vector vecUp = GetVector(ppair->GetLastNth(3));
  271. plistValue->GetList().PushEnd(
  272. FrameData(
  273. strName,
  274. vecPosition,
  275. vecForward,
  276. vecUp
  277. )
  278. );
  279. plist->GetNext();
  280. }
  281. return plistValue;
  282. }
  283. TRef<IObject> Read(IBinaryReaderSite* psite, ObjectStack& stack)
  284. {
  285. TRef<FrameDataListValue> plistValue = new FrameDataListValue();
  286. DWORD count = psite->GetDWORD();
  287. for(DWORD index = 0; index < count; index++) {
  288. ZString str = psite->GetString();
  289. #ifdef DREAMCAST
  290. Vector vecPosition, vecForward, vecUp;
  291. Vector* pvecPosition = &vecPosition; psite->CopyStructure(pvecPosition);
  292. Vector* pvecForward = &vecForward; psite->CopyStructure(pvecForward);
  293. Vector* pvecUp = &vecUp; psite->CopyStructure(pvecUp);
  294. #else
  295. Vector* pvecPosition; psite->GetStructure(pvecPosition);
  296. Vector* pvecForward; psite->GetStructure(pvecForward);
  297. Vector* pvecUp; psite->GetStructure(pvecUp);
  298. #endif
  299. plistValue->GetList().PushEnd(
  300. FrameData(
  301. str,
  302. *pvecPosition,
  303. *pvecForward,
  304. *pvecUp
  305. )
  306. );
  307. }
  308. return plistValue;
  309. }
  310. };
  311. //////////////////////////////////////////////////////////////////////////////
  312. //
  313. // GameStateContainer
  314. //
  315. //////////////////////////////////////////////////////////////////////////////
  316. class GameStateContainerFactory : public IFunction {
  317. private:
  318. TRef<Modeler> m_pmodeler;
  319. public:
  320. GameStateContainerFactory(Modeler* pmodeler) :
  321. m_pmodeler(pmodeler)
  322. {
  323. }
  324. TRef<IObject> Apply(ObjectStack& stack)
  325. {
  326. TRef<FontValue> pfontTitles; CastTo(pfontTitles, (IObject*)stack.Pop());
  327. TRef<FontValue> pfontTime; CastTo(pfontTime, (IObject*)stack.Pop());
  328. TRef<ButtonPane> pbutton; CastTo(pbutton, (IObject*)stack.Pop());
  329. return
  330. CreateGameStateContainer(
  331. m_pmodeler,
  332. pfontTitles->GetValue(),
  333. pfontTime->GetValue(),
  334. pbutton
  335. );
  336. }
  337. };
  338. //////////////////////////////////////////////////////////////////////////////
  339. //
  340. // GameStateImage
  341. //
  342. //////////////////////////////////////////////////////////////////////////////
  343. class GameStateImageFactory : public IFunction {
  344. public:
  345. TRef<IObject> Apply(ObjectStack& stack)
  346. {
  347. TRef<GameStateContainer> pgsc; CastTo(pgsc, (IObject*)stack.Pop());
  348. return (Value*)pgsc->GetImage();
  349. }
  350. };
  351. //////////////////////////////////////////////////////////////////////////////
  352. //
  353. // Model Optimizer
  354. //
  355. //////////////////////////////////////////////////////////////////////////////
  356. class GroupGeoCallbackImpl : public GroupGeoCallback {
  357. private:
  358. class Token : public TextTokenImpl {
  359. public:
  360. Token(PCC pcc, int length) :
  361. TextTokenImpl(pcc, length)
  362. {
  363. Next();
  364. }
  365. void ReadStrobe(float& phase, float& period)
  366. {
  367. if (IsNumber(phase, false)) {
  368. phase = -phase;
  369. if (IsNumber(period, false)) {
  370. period = -period;
  371. }
  372. }
  373. }
  374. };
  375. TRef<LightsGeo> m_plights;
  376. TRef<FrameDataListValue> m_pframes;
  377. public:
  378. GroupGeoCallbackImpl(
  379. FrameDataListValue* pframes,
  380. LightsGeo* plights
  381. ) :
  382. m_pframes(pframes),
  383. m_plights(plights)
  384. {
  385. }
  386. void AddLight(
  387. const ZString& str,
  388. const Color& color,
  389. const Vector& vecPosition
  390. ) {
  391. //
  392. // default values
  393. //
  394. float period = 1.25;
  395. float phase = 0;
  396. float rampUp = 0.1f;
  397. float hold = 0.0f;
  398. float rampDown = 0.05f;
  399. //
  400. // parse the string
  401. //
  402. Token(str, str.GetLength()).ReadStrobe(phase, period);
  403. //
  404. // Add it
  405. //
  406. m_plights->AddLight(
  407. color,
  408. vecPosition,
  409. period, phase, rampUp, hold, rampDown
  410. );
  411. }
  412. TRef<Geo> Execute(const Matrix& mat, GroupGeo* pgroup)
  413. {
  414. ZString strName = pgroup->GetName();
  415. if (!strName.IsEmpty()) {
  416. if ( strName.Find("frm-") == 0
  417. && (!pgroup->AnyChildGroups())
  418. ) {
  419. Vector vecPosition = mat.Transform(Vector(0, 0, 0));
  420. Vector vecForward = mat.TransformDirection(Vector(0, 0, -1));
  421. Vector vecUp = mat.TransformDirection(Vector(0, 1, 0));
  422. strName = strName.RightOf(4);
  423. if (strName.Find("SS") != -1) {
  424. //
  425. // a strobe light
  426. //
  427. ValueList* plist = pgroup->GetList();
  428. if (plist->GetCount() == 1) {
  429. MaterialGeo* pmatGeo; CastTo(pmatGeo, plist->GetFirst());
  430. Material* pmaterial = pmatGeo->GetMaterial();
  431. AddLight(strName, pmaterial->GetDiffuse(), vecPosition);
  432. } else {
  433. AddLight(strName, Color(1, 1, 1), vecPosition);
  434. }
  435. return Geo::GetEmpty();
  436. } else if (
  437. strName.Find("thrust") != -1
  438. || strName.Find("smoke") != -1
  439. || strName.Find("rocket") != -1
  440. ) {
  441. //
  442. // this is an engine
  443. //
  444. m_pframes->GetList().PushFront(
  445. FrameData(strName, vecPosition, vecForward, vecUp)
  446. );
  447. return Geo::GetEmpty();
  448. } else if (
  449. (strName.Find("weapon") != -1)
  450. || (strName.Find("wepatt") != -1)
  451. || (strName.Find("wepemt") != -1)
  452. || (strName.Find("wepmnt") != -1)
  453. || (strName.Find("trail") != -1)
  454. ) {
  455. //
  456. // This is an attachment point
  457. //
  458. m_pframes->GetList().PushFront(
  459. FrameData(strName, vecPosition, vecForward, vecUp)
  460. );
  461. return Geo::GetEmpty();
  462. } else if (
  463. (strName.Find("garage") != -1)
  464. ) {
  465. //
  466. // This is a garage we need to leave the frame in the graph
  467. //
  468. m_pframes->GetList().PushFront(
  469. FrameData(strName, vecPosition, vecForward, vecUp)
  470. );
  471. }
  472. }
  473. }
  474. return NULL;
  475. }
  476. void ReportTriangles(const Matrix& mat, const TVector<Vertex>& vertices, const TVector<WORD>& indices)
  477. {
  478. // we don't care about triangles here but might be nice to count for LOD analysis
  479. }
  480. void ReportTriangles(const Matrix& mat, const TVector<VertexL>& vertices, const TVector<WORD>& indices)
  481. {
  482. }
  483. void ReportTriangles(const Matrix& mat, const TVector<D3DLVertex>& vertices, const TVector<WORD>& indices)
  484. {
  485. }
  486. void ReportTriangles(const Matrix& mat, const TVector<D3DVertex>& vertices, const TVector<WORD>& indices)
  487. {
  488. }
  489. };
  490. //////////////////////////////////////////////////////////////////////////////
  491. //
  492. //
  493. //
  494. //////////////////////////////////////////////////////////////////////////////
  495. class ScrollPositionNumber : public Number {
  496. private:
  497. TRef<ScrollPane> m_pscroll;
  498. public:
  499. ScrollPositionNumber(ScrollPane* pscroll) :
  500. m_pscroll(pscroll)
  501. {
  502. }
  503. };
  504. //////////////////////////////////////////////////////////////////////////////
  505. //
  506. //
  507. //
  508. //////////////////////////////////////////////////////////////////////////////
  509. class BlendColorImageFactory : public IFunction {
  510. public:
  511. TRef<IObject> Apply(ObjectStack& stack)
  512. {
  513. TRef<ColorValue> pcolor = ColorValue::Cast((IObject*)stack.Pop());
  514. TRef<Image> pimage = Image::Cast((Value*)(IObject*)stack.Pop());
  515. return (Value*)CreateBlendColorImage(pimage, pcolor);
  516. }
  517. };
  518. //////////////////////////////////////////////////////////////////////////////
  519. //
  520. // EffectApp
  521. //
  522. //////////////////////////////////////////////////////////////////////////////
  523. HRESULT EffectApp::Initialize(const ZString& strCommandLine)
  524. {
  525. if (SUCCEEDED(EngineApp::Initialize(strCommandLine))) {
  526. TRef<INameSpace> pnsModel = GetModeler()->GetNameSpace("model");
  527. TRef<Number> pnumberTime; CastTo(pnumberTime, pnsModel->FindMember("time"));
  528. m_pns =
  529. GetModeler()->CreateNameSpace(
  530. "effect",
  531. pnsModel
  532. );
  533. //
  534. // Types
  535. //
  536. m_pns->AddType("QuickChatNode", CreateIObjectMDLType("QuickChatNode" , "qcn" ));
  537. m_pns->AddType("Sound" , CreateIObjectMDLType("IObject", "sound"));
  538. //
  539. // Constructors
  540. //
  541. m_pns->AddMember("LightsGeo", new LightsFactory(GetModeler(), pnumberTime));
  542. m_pns->AddMember("FrameData", new FrameDataFactory() );
  543. m_pns->AddMember("GameStateContainer", new GameStateContainerFactory(GetModeler()) );
  544. m_pns->AddMember("GameStateImage", new GameStateImageFactory() );
  545. m_pns->AddMember("BlendColorImage", new BlendColorImageFactory() );
  546. AddPaneFactories(m_pns, GetModeler(), GetPopupContainer(), pnumberTime);
  547. AddPagePaneFactory(m_pns, GetModeler());
  548. AddNavPaneFactory(m_pns);
  549. //
  550. // Fonts
  551. //
  552. #ifndef DREAMCAST
  553. //InitializeTrekResources(GetModeler());
  554. /*
  555. m_pns->AddMember("smallFont", new FontValue(TrekResources::SmallFont() ));
  556. m_pns->AddMember("smallBoldFont", new FontValue(TrekResources::SmallBoldFont()));
  557. m_pns->AddMember("largeFont", new FontValue(TrekResources::LargeFont() ));
  558. m_pns->AddMember("largeBoldFont", new FontValue(TrekResources::LargeBoldFont()));
  559. m_pns->AddMember("hugeFont", new FontValue(TrekResources::HugeFont() ));
  560. m_pns->AddMember("hugeBoldFont", new FontValue(TrekResources::HugeBoldFont() ));
  561. */
  562. #endif
  563. return S_OK;
  564. }
  565. return E_FAIL;
  566. }
  567. void EffectApp::Terminate()
  568. {
  569. m_pns = NULL;
  570. EngineApp::Terminate();
  571. }
  572. TRef<INameSpace> EffectApp::OptimizeThingGeo(const ZString& str, Geo* pgeo, Number* pnumber)
  573. {
  574. //
  575. // Get the time value
  576. //
  577. TRef<INameSpace> pnsModel = GetModeler()->GetNameSpace("model");
  578. TRef<Number> pnumberTime; CastTo(pnumberTime, pnsModel->FindMember("time"));
  579. //
  580. // we are going to create a namespace with all the stuff needed by a ThingGeo
  581. //
  582. TRef<INameSpace> pns = GetModeler()->CreateNameSpace(str, m_pns);
  583. if (pnumber != NULL) {
  584. pns->AddMember("frame", pnumber);
  585. }
  586. //
  587. // Wrap the Geo up so we don't lose the pointer as we do optimizations
  588. //
  589. TRef<WrapGeo> pwrap = new WrapGeo(pgeo);
  590. pwrap->Update();
  591. //
  592. // Add a LightsGeo to the Group
  593. //
  594. TRef<LightsGeo> plights = new LightsGeo(GetModeler(), pnumberTime);
  595. //
  596. // Add a list of frames
  597. //
  598. TRef<FrameDataListValue> pframes = new FrameDataListValue();
  599. //
  600. // Extract the lights and frames
  601. //
  602. ZDebugOutput("Before Callback: " + ZString(pwrap->GetGeo()->GetNodeCount()) + "\n");
  603. TRef<GroupGeoCallbackImpl> pcallback = new GroupGeoCallbackImpl(pframes, plights);
  604. pwrap->GetGeo()->CallGroupGeoCallback(Matrix::GetIdentity(), pcallback);
  605. //
  606. // If there are any lights or frames add them to the namespace
  607. //
  608. if (plights->GetCount() > 0) {
  609. pns->AddMember("lights", plights);
  610. }
  611. if (pframes->GetList().GetCount() > 0) {
  612. pns->AddMember("frames", pframes);
  613. }
  614. //
  615. // Optimize the geo
  616. //
  617. bool bAnyFold;
  618. TRef<Geo> pgeoFold;
  619. do {
  620. bAnyFold = false;
  621. ZDebugOutput("Before RemoveMaterial: " + ZString(pwrap->GetGeo()->GetNodeCount()) + "\n");
  622. pgeoFold = pwrap->GetGeo()->RemoveMaterial();
  623. if (pgeoFold) {
  624. bAnyFold = true;
  625. pwrap->SetGeo(pgeoFold);
  626. ZDebugOutput("Before Fold: " + ZString(pwrap->GetGeo()->GetNodeCount()) + "\n");
  627. pwrap->GetGeo()->DoFold();
  628. }
  629. ZDebugOutput("Before FoldTexture: " + ZString(pwrap->GetGeo()->GetNodeCount()) + "\n");
  630. pgeoFold = pwrap->GetGeo()->FoldTexture();
  631. if (pgeoFold) {
  632. bAnyFold = true;
  633. pwrap->SetGeo(pgeoFold);
  634. ZDebugOutput("Before Fold: " + ZString(pwrap->GetGeo()->GetNodeCount()) + "\n");
  635. pwrap->GetGeo()->DoFold();
  636. }
  637. if (!bAnyFold) {
  638. ZDebugOutput("Before Fold: " + ZString(pwrap->GetGeo()->GetNodeCount()) + "\n");
  639. bAnyFold = pwrap->GetGeo()->DoFold();
  640. }
  641. } while (bAnyFold);
  642. ZDebugOutput("After Optimization: " + ZString(pwrap->GetGeo()->GetNodeCount()) + "\n");
  643. //
  644. // We're done
  645. //
  646. pns->AddMember("object", pwrap->GetGeo());
  647. return pns;
  648. }