Simple game engine with complete export to scripting language
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

MeshManager.cpp 14KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494
  1. #include "MeshManager.h"
  2. #include "Utilities/format.h"
  3. #include "Utilities/Log.h"
  4. #include "physfs.h"
  5. #include "trimeshloader.h"
  6. #include <iostream>
  7. #include <vector>
  8. using namespace std;
  9. namespace BlueCore
  10. {
  11. Mesh::Mesh(RenderDevice* device) :
  12. _Device(device)
  13. {
  14. }
  15. Mesh::~Mesh()
  16. {
  17. clog << ">>> Mesh destructed ..."<< endline;
  18. }
  19. void Mesh::render()
  20. {
  21. glEnableClientState(GL_VERTEX_ARRAY);
  22. glEnableClientState(GL_TEXTURE_COORD_ARRAY);
  23. glEnableClientState(GL_NORMAL_ARRAY);
  24. glVertexPointer( 3, GL_FLOAT, sizeof(Vertex), &VertexBuffer[0].point.x);
  25. glTexCoordPointer( 2, GL_FLOAT, sizeof(Vertex), &VertexBuffer[0].u);
  26. glNormalPointer(GL_FLOAT, sizeof(Vertex), &VertexBuffer[0].normal.x);
  27. glDrawElements(GL_TRIANGLES, IndexBuffer.count() * 3, GL_UNSIGNED_SHORT,
  28. IndexBuffer.data() );
  29. glDisableClientState(GL_VERTEX_ARRAY);
  30. glDisableClientState(GL_TEXTURE_COORD_ARRAY);
  31. glDisableClientState(GL_NORMAL_ARRAY);
  32. }
  33. #if 0
  34. //--------------------------------------------------------------------------
  35. void Mesh::createVBO()
  36. {
  37. if ( GLEW_ARB_vertex_buffer_object && !vbo )
  38. {
  39. glGenBuffersARB ( 1, &vbo );
  40. glBindBufferARB ( GL_ARRAY_BUFFER_ARB, vbo );
  41. glBufferDataARB (
  42. GL_ARRAY_BUFFER_ARB,
  43. size(),
  44. data(),
  45. GL_STATIC_DRAW_ARB );
  46. }
  47. }
  48. //--------------------------------------------------------------------------
  49. void Mesh::releaseVBO()
  50. {
  51. if ( GLEW_ARB_vertex_buffer_object && vbo )
  52. {
  53. glDeleteBuffersARB ( 1, &vbo );
  54. vbo = 0;
  55. }
  56. }
  57. //--------------------------------------------------------------------------
  58. void Mesh::bind()
  59. {
  60. if ( GLEW_ARB_vertex_buffer_object && vbo )
  61. {
  62. glBindBufferARB ( GL_ARRAY_BUFFER_ARB, vbo );
  63. // hardcoded offset and stride
  64. glVertexPointer ( 3, GL_FLOAT, sizeof ( Vertex ), 0 );
  65. glTexCoordPointer ( 2, GL_FLOAT, sizeof ( Vertex ), ( const GLvoid* ) ( sizeof ( float ) * 3 ) );
  66. glNormalPointer ( GL_FLOAT, sizeof ( Vertex ), ( const GLvoid* ) ( sizeof ( float ) * 5 ) );
  67. }
  68. else
  69. {
  70. // hardcoded offset and stride
  71. glVertexPointer ( 3, GL_FLOAT, sizeof ( Vertex ), data() );
  72. glTexCoordPointer ( 2, GL_FLOAT, sizeof ( Vertex ), data() + sizeof ( float ) * 3 );
  73. glNormalPointer ( GL_FLOAT, sizeof ( Vertex ), data() + sizeof ( float ) * 5 );
  74. }
  75. }
  76. #endif
  77. MeshManager::MeshManager(RenderDevice* device) :
  78. _Device(device)
  79. {
  80. BlueCore::clog << ">>> MeshManager constructed..." << endlog;
  81. }
  82. MeshManager::~MeshManager()
  83. {
  84. clog << ">>> MeshManager destructed ..." << endlog;
  85. }
  86. bool loadTrimesh(const char* filename, Mesh *mesh)
  87. {
  88. PHYSFS_file* file = PHYSFS_openRead(filename);
  89. if (file != 0)
  90. {
  91. char buffer[1024];
  92. unsigned int size = 0;
  93. if (tlObjCheckFileExtension(filename) == 0)
  94. {
  95. tlObjState *state = tlObjCreateState();
  96. while (PHYSFS_eof(file) == 0)
  97. {
  98. size = (unsigned int) PHYSFS_read(file, buffer, 1,
  99. sizeof(buffer));
  100. tlObjParse(state, buffer, size, size < sizeof(buffer) ? 1 : 0);
  101. }
  102. mesh->VertexBuffer.create(tlObjVertexCount(state));
  103. for (unsigned int i = 0; i < mesh->VertexBuffer.count(); i++)
  104. tlObjGetVertex(state, i, &mesh->VertexBuffer[i].point.x,
  105. &mesh->VertexBuffer[i].point.y,
  106. &mesh->VertexBuffer[i].point.z,
  107. &mesh->VertexBuffer[i].u, &mesh->VertexBuffer[i].v,
  108. &mesh->VertexBuffer[i].normal.x,
  109. &mesh->VertexBuffer[i].normal.y,
  110. &mesh->VertexBuffer[i].normal.z);
  111. mesh->IndexBuffer.create(tlObjFaceCount(state));
  112. for (unsigned int i = 0; i < mesh->IndexBuffer.count(); i++)
  113. tlObjGetFace(state, i, &mesh->IndexBuffer[i].a,
  114. &mesh->IndexBuffer[i].b, &mesh->IndexBuffer[i].c);
  115. mesh->SubsetBuffer.create(tlObjObjectCount(state));
  116. for (unsigned int i = 0; i < mesh->SubsetBuffer.count(); i++)
  117. {
  118. mesh->SubsetBuffer[i].first = tlObjObjectFaceIndex(state, i);
  119. mesh->SubsetBuffer[i].count = tlObjObjectFaceCount(state, i);
  120. }
  121. tlObjDestroyState(state);
  122. }
  123. else if (tl3dsCheckFileExtension(filename) == 0)
  124. {
  125. tl3dsState *state = tl3dsCreateState();
  126. while (PHYSFS_eof(file) == 0)
  127. {
  128. size = (unsigned int) PHYSFS_read(file, buffer, 1,
  129. sizeof(buffer));
  130. tl3dsParse(state, buffer, size, size < sizeof(buffer) ? 1 : 0);
  131. }
  132. mesh->VertexBuffer.create(tl3dsVertexCount(state));
  133. for (unsigned int i = 0; i < mesh->VertexBuffer.count(); i++)
  134. tl3dsGetVertex(state, i, &mesh->VertexBuffer[i].point.x,
  135. &mesh->VertexBuffer[i].point.y,
  136. &mesh->VertexBuffer[i].point.z,
  137. &mesh->VertexBuffer[i].u, &mesh->VertexBuffer[i].v,
  138. &mesh->VertexBuffer[i].normal.x,
  139. &mesh->VertexBuffer[i].normal.y,
  140. &mesh->VertexBuffer[i].normal.z);
  141. mesh->IndexBuffer.create(tl3dsFaceCount(state));
  142. for (unsigned int i = 0; i < mesh->IndexBuffer.count(); i++)
  143. tl3dsGetFace(state, i, &mesh->IndexBuffer[i].a,
  144. &mesh->IndexBuffer[i].b, &mesh->IndexBuffer[i].c);
  145. mesh->SubsetBuffer.create(tl3dsObjectCount(state));
  146. for (unsigned int i = 0; i < mesh->SubsetBuffer.count(); i++)
  147. {
  148. mesh->SubsetBuffer[i].first = tl3dsObjectFaceIndex(state, i);
  149. mesh->SubsetBuffer[i].count = tl3dsObjectFaceCount(state, i);
  150. }
  151. tl3dsDestroyState(state);
  152. }
  153. PHYSFS_close(file);
  154. // create normlas, tangents, and binomials
  155. clog << " create normlas..." << endline;
  156. for (unsigned int i = 0; i < mesh->VertexBuffer.count(); i++)
  157. {
  158. mesh->VertexBuffer[i].normal.zero();
  159. }
  160. for (unsigned int i = 0; i < mesh->IndexBuffer.count(); i++)
  161. {
  162. const TriangleIndices& triangle = mesh->IndexBuffer[i];
  163. Vector3Template<float> ab = mesh->VertexBuffer[ triangle.a ].point
  164. - mesh->VertexBuffer[ triangle.b ].point;
  165. Vector3Template<float> ac = mesh->VertexBuffer[ triangle.a ].point
  166. - mesh->VertexBuffer[ triangle.c ].point;
  167. Vector3Template<float> n = ab.cross(ac);
  168. mesh->VertexBuffer[ triangle.a ].normal += n;
  169. mesh->VertexBuffer[ triangle.a ].normal += n;
  170. mesh->VertexBuffer[ triangle.a ].normal += n;
  171. }
  172. for (unsigned int i = 0; i < mesh->VertexBuffer.count(); i ++)
  173. {
  174. mesh->VertexBuffer[i].normal.normalize();
  175. }
  176. clog << " create tangents..." << endline;
  177. mesh->TangentBuffer.create(mesh->VertexBuffer.count());
  178. mesh->BitangentBuffer.create(mesh->VertexBuffer.count());
  179. for (unsigned int i = 0; i < mesh->TangentBuffer.count(); i ++)
  180. {
  181. mesh->TangentBuffer[i].zero();
  182. mesh->BitangentBuffer[i].zero();
  183. }
  184. for (unsigned int i = 0; i < mesh->IndexBuffer.count(); i ++)
  185. {
  186. const TriangleIndices& triangle = mesh->IndexBuffer[i];
  187. const Vertex& v1 = mesh->VertexBuffer[triangle.a];
  188. const Vertex& v2 = mesh->VertexBuffer[triangle.b];
  189. const Vertex& v3 = mesh->VertexBuffer[triangle.c];
  190. float x1 = v2.point.x - v1.point.x;
  191. float x2 = v3.point.x - v1.point.x;
  192. float y1 = v2.point.y - v1.point.y;
  193. float y2 = v3.point.y - v1.point.y;
  194. float z1 = v2.point.z - v1.point.z;
  195. float z2 = v3.point.z - v1.point.z;
  196. float s1 = v2.u - v1.u;
  197. float s2 = v3.u - v1.u;
  198. float t1 = v2.v - v1.v;
  199. float t2 = v3.v - v1.v;
  200. float r = 1.0f / (s1 * t2 - s2 * t1 );
  201. Vector3Float sdir( (t2 * x1 - t1 * x2 ) * r, (t2 * y1 - t1 * y2 )
  202. * r, (t2 * z1 - t1 * z2 ) * r);
  203. Vector3Float tdir( (s1 * x2 - s2 * x1 ) * r, (s1 * y2 - s2 * y1 )
  204. * r, (s1 * z2 - s2 * z1 ) * r);
  205. mesh->TangentBuffer[triangle.a] += sdir;
  206. mesh->TangentBuffer[triangle.b] += sdir;
  207. mesh->TangentBuffer[triangle.c] += sdir;
  208. mesh->BitangentBuffer[triangle.a] += tdir;
  209. mesh->BitangentBuffer[triangle.b] += tdir;
  210. mesh->BitangentBuffer[triangle.c] += tdir;
  211. }
  212. for (unsigned int i = 0; i < mesh->TangentBuffer.count(); i ++)
  213. {
  214. mesh->TangentBuffer[i].normalize();
  215. mesh->BitangentBuffer[i].normalize();
  216. }
  217. return 0;
  218. }
  219. return 1;
  220. }
  221. Mesh *MeshManager::loadMesh(const string &filename)
  222. {
  223. // check if this mesh is already loaded
  224. std::map<std::string, weak_ptr<Mesh> >::const_iterator result;
  225. result = _Meshes.find(filename);
  226. if (result != _Meshes.end() && result->second.valid())
  227. {
  228. return result->second.pointer();
  229. }
  230. Mesh *mesh = new Mesh (_Device);
  231. // check cache
  232. PHYSFS_sint64 mod_file = PHYSFS_getLastModTime(filename.c_str());
  233. std::string cachename = filename + ".msc";
  234. PHYSFS_sint64 mod_cache = PHYSFS_getLastModTime(cachename.c_str());
  235. if ( (mod_cache > mod_file) && loadFromCache(mesh, filename) )
  236. {
  237. clog << ">>> Mesh '" << filename << "' loaded from cache." << endline;
  238. _Meshes[filename] = mesh;
  239. return mesh;
  240. }
  241. clog << ">>> Mesh '" << filename << "': loading from file..." << endlog;
  242. if (loadTrimesh(filename.c_str(), mesh) != 0)
  243. {
  244. mesh->removeReference();
  245. clog << "!!! Mesh not found!" << endline;
  246. return 0;
  247. }
  248. #if 0
  249. mesh->buildShadowFaceBuffer();
  250. mesh->buildTangentBuffer();
  251. unsigned int counter;
  252. // calculate bounding sphere
  253. clog << " calculate bounding sphere";
  254. mesh->bounding_sphere.center().zero();
  255. for ( counter = 0; counter < mesh->vertex_buffer.count(); counter++ )
  256. {
  257. mesh->bounding_sphere.center() += mesh->vertex_buffer[counter].point;
  258. }
  259. mesh->bounding_sphere.center() /= mesh->vertex_buffer.size();
  260. mesh->bounding_sphere.radius() = 0.;
  261. for ( counter = 0; counter < mesh->vertex_buffer.count(); counter++ )
  262. {
  263. Scalar distance = ( mesh->vertex_buffer[counter].point - mesh->bounding_sphere.center() ).length();
  264. if ( distance > mesh->bounding_sphere.radius() )
  265. mesh->bounding_sphere.radius() = distance;
  266. }
  267. clog << ": " << mesh->bounding_sphere.radius() << endline;
  268. // create normlas, tangents, and binomials
  269. clog << " create normlas, tangents, and binomials" << endline;
  270. for ( counter = 0; counter < mesh->vertex_buffer.count(); counter += 1 )
  271. {
  272. mesh->vertex_buffer[counter].normal.zero();
  273. }
  274. for ( counter = 0; counter < mesh->index_buffer.count(); counter += 3 )
  275. {
  276. Index a = mesh->index_buffer[counter];
  277. Index b = mesh->index_buffer[counter+1];
  278. Index c = mesh->index_buffer[counter+2];
  279. Vector3Template<float> ab = mesh->vertex_buffer[ a ].point - mesh->vertex_buffer[ b ].point;
  280. Vector3Template<float> ac = mesh->vertex_buffer[ a ].point - mesh->vertex_buffer[ c ].point;
  281. Vector3Template<float> n = ab.cross ( ac );
  282. mesh->vertex_buffer[ a ].normal += n;
  283. mesh->vertex_buffer[ b ].normal += n;
  284. mesh->vertex_buffer[ c ].normal += n;
  285. }
  286. for ( counter = 0; counter < mesh->vertex_buffer.count(); counter += 1 )
  287. {
  288. mesh->vertex_buffer[counter].normal.normalize();
  289. }
  290. clog << " create vbos" << endline;
  291. mesh->vertex_buffer.createVBO();
  292. mesh->index_buffer.createVBO();
  293. mesh->tangent_buffer.createVBO();
  294. mesh->bitangent_buffer.createVBO();
  295. #endif
  296. _Meshes[filename] = mesh;
  297. saveToCache(mesh, filename);
  298. return mesh;
  299. }
  300. bool MeshManager::loadFromCache(Mesh *mesh, const std::string &name)
  301. {
  302. std::string filename = name + ".msc";
  303. PHYSFS_file *file = PHYSFS_openRead(filename.c_str());
  304. if (file == 0)
  305. return false;
  306. unsigned int size;
  307. // read vertex_buffer
  308. PHYSFS_read(file, &size, sizeof (size ), 1);
  309. mesh->VertexBuffer.create(size);
  310. PHYSFS_read(file, mesh->VertexBuffer.data(), mesh->VertexBuffer.size(), 1);
  311. // read index buffer
  312. PHYSFS_read(file, &size, sizeof (size ), 1);
  313. mesh->IndexBuffer.create(size);
  314. PHYSFS_read(file, mesh->IndexBuffer.data(), mesh->IndexBuffer.size(), 1);
  315. // read subsets
  316. PHYSFS_read(file, &size, sizeof (size ), 1);
  317. mesh->SubsetBuffer.create(size);
  318. PHYSFS_read(file, mesh->SubsetBuffer.data(), mesh->SubsetBuffer.size(), 1);
  319. // read tangent buffer
  320. PHYSFS_read(file, &size, sizeof (size ), 1);
  321. mesh->TangentBuffer.create(size);
  322. PHYSFS_read(file, mesh->TangentBuffer.data(), mesh->TangentBuffer.size(), 1);
  323. // read bitangent buffer
  324. PHYSFS_read(file, &size, sizeof (size ), 1);
  325. mesh->BitangentBuffer.create(size);
  326. PHYSFS_read(file, mesh->BitangentBuffer.data(),
  327. mesh->BitangentBuffer.size(), 1);
  328. #if 0
  329. // read bounding sphere
  330. PHYSFS_read ( file, &mesh->bounding_sphere, sizeof ( mesh->bounding_sphere ), 1 );
  331. #endif
  332. #if 0
  333. // read bitangent buffer
  334. PHYSFS_read ( file, &size, sizeof ( size ), 1 );
  335. mesh->shadowface_buffer.create ( size );
  336. PHYSFS_read ( file, mesh->shadowface_buffer.data(), mesh->shadowface_buffer.size(), 1 );
  337. #endif
  338. PHYSFS_close(file);
  339. return true;
  340. }
  341. bool MeshManager::saveToCache(Mesh *mesh, const std::string &name)
  342. {
  343. std::string filename = name + ".msc";
  344. PHYSFS_file *file = PHYSFS_openWrite(filename.c_str() );
  345. if (file == 0)
  346. {
  347. clog << ">>> cannot open cache file for mesh: " << name << endline;
  348. return false;
  349. }
  350. // write vertex_buffer
  351. unsigned int size = mesh->VertexBuffer.count();
  352. PHYSFS_write(file, &size, sizeof (size ), 1);
  353. PHYSFS_write(file, mesh->VertexBuffer.data(), mesh->VertexBuffer.size(), 1);
  354. // write index_buffer
  355. size = mesh->IndexBuffer.count();
  356. PHYSFS_write(file, &size, sizeof (size ), 1);
  357. PHYSFS_write(file, mesh->IndexBuffer.data(), mesh->IndexBuffer.size(), 1);
  358. // write subsets
  359. size = mesh->SubsetBuffer.count();
  360. PHYSFS_write(file, &size, sizeof (size ), 1);
  361. PHYSFS_write(file, mesh->SubsetBuffer.data(), mesh->SubsetBuffer.size(), 1);
  362. // write tangent_buffer
  363. size = mesh->TangentBuffer.count();
  364. PHYSFS_write(file, &size, sizeof (size ), 1);
  365. PHYSFS_write(file, mesh->TangentBuffer.data(), mesh->TangentBuffer.size(),
  366. 1);
  367. // write bitangent_buffer
  368. size = mesh->BitangentBuffer.count();
  369. PHYSFS_write(file, &size, sizeof (size ), 1);
  370. PHYSFS_write(file, mesh->BitangentBuffer.data(),
  371. mesh->BitangentBuffer.size(), 1);
  372. #if 0
  373. // write bounding sphere
  374. PHYSFS_write ( file, &mesh->bounding_sphere, sizeof ( mesh->bounding_sphere ), 1 );
  375. // write shadowfaces
  376. size = mesh->shadowface_buffer.count();
  377. PHYSFS_write ( file, &size, sizeof ( size ), 1 );
  378. PHYSFS_write ( file, mesh->shadowface_buffer.data(), mesh->shadowface_buffer.size(), 1 );
  379. #endif
  380. PHYSFS_close(file);
  381. return true;
  382. }
  383. } // namespace BlueCore