PageRenderTime 51ms CodeModel.GetById 19ms RepoModel.GetById 1ms app.codeStats 0ms

/CS/migrated/branches/NEW_SHADERSYS/plugins/mesh/genmesh/persist/standard/gmeshldr.cpp

#
C++ | 620 lines | 536 code | 62 blank | 22 comment | 57 complexity | 67116f58237075821969a67410919fc1 MD5 | raw file
Possible License(s): GPL-2.0, LGPL-2.1, LGPL-2.0
  1. /*
  2. Copyright (C) 2002 by Jorrit Tyberghein
  3. This library is free software; you can redistribute it and/or
  4. modify it under the terms of the GNU Library General Public
  5. License as published by the Free Software Foundation; either
  6. version 2 of the License, or (at your option) any later version.
  7. This library is distributed in the hope that it will be useful,
  8. but WITHOUT ANY WARRANTY; without even the implied warranty of
  9. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  10. Library General Public License for more details.
  11. You should have received a copy of the GNU Library General Public
  12. License along with this library; if not, write to the Free
  13. Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  14. */
  15. #include "cssysdef.h"
  16. #include "cssys/sysfunc.h"
  17. #include "csgeom/math3d.h"
  18. #include "csutil/scanstr.h"
  19. #include "csutil/cscolor.h"
  20. #include "gmeshldr.h"
  21. #include "imesh/object.h"
  22. #include "iengine/mesh.h"
  23. #include "iengine/engine.h"
  24. #include "iutil/plugin.h"
  25. #include "iutil/document.h"
  26. #include "imesh/genmesh.h"
  27. #include "ivideo/graph3d.h"
  28. #include "ivideo/rndbuf.h"
  29. #include "qint.h"
  30. #include "iutil/object.h"
  31. #include "iengine/material.h"
  32. #include "ivaria/reporter.h"
  33. #include "iutil/objreg.h"
  34. #include "iutil/eventh.h"
  35. #include "iutil/comp.h"
  36. #include "imap/services.h"
  37. #include "imap/ldrctxt.h"
  38. #include "csgeom/vector2.h"
  39. #include "csgeom/vector4.h"
  40. CS_IMPLEMENT_PLUGIN
  41. enum
  42. {
  43. XMLTOKEN_BOX = 1,
  44. XMLTOKEN_LIGHTING,
  45. XMLTOKEN_COLOR,
  46. XMLTOKEN_MATERIAL,
  47. XMLTOKEN_FACTORY,
  48. XMLTOKEN_MIXMODE,
  49. XMLTOKEN_MANUALCOLORS,
  50. XMLTOKEN_NUMTRI,
  51. XMLTOKEN_NUMVT,
  52. XMLTOKEN_V,
  53. XMLTOKEN_T,
  54. XMLTOKEN_N,
  55. XMLTOKEN_RENDERBUFFER,
  56. XMLTOKEN_COLORS,
  57. XMLTOKEN_AUTONORMALS,
  58. XMLTOKEN_NOSHADOWS,
  59. XMLTOKEN_LOCALSHADOWS
  60. };
  61. SCF_IMPLEMENT_IBASE (csGeneralFactoryLoader)
  62. SCF_IMPLEMENTS_INTERFACE (iLoaderPlugin)
  63. SCF_IMPLEMENTS_EMBEDDED_INTERFACE (iComponent)
  64. SCF_IMPLEMENT_IBASE_END
  65. SCF_IMPLEMENT_EMBEDDED_IBASE (csGeneralFactoryLoader::eiComponent)
  66. SCF_IMPLEMENTS_INTERFACE (iComponent)
  67. SCF_IMPLEMENT_EMBEDDED_IBASE_END
  68. SCF_IMPLEMENT_IBASE (csGeneralFactorySaver)
  69. SCF_IMPLEMENTS_INTERFACE (iSaverPlugin)
  70. SCF_IMPLEMENTS_EMBEDDED_INTERFACE (iComponent)
  71. SCF_IMPLEMENT_IBASE_END
  72. SCF_IMPLEMENT_EMBEDDED_IBASE (csGeneralFactorySaver::eiComponent)
  73. SCF_IMPLEMENTS_INTERFACE (iComponent)
  74. SCF_IMPLEMENT_EMBEDDED_IBASE_END
  75. SCF_IMPLEMENT_IBASE (csGeneralMeshLoader)
  76. SCF_IMPLEMENTS_INTERFACE (iLoaderPlugin)
  77. SCF_IMPLEMENTS_EMBEDDED_INTERFACE (iComponent)
  78. SCF_IMPLEMENT_IBASE_END
  79. SCF_IMPLEMENT_EMBEDDED_IBASE (csGeneralMeshLoader::eiComponent)
  80. SCF_IMPLEMENTS_INTERFACE (iComponent)
  81. SCF_IMPLEMENT_EMBEDDED_IBASE_END
  82. SCF_IMPLEMENT_IBASE (csGeneralMeshSaver)
  83. SCF_IMPLEMENTS_INTERFACE (iSaverPlugin)
  84. SCF_IMPLEMENTS_EMBEDDED_INTERFACE (iComponent)
  85. SCF_IMPLEMENT_IBASE_END
  86. SCF_IMPLEMENT_EMBEDDED_IBASE (csGeneralMeshSaver::eiComponent)
  87. SCF_IMPLEMENTS_INTERFACE (iComponent)
  88. SCF_IMPLEMENT_EMBEDDED_IBASE_END
  89. SCF_IMPLEMENT_FACTORY (csGeneralFactoryLoader)
  90. SCF_IMPLEMENT_FACTORY (csGeneralFactorySaver)
  91. SCF_IMPLEMENT_FACTORY (csGeneralMeshLoader)
  92. SCF_IMPLEMENT_FACTORY (csGeneralMeshSaver)
  93. csGeneralFactoryLoader::csGeneralFactoryLoader (iBase* pParent)
  94. {
  95. SCF_CONSTRUCT_IBASE (pParent);
  96. SCF_CONSTRUCT_EMBEDDED_IBASE(scfiComponent);
  97. }
  98. csGeneralFactoryLoader::~csGeneralFactoryLoader ()
  99. {
  100. }
  101. bool csGeneralFactoryLoader::Initialize (iObjectRegistry* object_reg)
  102. {
  103. csGeneralFactoryLoader::object_reg = object_reg;
  104. reporter = CS_QUERY_REGISTRY (object_reg, iReporter);
  105. synldr = CS_QUERY_REGISTRY (object_reg, iSyntaxService);
  106. xmltokens.Register ("box", XMLTOKEN_BOX);
  107. xmltokens.Register ("material", XMLTOKEN_MATERIAL);
  108. xmltokens.Register ("factory", XMLTOKEN_FACTORY);
  109. xmltokens.Register ("numtri", XMLTOKEN_NUMTRI);
  110. xmltokens.Register ("numvt", XMLTOKEN_NUMVT);
  111. xmltokens.Register ("v", XMLTOKEN_V);
  112. xmltokens.Register ("t", XMLTOKEN_T);
  113. xmltokens.Register ("color", XMLTOKEN_COLOR);
  114. xmltokens.Register ("autonormals", XMLTOKEN_AUTONORMALS);
  115. xmltokens.Register ("n", XMLTOKEN_N);
  116. xmltokens.Register ("renderbuffer", XMLTOKEN_RENDERBUFFER);
  117. return true;
  118. }
  119. #ifdef CS_USE_NEW_RENDERER
  120. bool csGeneralFactoryLoader::ParseRenderBuffer(iDocumentNode *node,
  121. iGeneralFactoryState* state)
  122. {
  123. if(!node) return false;
  124. if(!state) return false;
  125. csRef<iDocumentNode> child;
  126. csRef<iDocumentNodeIterator> children = node->GetNodes();
  127. if(!children.IsValid()) return false; // empty renderbuffer..
  128. const char *comptype = node->GetAttributeValue("type");
  129. const char *name = node->GetAttributeValue("name");
  130. int compcount = node->GetAttributeValueAsInt("compcount");
  131. int length = state->GetVertexCount();
  132. if(strcmp(comptype, "float") == 0)
  133. {
  134. float *floatarray = new float[length * compcount];
  135. int vertexindex = 0;
  136. while(children->HasNext())
  137. {
  138. child = children->Next();
  139. if (child->GetType () != CS_NODE_ELEMENT) continue;
  140. if(strcmp("va", child->GetValue ()) == 0)
  141. {
  142. for(int i = 0; i < compcount; i++)
  143. {
  144. char attribname[12];
  145. attribname[0] = 'f';
  146. attribname[1] = '\0';
  147. sprintf (&attribname[1], "%d", i);
  148. floatarray[vertexindex * compcount + i] = child
  149. ->GetAttributeValueAsFloat(attribname);
  150. }
  151. vertexindex++;
  152. }
  153. };
  154. state->AddRenderBuffer(name, CS_BUFCOMP_FLOAT, compcount);
  155. state->SetRenderBuffer(name, floatarray);
  156. delete[] floatarray;
  157. }
  158. if(strcmp(comptype, "int") == 0)
  159. {
  160. int *intarray = new int[length * compcount];
  161. int vertexindex = 0;
  162. while(children->HasNext())
  163. {
  164. child = children->Next();
  165. if (child->GetType () != CS_NODE_ELEMENT) continue;
  166. if(strcmp("va", child->GetValue()) == 0)
  167. {
  168. for(int i = 0; i < compcount; i++)
  169. {
  170. char attribname[12];
  171. attribname[0] = 'i';
  172. attribname[1] = '\0';
  173. sprintf(&attribname[1], "%d", i);
  174. intarray[vertexindex * compcount + i] = child
  175. ->GetAttributeValueAsInt(attribname);
  176. }
  177. vertexindex++;
  178. }
  179. };
  180. state->AddRenderBuffer(name, CS_BUFCOMP_INT, compcount);
  181. state->SetRenderBuffer(name, intarray);
  182. delete[] intarray;
  183. }
  184. else if(strcmp(comptype, "short") == 0)
  185. {
  186. compcount += (compcount % 2);
  187. short *shortarray = new short[length * compcount];
  188. int vertexindex = 0;
  189. while(children->HasNext())
  190. {
  191. child = children->Next();
  192. if (child->GetType () != CS_NODE_ELEMENT) continue;
  193. if(strcmp("va", child->GetValue()) == 0)
  194. {
  195. for(int i = 0; i < compcount; i++)
  196. {
  197. char attribname[12];
  198. attribname[0] = 's';
  199. attribname[1] = '\0';
  200. sprintf (&attribname[1], "%d", i);
  201. shortarray[vertexindex * compcount + i] = child
  202. ->GetAttributeValueAsInt(attribname);
  203. }
  204. vertexindex++;
  205. }
  206. };
  207. state->AddRenderBuffer(name, CS_BUFCOMP_SHORT, compcount);
  208. state->SetRenderBuffer(name, (int*)shortarray);
  209. delete[] shortarray;
  210. }
  211. else if(strcmp(comptype, "byte") == 0)
  212. {
  213. compcount += (compcount % 4);
  214. unsigned char *bytearray = new unsigned char[length * compcount];
  215. int vertexindex = 0;
  216. while(children->HasNext())
  217. {
  218. child = children->Next();
  219. if (child->GetType () != CS_NODE_ELEMENT) continue;
  220. if(strcmp("va", child->GetValue()) == 0)
  221. {
  222. for(int i = 0; i < compcount; i++)
  223. {
  224. char attribname[12];
  225. attribname[0] = 'b';
  226. attribname[1] = '\0';
  227. sprintf (&attribname[1], "%d", i);
  228. bytearray[vertexindex * compcount + i] = child
  229. ->GetAttributeValueAsInt(attribname);
  230. }
  231. vertexindex++;
  232. }
  233. };
  234. state->AddRenderBuffer(name, CS_BUFCOMP_BYTE, compcount);
  235. state->SetRenderBuffer(name, (int*)bytearray);
  236. delete[] bytearray;
  237. }
  238. else
  239. return false;
  240. return true;
  241. }
  242. #endif // CS_USE_NEW_RENDERER
  243. csPtr<iBase> csGeneralFactoryLoader::Parse (iDocumentNode* node,
  244. iLoaderContext* ldr_context, iBase* /* context */)
  245. {
  246. csRef<iPluginManager> plugin_mgr (CS_QUERY_REGISTRY (object_reg,
  247. iPluginManager));
  248. csRef<iMeshObjectType> type (CS_QUERY_PLUGIN_CLASS (plugin_mgr,
  249. "crystalspace.mesh.object.genmesh", iMeshObjectType));
  250. if (!type)
  251. {
  252. type = CS_LOAD_PLUGIN (plugin_mgr, "crystalspace.mesh.object.genmesh",
  253. iMeshObjectType);
  254. }
  255. if (!type)
  256. {
  257. synldr->ReportError (
  258. "crystalspace.genmeshfactoryloader.setup.objecttype",
  259. node, "Could not load the general mesh object plugin!");
  260. return 0;
  261. }
  262. csRef<iMeshObjectFactory> fact;
  263. csRef<iGeneralFactoryState> state;
  264. fact = type->NewFactory ();
  265. state = SCF_QUERY_INTERFACE (fact, iGeneralFactoryState);
  266. int num_tri = 0;
  267. int num_nor = 0;
  268. int num_col = 0;
  269. int num_vt = 0;
  270. bool auto_normals = false;
  271. csRef<iDocumentNodeIterator> it = node->GetNodes ();
  272. while (it->HasNext ())
  273. {
  274. csRef<iDocumentNode> child = it->Next ();
  275. if (child->GetType () != CS_NODE_ELEMENT) continue;
  276. const char* value = child->GetValue ();
  277. csStringID id = xmltokens.Request (value);
  278. switch (id)
  279. {
  280. case XMLTOKEN_MATERIAL:
  281. {
  282. const char* matname = child->GetContentsValue ();
  283. iMaterialWrapper* mat = ldr_context->FindMaterial (matname);
  284. if (!mat)
  285. {
  286. synldr->ReportError (
  287. "crystalspace.genmeshfactoryloader.parse.unknownmaterial",
  288. child, "Couldn't find material '%s'!", matname);
  289. return 0;
  290. }
  291. state->SetMaterialWrapper (mat);
  292. }
  293. break;
  294. case XMLTOKEN_BOX:
  295. {
  296. csBox3 box;
  297. if (!synldr->ParseBox (child, box))
  298. return 0;
  299. state->GenerateBox (box);
  300. }
  301. break;
  302. case XMLTOKEN_AUTONORMALS:
  303. if (!synldr->ParseBool (child, auto_normals, true))
  304. return 0;
  305. break;
  306. case XMLTOKEN_NUMTRI:
  307. state->SetTriangleCount (child->GetContentsValueAsInt ());
  308. break;
  309. case XMLTOKEN_NUMVT:
  310. state->SetVertexCount (child->GetContentsValueAsInt ());
  311. break;
  312. case XMLTOKEN_RENDERBUFFER:
  313. #ifdef CS_USE_NEW_RENDERER
  314. ParseRenderBuffer(child, state);
  315. #endif
  316. break;
  317. case XMLTOKEN_T:
  318. {
  319. csTriangle* tr = state->GetTriangles ();
  320. if (num_tri >= state->GetTriangleCount ())
  321. {
  322. synldr->ReportError (
  323. "crystalspace.genmeshfactoryloader.parse.frame.badformat",
  324. child, "Too many triangles for a general mesh factory!");
  325. return 0;
  326. }
  327. tr[num_tri].a = child->GetAttributeValueAsInt ("v1");
  328. tr[num_tri].b = child->GetAttributeValueAsInt ("v2");
  329. tr[num_tri].c = child->GetAttributeValueAsInt ("v3");
  330. num_tri++;
  331. }
  332. break;
  333. case XMLTOKEN_N:
  334. {
  335. csVector3* no = state->GetNormals ();
  336. if (num_nor >= state->GetVertexCount ())
  337. {
  338. synldr->ReportError (
  339. "crystalspace.genmeshfactoryloader.parse.frame.badformat",
  340. child, "Too many normals for a general mesh factory!");
  341. return 0;
  342. }
  343. float x, y, z;
  344. x = child->GetAttributeValueAsFloat ("x");
  345. y = child->GetAttributeValueAsFloat ("y");
  346. z = child->GetAttributeValueAsFloat ("z");
  347. no[num_nor].Set (x, y, z);
  348. num_nor++;
  349. }
  350. break;
  351. case XMLTOKEN_COLOR:
  352. {
  353. csColor* co = state->GetColors ();
  354. if (num_col >= state->GetVertexCount ())
  355. {
  356. synldr->ReportError (
  357. "crystalspace.genmeshfactoryloader.parse.frame.badformat",
  358. child, "Too many colors for a general mesh factory!");
  359. return 0;
  360. }
  361. float r, g, b;
  362. r = child->GetAttributeValueAsFloat ("red");
  363. g = child->GetAttributeValueAsFloat ("green");
  364. b = child->GetAttributeValueAsFloat ("blue");
  365. co[num_col].Set (r, g, b);
  366. num_col++;
  367. }
  368. break;
  369. case XMLTOKEN_V:
  370. {
  371. csVector3* vt = state->GetVertices ();
  372. csVector2* te = state->GetTexels ();
  373. if (num_vt >= state->GetVertexCount ())
  374. {
  375. synldr->ReportError (
  376. "crystalspace.genmeshfactoryloader.parse.frame.badformat",
  377. child, "Too many vertices for a general mesh factory!");
  378. return 0;
  379. }
  380. float x, y, z, u, v;
  381. x = child->GetAttributeValueAsFloat ("x");
  382. y = child->GetAttributeValueAsFloat ("y");
  383. z = child->GetAttributeValueAsFloat ("z");
  384. u = child->GetAttributeValueAsFloat ("u");
  385. v = child->GetAttributeValueAsFloat ("v");
  386. vt[num_vt].Set (x, y, z);
  387. te[num_vt].Set (u, v);
  388. num_vt++;
  389. }
  390. break;
  391. default:
  392. synldr->ReportBadToken (child);
  393. return 0;
  394. }
  395. }
  396. if (auto_normals)
  397. state->CalculateNormals ();
  398. return csPtr<iBase> (fact);
  399. }
  400. //---------------------------------------------------------------------------
  401. csGeneralFactorySaver::csGeneralFactorySaver (iBase* pParent)
  402. {
  403. SCF_CONSTRUCT_IBASE (pParent);
  404. SCF_CONSTRUCT_EMBEDDED_IBASE(scfiComponent);
  405. }
  406. csGeneralFactorySaver::~csGeneralFactorySaver ()
  407. {
  408. }
  409. bool csGeneralFactorySaver::Initialize (iObjectRegistry* object_reg)
  410. {
  411. csGeneralFactorySaver::object_reg = object_reg;
  412. reporter = CS_QUERY_REGISTRY (object_reg, iReporter);
  413. return true;
  414. }
  415. #define MAXLINE 100 /* max number of chars per line... */
  416. void csGeneralFactorySaver::WriteDown (iBase* /*obj*/, iFile * /*file*/)
  417. {
  418. // no params
  419. // @@@ NOT IMPLEMENTED!
  420. }
  421. //---------------------------------------------------------------------------
  422. csGeneralMeshLoader::csGeneralMeshLoader (iBase* pParent)
  423. {
  424. SCF_CONSTRUCT_IBASE (pParent);
  425. SCF_CONSTRUCT_EMBEDDED_IBASE(scfiComponent);
  426. }
  427. csGeneralMeshLoader::~csGeneralMeshLoader ()
  428. {
  429. }
  430. bool csGeneralMeshLoader::Initialize (iObjectRegistry* object_reg)
  431. {
  432. csGeneralMeshLoader::object_reg = object_reg;
  433. reporter = CS_QUERY_REGISTRY (object_reg, iReporter);
  434. synldr = CS_QUERY_REGISTRY (object_reg, iSyntaxService);
  435. xmltokens.Register ("material", XMLTOKEN_MATERIAL);
  436. xmltokens.Register ("factory", XMLTOKEN_FACTORY);
  437. xmltokens.Register ("mixmode", XMLTOKEN_MIXMODE);
  438. xmltokens.Register ("manualcolors", XMLTOKEN_MANUALCOLORS);
  439. xmltokens.Register ("color", XMLTOKEN_COLOR);
  440. xmltokens.Register ("lighting", XMLTOKEN_LIGHTING);
  441. xmltokens.Register ("noshadows", XMLTOKEN_NOSHADOWS);
  442. xmltokens.Register ("localshadows", XMLTOKEN_LOCALSHADOWS);
  443. return true;
  444. }
  445. csPtr<iBase> csGeneralMeshLoader::Parse (iDocumentNode* node,
  446. iLoaderContext* ldr_context, iBase*)
  447. {
  448. csRef<iMeshObject> mesh;
  449. csRef<iGeneralMeshState> meshstate;
  450. csRef<iDocumentNodeIterator> it = node->GetNodes ();
  451. while (it->HasNext ())
  452. {
  453. csRef<iDocumentNode> child = it->Next ();
  454. if (child->GetType () != CS_NODE_ELEMENT) continue;
  455. const char* value = child->GetValue ();
  456. csStringID id = xmltokens.Request (value);
  457. switch (id)
  458. {
  459. case XMLTOKEN_MANUALCOLORS:
  460. {
  461. bool r;
  462. if (!synldr->ParseBool (child, r, true))
  463. return 0;
  464. meshstate->SetManualColors (r);
  465. }
  466. break;
  467. case XMLTOKEN_NOSHADOWS:
  468. {
  469. meshstate->SetShadowCasting (false);
  470. }
  471. break;
  472. case XMLTOKEN_LOCALSHADOWS:
  473. {
  474. meshstate->SetShadowReceiving (true);
  475. }
  476. break;
  477. case XMLTOKEN_LIGHTING:
  478. {
  479. bool r;
  480. if (!synldr->ParseBool (child, r, true))
  481. return 0;
  482. meshstate->SetLighting (r);
  483. }
  484. break;
  485. case XMLTOKEN_COLOR:
  486. {
  487. csColor col;
  488. if (!synldr->ParseColor (child, col))
  489. return 0;
  490. meshstate->SetColor (col);
  491. }
  492. break;
  493. case XMLTOKEN_FACTORY:
  494. {
  495. const char* factname = child->GetContentsValue ();
  496. iMeshFactoryWrapper* fact = ldr_context->FindMeshFactory (factname);
  497. if (!fact)
  498. {
  499. synldr->ReportError (
  500. "crystalspace.genmeshloader.parse.unknownfactory",
  501. child, "Couldn't find factory '%s'!", factname);
  502. return 0;
  503. }
  504. mesh = fact->GetMeshObjectFactory ()->NewInstance ();
  505. meshstate = SCF_QUERY_INTERFACE (mesh, iGeneralMeshState);
  506. }
  507. break;
  508. case XMLTOKEN_MATERIAL:
  509. {
  510. const char* matname = child->GetContentsValue ();
  511. iMaterialWrapper* mat = ldr_context->FindMaterial (matname);
  512. if (!mat)
  513. {
  514. synldr->ReportError (
  515. "crystalspace.genmeshloader.parse.unknownmaterial",
  516. child, "Couldn't find material '%s'!", matname);
  517. return 0;
  518. }
  519. meshstate->SetMaterialWrapper (mat);
  520. }
  521. break;
  522. case XMLTOKEN_MIXMODE:
  523. {
  524. uint mm;
  525. if (!synldr->ParseMixmode (child, mm))
  526. return 0;
  527. meshstate->SetMixMode (mm);
  528. }
  529. break;
  530. default:
  531. synldr->ReportBadToken (child);
  532. return 0;
  533. }
  534. }
  535. return csPtr<iBase> (mesh);
  536. }
  537. //---------------------------------------------------------------------------
  538. csGeneralMeshSaver::csGeneralMeshSaver (iBase* pParent)
  539. {
  540. SCF_CONSTRUCT_IBASE (pParent);
  541. SCF_CONSTRUCT_EMBEDDED_IBASE(scfiComponent);
  542. }
  543. csGeneralMeshSaver::~csGeneralMeshSaver ()
  544. {
  545. }
  546. bool csGeneralMeshSaver::Initialize (iObjectRegistry* object_reg)
  547. {
  548. csGeneralMeshSaver::object_reg = object_reg;
  549. reporter = CS_QUERY_REGISTRY (object_reg, iReporter);
  550. synldr = CS_QUERY_REGISTRY (object_reg, iSyntaxService);
  551. return true;
  552. }
  553. void csGeneralMeshSaver::WriteDown (iBase*, iFile*)
  554. {
  555. }