PolyMesh.cpp 41 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324
  1. /*
  2. Copyright (C) 2011 by Ivan Safrin
  3. Permission is hereby granted, free of charge, to any person obtaining a copy
  4. of this software and associated documentation files (the "Software"), to deal
  5. in the Software without restriction, including without limitation the rights
  6. to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  7. copies of the Software, and to permit persons to whom the Software is
  8. furnished to do so, subject to the following conditions:
  9. The above copyright notice and this permission notice shall be included in
  10. all copies or substantial portions of the Software.
  11. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  12. IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  13. FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  14. AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  15. LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  16. OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
  17. THE SOFTWARE.
  18. */
  19. #include <map>
  20. #include "PolyMesh.h"
  21. #include "PolyLogger.h"
  22. #include "OSBasics.h"
  23. using std::min;
  24. using std::max;
  25. using std::vector;
  26. using namespace Polycode;
  27. Mesh::Mesh(const String& fileName)
  28. : vertexPositionArray(RenderDataArray::VERTEX_DATA_ARRAY),
  29. vertexColorArray(RenderDataArray::COLOR_DATA_ARRAY),
  30. vertexNormalArray(RenderDataArray::NORMAL_DATA_ARRAY),
  31. vertexTexCoordArray(RenderDataArray::TEXCOORD_DATA_ARRAY),
  32. vertexTexCoord2Array(RenderDataArray::TEXCOORD2_DATA_ARRAY),
  33. vertexTangentArray(RenderDataArray::TANGENT_DATA_ARRAY),
  34. vertexBoneWeightArray(RenderDataArray::BONE_WEIGHT_DATA_ARRAY),
  35. vertexBoneIndexArray(RenderDataArray::BONE_INDEX_DATA_ARRAY),
  36. indexArray(RenderDataArray::INDEX_DATA_ARRAY)
  37. {
  38. indexedMesh = false;
  39. meshType = TRI_MESH;
  40. meshHasVertexBuffer = false;
  41. vertexBuffer = NULL;
  42. loadMesh(fileName);
  43. useVertexColors = false;
  44. }
  45. Mesh::Mesh(int meshType)
  46. : vertexPositionArray(RenderDataArray::VERTEX_DATA_ARRAY),
  47. vertexColorArray(RenderDataArray::COLOR_DATA_ARRAY),
  48. vertexNormalArray(RenderDataArray::NORMAL_DATA_ARRAY),
  49. vertexTexCoordArray(RenderDataArray::TEXCOORD_DATA_ARRAY),
  50. vertexTexCoord2Array(RenderDataArray::TEXCOORD2_DATA_ARRAY),
  51. vertexTangentArray(RenderDataArray::TANGENT_DATA_ARRAY),
  52. vertexBoneWeightArray(RenderDataArray::BONE_WEIGHT_DATA_ARRAY),
  53. vertexBoneIndexArray(RenderDataArray::BONE_INDEX_DATA_ARRAY),
  54. indexArray(RenderDataArray::INDEX_DATA_ARRAY)
  55. {
  56. this->meshType = meshType;
  57. meshHasVertexBuffer = false;
  58. vertexBuffer = NULL;
  59. useVertexColors = false;
  60. indexedMesh = false;
  61. }
  62. Mesh *Mesh::MeshFromFileName(String& fileName) {
  63. return new Mesh(fileName);
  64. }
  65. Mesh::~Mesh() {
  66. clearMesh();
  67. }
  68. void Mesh::clearMesh() {
  69. if(vertexBuffer)
  70. delete vertexBuffer;
  71. vertexBuffer = NULL;
  72. vertexPositionArray.data.clear();
  73. vertexColorArray.data.clear();
  74. vertexNormalArray.data.clear();
  75. vertexTexCoordArray.data.clear();
  76. vertexTexCoord2Array.data.clear();
  77. vertexTangentArray.data.clear();
  78. indexArray.data.clear();
  79. vertexBoneWeightArray.data.clear();
  80. vertexBoneIndexArray.data.clear();
  81. meshHasVertexBuffer = false;
  82. }
  83. VertexBuffer *Mesh::getVertexBuffer() {
  84. return vertexBuffer;
  85. }
  86. void Mesh::setVertexBuffer(VertexBuffer *buffer) {
  87. if(vertexBuffer) {
  88. delete vertexBuffer;
  89. }
  90. vertexBuffer = buffer;
  91. meshHasVertexBuffer = true;
  92. }
  93. Number Mesh::getRadius() {
  94. Number hRad = 0;
  95. Number len;
  96. for(int i=0; i < vertexPositionArray.data.size()-2; i += 3) {
  97. Vector3 vec;
  98. len = vec.length();
  99. if(len > hRad) {
  100. hRad = len;
  101. }
  102. }
  103. return hRad;
  104. }
  105. void Mesh::writeVertexBlock(VertexDataArray *array, OSFILE *outFile) {
  106. if(array->getDataSize() == 0) {
  107. return;
  108. }
  109. unsigned char blockType = array->type;
  110. unsigned int blockCount = array->getDataSize();
  111. OSBasics::write(&blockType, sizeof(unsigned char), 1, outFile);
  112. OSBasics::write(&blockCount, sizeof(unsigned int), 1, outFile);
  113. OSBasics::write(array->getArrayData(), sizeof(PolyRendererVertexType), array->getDataSize(), outFile);
  114. }
  115. void Mesh::writeIndexBlock(IndexDataArray *array, OSFILE *outFile) {
  116. if(array->getDataSize() == 0) {
  117. return;
  118. }
  119. unsigned char blockType = array->type;
  120. unsigned int blockCount = array->getDataSize();
  121. OSBasics::write(&blockType, sizeof(unsigned char), 1, outFile);
  122. OSBasics::write(&blockCount, sizeof(unsigned int), 1, outFile);
  123. OSBasics::write(array->getArrayData(), sizeof(PolyRendererIndexType), array->getDataSize(), outFile);
  124. }
  125. void Mesh::saveToFile(OSFILE *outFile, bool writeNormals, bool writeTangents, bool writeColors, bool writeBoneWeights, bool writeUVs, bool writeSecondaryUVs) {
  126. // new mesh format
  127. // IMPORTANT: PolyRendererVertexType type defines mesh format internal type. Consider making floats always. Don't want to cast for now.
  128. const char headerTag[] = "MSH2";
  129. OSBasics::write(headerTag, 1, 4, outFile);
  130. unsigned char meshFlags = 0;
  131. if(indexedMesh) {
  132. meshFlags |= 1 << 0;
  133. }
  134. OSBasics::write(&meshFlags, sizeof(unsigned char), 1, outFile);
  135. writeVertexBlock(&vertexPositionArray, outFile);
  136. if(indexedMesh) {
  137. writeIndexBlock(&indexArray, outFile);
  138. }
  139. if(writeColors) {
  140. writeVertexBlock(&vertexColorArray, outFile);
  141. }
  142. if(writeNormals) {
  143. writeVertexBlock(&vertexNormalArray, outFile);
  144. }
  145. if(writeUVs) {
  146. writeVertexBlock(&vertexTexCoordArray, outFile);
  147. }
  148. if(writeSecondaryUVs) {
  149. writeVertexBlock(&vertexTexCoord2Array, outFile);
  150. }
  151. if(writeTangents) {
  152. writeVertexBlock(&vertexTangentArray, outFile);
  153. }
  154. if(writeBoneWeights) {
  155. writeVertexBlock(&vertexBoneWeightArray, outFile);
  156. writeIndexBlock(&vertexBoneIndexArray, outFile);
  157. }
  158. }
  159. void Mesh::loadFromFile(OSFILE *inFile) {
  160. clearMesh();
  161. char tag[4];
  162. OSBasics::read(tag, 1, 4, inFile);
  163. if(tag[0] == 'M' && tag[1] == 'S' && tag[2] == 'H' && tag[3] == '2') {
  164. loadFromFileV2(inFile);
  165. } else {
  166. OSBasics::seek(inFile, 0, SEEK_SET);
  167. loadFromFileLegacyV1(inFile);
  168. }
  169. }
  170. void Mesh::loadFromFileV2(OSFILE *inFile) {
  171. unsigned char meshFlags;
  172. OSBasics::read(&meshFlags, sizeof(unsigned char), 1, inFile);
  173. indexedMesh = meshFlags & (1 << 0);
  174. char blockType;
  175. unsigned int blockSize;
  176. while(OSBasics::read(&blockType, sizeof(unsigned char), 1, inFile)) {
  177. OSBasics::read(&blockSize, sizeof(unsigned int), 1, inFile);
  178. switch(blockType) {
  179. case RenderDataArray::VERTEX_DATA_ARRAY:
  180. vertexPositionArray.data.resize(blockSize);
  181. OSBasics::read(&vertexPositionArray.data[0], sizeof(PolyRendererVertexType), blockSize, inFile);
  182. break;
  183. case RenderDataArray::TEXCOORD_DATA_ARRAY:
  184. vertexTexCoordArray.data.resize(blockSize);
  185. OSBasics::read(&vertexTexCoordArray.data[0], sizeof(PolyRendererVertexType), blockSize, inFile);
  186. break;
  187. case RenderDataArray::NORMAL_DATA_ARRAY:
  188. vertexNormalArray.data.resize(blockSize);
  189. OSBasics::read(&vertexNormalArray.data[0], sizeof(PolyRendererVertexType), blockSize, inFile);
  190. break;
  191. case RenderDataArray::COLOR_DATA_ARRAY:
  192. vertexColorArray.data.resize(blockSize);
  193. OSBasics::read(&vertexColorArray.data[0], sizeof(PolyRendererVertexType), blockSize, inFile);
  194. break;
  195. case RenderDataArray::TANGENT_DATA_ARRAY:
  196. vertexTangentArray.data.resize(blockSize);
  197. OSBasics::read(&vertexTangentArray.data[0], sizeof(PolyRendererVertexType), blockSize, inFile);
  198. break;
  199. case RenderDataArray::BONE_WEIGHT_DATA_ARRAY:
  200. vertexBoneWeightArray.data.resize(blockSize);
  201. OSBasics::read(&vertexBoneWeightArray.data[0], sizeof(PolyRendererVertexType), blockSize, inFile);
  202. break;
  203. case RenderDataArray::INDEX_DATA_ARRAY:
  204. indexArray.data.resize(blockSize);
  205. OSBasics::read(&indexArray.data[0], sizeof(PolyRendererIndexType), blockSize, inFile);
  206. break;
  207. case RenderDataArray::BONE_INDEX_DATA_ARRAY:
  208. vertexBoneIndexArray.data.resize(blockSize);
  209. OSBasics::read(&vertexBoneIndexArray.data[0], sizeof(PolyRendererIndexType), blockSize, inFile);
  210. break;
  211. }
  212. }
  213. if(vertexBoneIndexArray.getDataSize() > 0) {
  214. normalizeBoneWeights();
  215. }
  216. }
  217. void Mesh::normalizeBoneWeights() {
  218. for(int i=0; i < vertexBoneWeightArray.getDataSize()-3; i += 4) {
  219. Number totalWeight = vertexBoneWeightArray.data[i] + vertexBoneWeightArray.data[i+1] + vertexBoneWeightArray.data[i+2] + vertexBoneWeightArray.data[i+3];
  220. if(totalWeight != 0.0) {
  221. vertexBoneWeightArray.data[i] = vertexBoneWeightArray.data[i] / totalWeight;
  222. vertexBoneWeightArray.data[i+1] = vertexBoneWeightArray.data[i+1] / totalWeight;
  223. vertexBoneWeightArray.data[i+2] = vertexBoneWeightArray.data[i+2] / totalWeight;
  224. vertexBoneWeightArray.data[i+3] = vertexBoneWeightArray.data[i+3] / totalWeight;
  225. }
  226. }
  227. }
  228. void Mesh::loadFromFileLegacyV1(OSFILE *inFile) {
  229. unsigned char meshFlags;
  230. OSBasics::read(&meshFlags, sizeof(unsigned char), 1, inFile);
  231. indexedMesh = meshFlags & (1 << 0);
  232. bool hasNormals = meshFlags & (1 << 1);
  233. bool hasTangents = meshFlags & (1 << 2);
  234. bool hasColors = meshFlags & (1 << 3);
  235. bool hasUV = meshFlags & (1 << 4);
  236. bool hasSecondaryUVs = meshFlags & (1 << 5);
  237. bool hasBoneWeights = meshFlags & (1 << 6);
  238. unsigned int meshType;
  239. OSBasics::read(&meshType, sizeof(unsigned int), 1, inFile);
  240. setMeshType(meshType);
  241. unsigned int numVertices;
  242. OSBasics::read(&numVertices, sizeof(unsigned int), 1, inFile);
  243. Vector3_struct pos;
  244. Vector3_struct nor;
  245. Vector3_struct tan;
  246. Vector4_struct col;
  247. Vector2_struct tex;
  248. for(int i=0; i < numVertices; i++) {
  249. OSBasics::read(&pos, sizeof(Vector3_struct), 1, inFile);
  250. vertexPositionArray.data.push_back(pos.x);
  251. vertexPositionArray.data.push_back(pos.y);
  252. vertexPositionArray.data.push_back(pos.z);
  253. if(hasNormals) {
  254. OSBasics::read(&nor, sizeof(Vector3_struct), 1, inFile);
  255. vertexNormalArray.data.push_back(nor.x);
  256. vertexNormalArray.data.push_back(nor.y);
  257. vertexNormalArray.data.push_back(nor.z);
  258. }
  259. if(hasTangents) {
  260. OSBasics::read(&tan, sizeof(Vector3_struct), 1, inFile);
  261. vertexTangentArray.data.push_back(tan.x);
  262. vertexTangentArray.data.push_back(tan.y);
  263. vertexTangentArray.data.push_back(tan.z);
  264. }
  265. if(hasColors) {
  266. OSBasics::read(&col, sizeof(Vector4_struct), 1, inFile);
  267. vertexColorArray.data.push_back(col.x);
  268. vertexColorArray.data.push_back(col.y);
  269. vertexColorArray.data.push_back(col.z);
  270. vertexColorArray.data.push_back(col.w);
  271. }
  272. if(hasUV) {
  273. OSBasics::read(&tex, sizeof(Vector2_struct), 1, inFile);
  274. vertexTexCoordArray.data.push_back(tex.x);
  275. vertexTexCoordArray.data.push_back(tex.y);
  276. }
  277. if(hasSecondaryUVs) {
  278. OSBasics::read(&tex, sizeof(Vector2_struct), 1, inFile);
  279. vertexTexCoord2Array.data.push_back(tex.x);
  280. vertexTexCoord2Array.data.push_back(tex.x);
  281. }
  282. if(hasBoneWeights) {
  283. unsigned int numBoneWeights;
  284. OSBasics::read(&numBoneWeights, sizeof(unsigned int), 1, inFile);
  285. Number totalWeight = 0;
  286. int numPushed = 0;
  287. for(int b=0; b < numBoneWeights; b++) {
  288. float weight;
  289. unsigned int boneID;
  290. OSBasics::read(&boneID, sizeof(unsigned int), 1, inFile);
  291. OSBasics::read(&weight, sizeof(float), 1, inFile);
  292. if(b < 4) {
  293. vertexBoneWeightArray.data.push_back(weight);
  294. vertexBoneIndexArray.data.push_back(boneID);
  295. numPushed++;
  296. }
  297. totalWeight += weight;
  298. }
  299. if(numPushed < 4) {
  300. for(int b=numPushed; b < 4; b++) {
  301. vertexBoneWeightArray.data.push_back(0.0);
  302. vertexBoneIndexArray.data.push_back(0.0);
  303. }
  304. }
  305. for(int m=0; m < 4; m++) {
  306. vertexBoneWeightArray.data[vertexBoneWeightArray.data.size()-1-m] = vertexBoneWeightArray.data[vertexBoneWeightArray.data.size()-1-m] / totalWeight;
  307. }
  308. }
  309. }
  310. if(indexedMesh) {
  311. unsigned int numIndices;
  312. OSBasics::read(&numIndices, sizeof(unsigned int), 1, inFile);
  313. unsigned int val;
  314. for(int i=0; i < numIndices; i++) {
  315. OSBasics::read(&val, sizeof(unsigned int), 1, inFile);
  316. indexArray.data.push_back(val);
  317. }
  318. }
  319. }
  320. Vector2 Mesh::getVertexTexCoord(unsigned int vertexOffset) {
  321. return Vector2(vertexTexCoordArray.data[(vertexOffset*2)], vertexTexCoordArray.data[(vertexOffset*2)+1]);
  322. }
  323. Vector2 Mesh::getVertexTexCoordAtIndex(unsigned int index) {
  324. unsigned int vertexOffset = indexArray.data[index]*2;
  325. return Vector2(vertexTexCoordArray.data[vertexOffset], vertexTexCoordArray.data[vertexOffset+1]);
  326. }
  327. Vector3 Mesh::getVertexPosition(unsigned int vertexOffset) {
  328. return Vector3(vertexPositionArray.data[(vertexOffset*3)], vertexPositionArray.data[(vertexOffset*3)+1], vertexPositionArray.data[(vertexOffset*3)+2]);
  329. }
  330. Vector3 Mesh::getVertexPositionAtIndex(unsigned int index) {
  331. unsigned int vertexOffset = indexArray.data[index]*3;
  332. return Vector3(vertexPositionArray.data[vertexOffset], vertexPositionArray.data[vertexOffset+1], vertexPositionArray.data[vertexOffset+2]);
  333. }
  334. void Mesh::addColor(const Color &color) {
  335. vertexColorArray.data.push_back(color.r);
  336. vertexColorArray.data.push_back(color.g);
  337. vertexColorArray.data.push_back(color.b);
  338. vertexColorArray.data.push_back(color.a);
  339. }
  340. void Mesh::addColor(Number r, Number g, Number b, Number a) {
  341. vertexColorArray.data.push_back(r);
  342. vertexColorArray.data.push_back(g);
  343. vertexColorArray.data.push_back(b);
  344. vertexColorArray.data.push_back(a);
  345. }
  346. void Mesh::addVertex(Number x, Number y, Number z) {
  347. vertexPositionArray.data.push_back(x);
  348. vertexPositionArray.data.push_back(y);
  349. vertexPositionArray.data.push_back(z);
  350. }
  351. void Mesh::addTangent(Number x, Number y, Number z) {
  352. vertexTangentArray.data.push_back(x);
  353. vertexTangentArray.data.push_back(y);
  354. vertexTangentArray.data.push_back(z);
  355. }
  356. void Mesh::addTexCoord(Number u, Number v) {
  357. vertexTexCoordArray.data.push_back(u);
  358. vertexTexCoordArray.data.push_back(v);
  359. }
  360. void Mesh::addTexCoord2(Number u, Number v) {
  361. vertexTexCoord2Array.data.push_back(u);
  362. vertexTexCoord2Array.data.push_back(v);
  363. }
  364. void Mesh::addBoneAssignments(Number b1Weight, unsigned int b1Index, Number b2Weight, unsigned int b2Index, Number b3Weight, unsigned int b3Index, Number b4Weight, unsigned int b4Index) {
  365. vertexBoneWeightArray.data.push_back(b1Weight);
  366. vertexBoneWeightArray.data.push_back(b2Weight);
  367. vertexBoneWeightArray.data.push_back(b3Weight);
  368. vertexBoneWeightArray.data.push_back(b4Weight);
  369. vertexBoneIndexArray.data.push_back(b1Index);
  370. vertexBoneIndexArray.data.push_back(b2Index);
  371. vertexBoneIndexArray.data.push_back(b3Index);
  372. vertexBoneIndexArray.data.push_back(b4Index);
  373. }
  374. void Mesh::setVertexAtOffset(unsigned int offset, Number x, Number y, Number z) {
  375. if((offset*3)+2 < vertexPositionArray.data.size()) {
  376. vertexPositionArray.data[(offset*3)] = x;
  377. vertexPositionArray.data[(offset*3)+1] = y;
  378. vertexPositionArray.data[(offset*3)+2] = z;
  379. }
  380. }
  381. void Mesh::addVertexWithUV(Number x, Number y, Number z, Number u, Number v) {
  382. addVertex(x,y,z);
  383. addTexCoord(u,v);
  384. }
  385. void Mesh::addVertexWithUVAndNormal(Number x, Number y, Number z, Number u, Number v, Number nx, Number ny, Number nz) {
  386. addVertexWithUV(x,y,z, u, v);
  387. addNormal(nx, ny, nz);
  388. }
  389. void Mesh::addNormal(Number nx, Number ny, Number nz) {
  390. vertexNormalArray.data.push_back(nx);
  391. vertexNormalArray.data.push_back(ny);
  392. vertexNormalArray.data.push_back(nz);
  393. }
  394. void Mesh::addNormal(const Vector3 &n) {
  395. vertexNormalArray.data.push_back(n.x);
  396. vertexNormalArray.data.push_back(n.y);
  397. vertexNormalArray.data.push_back(n.z);
  398. }
  399. void Mesh::saveToFile(const String& fileName, bool writeNormals, bool writeTangents, bool writeColors, bool writeBoneWeights, bool writeUVs, bool writeSecondaryUVs) {
  400. OSFILE *outFile = OSBasics::open(fileName, "wb");
  401. if(!outFile) {
  402. Logger::log("Error opening mesh file for saving: %s\n", fileName.c_str());
  403. return;
  404. }
  405. saveToFile(outFile, writeNormals, writeTangents, writeColors, writeBoneWeights, writeUVs, writeSecondaryUVs);
  406. OSBasics::close(outFile);
  407. }
  408. void Mesh::loadMesh(const String& fileName) {
  409. OSFILE *inFile = OSBasics::open(fileName, "rb");
  410. if(!inFile) {
  411. Logger::log("Error opening mesh file %s\n", fileName.c_str());
  412. return;
  413. }
  414. loadFromFile(inFile);
  415. OSBasics::close(inFile);
  416. }
  417. void Mesh::createCircle(Number w, Number h, unsigned int numSegments) {
  418. setMeshType(Mesh::TRI_MESH);
  419. indexedMesh = false;
  420. Number lastx = 0;
  421. Number lasty = 0;
  422. Number lastv = 0;
  423. for (int i=0 ; i < numSegments+1; i++) {
  424. Number v = ((Number)i)/((Number)numSegments);
  425. Number pos = ((PI*2.0)/((Number)numSegments)) * i;
  426. Number x = sin(pos) * w * 0.5;
  427. Number y = cos(pos) * h * 0.5;
  428. if(i > 0) {
  429. addVertexWithUVAndNormal(0,0,0,0.5,0.5, 0.0, 0.0, 1.0);
  430. addVertexWithUVAndNormal(x,y,0, 0.5+(y/h*0.5), 0.5+(x/w*0.5), 0.0, 0.0, 1.0);
  431. addVertexWithUVAndNormal(lastx,lasty,0, 0.5+(lasty/h*0.5), 0.5+(lastx/w*0.5), 0.0, 0.0, 1.0);
  432. }
  433. lastx = x;
  434. lastv = v;
  435. lasty = y;
  436. }
  437. }
  438. Mesh *Mesh::Copy() const {
  439. Mesh *newMesh = new Mesh(meshType);
  440. newMesh->indexedMesh = indexedMesh;
  441. (*newMesh) = (*this);
  442. return newMesh;
  443. }
  444. void Mesh::createLineCircle(Number w, Number h, unsigned int numSegments) {
  445. setMeshType(Mesh::TRIFAN_MESH);
  446. indexedMesh = false;
  447. int step;
  448. if(numSegments > 0) {
  449. step = ceil(360.0/((Number)numSegments));
  450. } else {
  451. step = 1;
  452. }
  453. addVertexWithUV(cosf(0)*(w/2),sinf(0)*(h/2), 0, (cosf(0)*0.5) + 0.5,(sinf(0) * 0.5)+ 0.5);
  454. addNormal(0.0, 0.0, 0.0);
  455. for (int i=0; i < 361; i+= step) {
  456. Number degInRad = i*TORADIANS;
  457. Number x = cos(degInRad)*(w/2);
  458. Number y = sin(degInRad)*(h/2);
  459. addVertexWithUV(x, y, 0, (cos(degInRad) * 0.5)+ 0.5 , 1.0- ((sin(degInRad) * 0.5)+ 0.5));
  460. Vector3 normal(x,y, 0.0);
  461. normal.Normalize();
  462. addNormal(normal.x, normal.y, normal.z);
  463. }
  464. }
  465. void Mesh::createVPlane(Number w, Number h) {
  466. setMeshType(Mesh::TRI_MESH);
  467. indexedMesh = false;
  468. addVertexWithUVAndNormal(0 - (w/2.0f),0 - (h/2.0f), 0,0,0, 0.0, 0.0, 1.0);
  469. addVertexWithUVAndNormal(w - (w/2.0f), 0- (h/2.0f), 0, 1, 0, 0.0, 0.0, 1.0);
  470. addVertexWithUVAndNormal(w- (w/2.0f), h- (h/2.0f), 0, 1, 1, 0.0, 0.0, 1.0);
  471. addVertexWithUVAndNormal(0 - (w/2.0f),0- (h/2.0f), 0,0,0, 0.0, 0.0, 1.0);
  472. addVertexWithUVAndNormal(w - (w/2.0f),h - (h/2.0f), 0, 1, 1, 0.0, 0.0, 1.0);
  473. addVertexWithUVAndNormal(0 - (w/2.0f),h - (h/2.0f), 0,0,1, 0.0, 0.0, 1.0);
  474. calculateNormals();
  475. calculateTangents();
  476. }
  477. void Mesh::createPlane(Number w, Number h) {
  478. setMeshType(Mesh::TRI_MESH);
  479. indexedMesh = false;
  480. addVertexWithUV(0- (w/2.0f),0,h- (h/2.0f),0,0);
  481. addVertexWithUV(w- (w/2.0f),0,h- (h/2.0f), 1, 0);
  482. addVertexWithUV(w- (w/2.0f),0,0- (h/2.0f), 1, 1);
  483. addVertexWithUV(0- (w/2.0f),0,h- (h/2.0f),0,0);
  484. addVertexWithUV(w- (w/2.0f),0,0- (h/2.0f), 1, 1);
  485. addVertexWithUV(0- (w/2.0f),0,0- (h/2.0f),0,1);
  486. calculateNormals();
  487. calculateTangents();
  488. }
  489. Vector3 Mesh::recenterMesh() {
  490. // TODO: implement
  491. Vector3 positiveOffset;
  492. Vector3 negativeOffset;
  493. Vector3 finalOffset;
  494. /*
  495. for(int i=0; i < vertices.size(); i++) {
  496. positiveOffset.x = max(positiveOffset.x, vertices[i]->x);
  497. positiveOffset.y = max(positiveOffset.y, vertices[i]->y);
  498. positiveOffset.z = max(positiveOffset.z, vertices[i]->z);
  499. negativeOffset.x = min(negativeOffset.x, vertices[i]->x);
  500. negativeOffset.y = min(negativeOffset.y, vertices[i]->y);
  501. negativeOffset.z = min(negativeOffset.z, vertices[i]->z);
  502. }
  503. finalOffset.x = (positiveOffset.x + negativeOffset.x)/2.0f;
  504. finalOffset.y = (positiveOffset.y + negativeOffset.y)/2.0f;
  505. finalOffset.z = (positiveOffset.z + negativeOffset.z)/2.0f;
  506. for(int i=0; i < vertices.size(); i++) {
  507. vertices[i]->x = vertices[i]->x - finalOffset.x;
  508. vertices[i]->y = vertices[i]->y - finalOffset.y;
  509. vertices[i]->z = vertices[i]->z - finalOffset.z;
  510. }
  511. */
  512. return finalOffset;
  513. }
  514. Vector3 Mesh::calculateBBox() {
  515. Vector3 retVec;
  516. if(vertexPositionArray.data.size() == 0) {
  517. return retVec;
  518. }
  519. for(int i=0; i < vertexPositionArray.data.size()-2; i += 3) {
  520. retVec.x = max(retVec.x,(Number)fabs(vertexPositionArray.data[i]));
  521. retVec.y = max(retVec.y,(Number)fabs(vertexPositionArray.data[i]+1));
  522. retVec.z = max(retVec.z,(Number)fabs(vertexPositionArray.data[i]+2));
  523. }
  524. if(retVec.x == 0.0) {
  525. retVec.x = 0.001;
  526. }
  527. if(retVec.y == 0.0) {
  528. retVec.y = 0.001;
  529. }
  530. if(retVec.z == 0.0) {
  531. retVec.z = 0.001;
  532. }
  533. return retVec*2;
  534. }
  535. void Mesh::createSphere(Number radius, int segmentsH, int segmentsW) {
  536. segmentsH++;
  537. segmentsW++;
  538. setMeshType(Mesh::TRI_MESH);
  539. indexedMesh = true;
  540. Number tdelta = 360.f/(segmentsW-1);
  541. Number pdelta = 180.f/(segmentsH-1);
  542. Number phi = -90;
  543. Number theta = 0;
  544. for(unsigned int i = 0; i< segmentsH; i++) {
  545. for(unsigned int j = 0; j < segmentsW; j++) {
  546. Vector3 v;
  547. v.x = radius * cos(phi*PI/180.f) * cos(theta*PI/180.f);
  548. v.y = radius * sin(phi*PI/180.f);
  549. v.z = radius * cos(phi*PI/180.f) * sin(theta*PI/180.f);
  550. addVertex(v.x, v.y, v.z);
  551. v.Normalize();
  552. addNormal(v.x, v.y, v.z);
  553. addTexCoord(-theta/(360.f) , (phi+90.f)/180.f);
  554. theta += tdelta;
  555. }
  556. phi += pdelta;
  557. theta = 0;
  558. }
  559. for(unsigned int i = 0; i < segmentsH-1; i++) {
  560. for(unsigned int j = 0; j< segmentsW-1; j++) {
  561. addIndexedFace(((i+1)*segmentsW) + j, ((i+1)*segmentsW) + j+1, (i*segmentsW) + j+1);
  562. addIndexedFace((i*segmentsW) + j+1, (i*segmentsW)+j, ((i+1)*segmentsW) + j);
  563. }
  564. }
  565. calculateTangents();
  566. }
  567. void Mesh::subdivideToRadius(Number radius, int subdivisions)
  568. {
  569. typedef std::map<std::pair<int,int>, int> EdgeSet;
  570. for (int s = 0; s < subdivisions; s++) {
  571. EdgeSet dividedEdges;
  572. //Take a copy of the number of face indices at the BEGINNING, so we don't go on forever
  573. for (int i = 0, n = indexArray.data.size(); i < n; i += 3) {
  574. int vi0 = indexArray.data[i];
  575. int vi1 = indexArray.data[i+1];
  576. int vi2 = indexArray.data[i+2];
  577. Vector3 v0 = Vector3(vertexPositionArray.data[(vi0*3)], vertexPositionArray.data[(vi0*3)+1], vertexPositionArray.data[(vi0*3)+2]);
  578. Vector3 v1 = Vector3(vertexPositionArray.data[(vi1*3)], vertexPositionArray.data[(vi1*3)+1], vertexPositionArray.data[(vi1*3)+2]);
  579. Vector3 v2 = Vector3(vertexPositionArray.data[(vi2*3)], vertexPositionArray.data[(vi2*3)+1], vertexPositionArray.data[(vi2*3)+2]);
  580. //Midpoints
  581. Vector3 vm01 = (v0 + v1) * 0.5f;
  582. Vector3 vm12 = (v1 + v2) * 0.5f;
  583. Vector3 vm20 = (v2 + v0) * 0.5f;
  584. //Normalize so they're pushed outwards to the sphere
  585. vm01 = vm01 * (radius / vm01.length());
  586. vm12 = vm12 * (radius / vm12.length());
  587. vm20 = vm20 * (radius / vm20.length());
  588. std::pair<int,int>
  589. key01 = vi0 < vi1 ? std::pair<int,int>(vi0, vi1) : std::pair<int,int>(vi1, vi0),
  590. key12 = vi1 < vi2 ? std::pair<int,int>(vi1, vi2) : std::pair<int,int>(vi2, vi1),
  591. key20 = vi2 < vi0 ? std::pair<int,int>(vi2, vi0) : std::pair<int,int>(vi0, vi2);
  592. EdgeSet::iterator it01 = dividedEdges.find(key01);
  593. int vmi01;
  594. if (it01 != dividedEdges.end()) {
  595. vmi01 = it01->second;
  596. }
  597. else {
  598. vmi01 = vertexPositionArray.data.size()/3;
  599. addVertex(vm01.x, vm01.y, vm01.z);
  600. dividedEdges[key01] = vmi01;
  601. }
  602. EdgeSet::iterator it12 = dividedEdges.find(key12);
  603. int vmi12;
  604. if (it12 != dividedEdges.end()) {
  605. vmi12 = it12->second;
  606. }
  607. else {
  608. vmi12 = vertexPositionArray.data.size()/3;
  609. addVertex(vm12.x, vm12.y, vm12.z);
  610. dividedEdges[key12] = vmi12;
  611. }
  612. EdgeSet::iterator it20 = dividedEdges.find(key20);
  613. int vmi20;
  614. if (it20 != dividedEdges.end()) {
  615. vmi20 = it20->second;
  616. }
  617. else {
  618. vmi20 = vertexPositionArray.data.size()/3;
  619. addVertex(vm20.x, vm20.y, vm20.z);
  620. dividedEdges[key20] = vmi20;
  621. }
  622. addIndexedFace(vi0, vmi01, vmi20);
  623. addIndexedFace(vi1, vmi12, vmi01);
  624. addIndexedFace(vi2, vmi20, vmi12);
  625. //Recycle the original face to be the new central face
  626. indexArray.data[i] = vmi01;
  627. indexArray.data[i+1] = vmi12;
  628. indexArray.data[i+2] = vmi20;
  629. }
  630. }
  631. }
  632. void Mesh::createOctosphere(Number radius, int subdivisions) {
  633. setMeshType(Mesh::TRI_MESH);
  634. indexedMesh = true;
  635. Vector3 points[6]={
  636. Vector3(0,0,-1),
  637. Vector3(0,0,1),
  638. Vector3(-1,0,0),
  639. Vector3(1,0,0),
  640. Vector3(0,-1,0),
  641. Vector3(0,1,0)
  642. };
  643. for(int i =0;i<6;i++) {
  644. Vector3 n = points[i];
  645. Vector3 v = n * radius;
  646. addVertex(v.x, v.y, v.z);
  647. addNormal(n.x, n.y, n.z);
  648. }
  649. addIndexedFace(0, 4, 2);
  650. addIndexedFace(0, 2, 5);
  651. addIndexedFace(0, 5, 3);
  652. addIndexedFace(0, 3, 4);
  653. addIndexedFace(1, 2, 4);
  654. addIndexedFace(1, 4, 3);
  655. addIndexedFace(1, 3, 5);
  656. addIndexedFace(1, 5, 2);
  657. subdivideToRadius(radius, subdivisions);
  658. calculateNormals();
  659. calculateTangents();
  660. }
  661. void Mesh::createIcosphere(Number radius, int subdivisions) {
  662. setMeshType(Mesh::TRI_MESH);
  663. const float a = 0.5257311121191336;
  664. const float b = 0.85065080835204;
  665. indexedMesh = true;
  666. Vector3 icosahedron_points[12]={
  667. Vector3(-a, b, 0),
  668. Vector3( a, b, 0),
  669. Vector3(-a, -b, 0),
  670. Vector3( a, -b, 0),
  671. Vector3(0, -a, b),
  672. Vector3(0, a, b),
  673. Vector3(0, -a, -b),
  674. Vector3(0, a, -b),
  675. Vector3( b, 0, -a),
  676. Vector3( b, 0, a),
  677. Vector3(-b, 0, -a),
  678. Vector3(-b, 0, a)
  679. };
  680. for(int i =0;i<12;i++) {
  681. Vector3 n = icosahedron_points[i];
  682. Vector3 v = n * radius;
  683. addVertex(v.x, v.y, v.z);
  684. addNormal(n.x, n.y, n.z);
  685. }
  686. addIndexedFace(0, 11, 5);
  687. addIndexedFace(0, 5, 1);
  688. addIndexedFace(0, 1, 7);
  689. addIndexedFace(0, 7, 10);
  690. addIndexedFace(0, 10, 11);
  691. addIndexedFace(1, 5, 9);
  692. addIndexedFace(5, 11, 4);
  693. addIndexedFace(11, 10, 2);
  694. addIndexedFace(10, 7, 6);
  695. addIndexedFace(7, 1, 8);
  696. addIndexedFace(3, 9, 4);
  697. addIndexedFace(3, 4, 2);
  698. addIndexedFace(3, 2, 6);
  699. addIndexedFace(3, 6, 8);
  700. addIndexedFace(3, 8, 9);
  701. addIndexedFace(4, 9, 5);
  702. addIndexedFace(2, 4, 11);
  703. addIndexedFace(6, 2, 10);
  704. addIndexedFace(8, 6, 7);
  705. addIndexedFace(9, 8, 1);
  706. subdivideToRadius(radius, subdivisions);
  707. calculateNormals();
  708. calculateTangents();
  709. }
  710. unsigned int Mesh::getVertexCount() {
  711. return vertexPositionArray.data.size()/3;
  712. }
  713. unsigned int Mesh::getIndexCount() {
  714. return indexArray.data.size();
  715. }
  716. void Mesh::createTorus(Number radius, Number tubeRadius, int segmentsW, int segmentsH) {
  717. segmentsH++;
  718. segmentsW++;
  719. setMeshType(Mesh::TRI_MESH);
  720. indexedMesh = true;
  721. Number tdelta = 360.f/(segmentsW-1);
  722. Number pdelta = 360.f/(segmentsH-1);
  723. Number phi = -90;
  724. Number theta = 0;
  725. for(unsigned int i = 0; i< segmentsH; i++) {
  726. for(unsigned int j = 0; j < segmentsW; j++) {
  727. Vector3 v;
  728. v.x = (radius + tubeRadius*cos(phi*TORADIANS))*cos(theta*TORADIANS);
  729. v.y = tubeRadius*sin(phi*TORADIANS);
  730. v.z = (radius + tubeRadius*cos(phi*TORADIANS))*sin(theta*TORADIANS);
  731. addVertex(v.x, v.y, v.z);
  732. addTexCoord(-theta/(360.f) , (phi/(360.f)) + 0.5);
  733. theta += tdelta;
  734. }
  735. phi += pdelta;
  736. theta = 0;
  737. }
  738. for(unsigned int i = 0; i < segmentsH-1; i++) {
  739. for(unsigned int j = 0; j< segmentsW-1; j++) {
  740. addIndexedFace(((i+1)*segmentsW) + j, ((i+1)*segmentsW) + j+1, (i*segmentsW) + j+1);
  741. addIndexedFace((i*segmentsW) + j+1, (i*segmentsW)+j, ((i+1)*segmentsW) + j);
  742. }
  743. }
  744. calculateNormals();
  745. calculateTangents();
  746. }
  747. void Mesh::createCylinder(Number height, Number radius, int numSegments, bool capped) {
  748. setMeshType(Mesh::TRI_MESH);
  749. indexedMesh = true;
  750. Number lastx = 0;
  751. Number lastz = 0;
  752. Number lastv = 0;
  753. numSegments++;
  754. if(capped) {
  755. addVertexWithUVAndNormal(0,0 - (height/2.0f),0,0.5,0.5, 0.0, -1.0, 0.0);
  756. addVertexWithUVAndNormal(0,height - (height/2.0f),0,0.5,0.5, 0.0, 1.0, 0.0);
  757. }
  758. for (int i=0 ; i < numSegments; i++) {
  759. Number v = ((Number)i)/((Number)numSegments-1);
  760. Number pos = ((PI*2.0)/((Number)numSegments-1)) * i;
  761. Number x = sin(pos);
  762. Number z = cos(pos);
  763. addVertexWithUVAndNormal(x*radius,0 - (height/2.0f),z*radius, v, 0, x, 0, z);
  764. addVertexWithUVAndNormal(x*radius,height - (height/2.0f),z*radius, v, 1, x,0,z);
  765. if(capped) {
  766. addVertexWithUVAndNormal(x*radius,0 - (height/2.0f),z*radius, 0.5+(z*0.5), 0.5+(x*0.5), 0.0, -1.0, 0.0);
  767. addVertexWithUVAndNormal(x*radius,height - (height/2.0f),z*radius, 0.5+(z*0.5), 0.5+(x*0.5), 0.0, 1.0, 0.0);
  768. }
  769. lastx = x;
  770. lastz = z;
  771. lastv = v;
  772. }
  773. int vertexOffset = 2;
  774. int vertexInterval = 1;
  775. if(capped) {
  776. vertexInterval = 3;
  777. vertexOffset = 6;
  778. }
  779. for (int i=1 ; i <= numSegments-1; i++) {
  780. addIndexedFace(vertexOffset, vertexOffset-vertexInterval, vertexOffset-vertexInterval-1 );
  781. addIndexedFace(vertexOffset, vertexOffset+1, vertexOffset-vertexInterval );
  782. vertexOffset += 2;
  783. if(capped) {
  784. addIndexedFace(vertexOffset, vertexOffset-vertexInterval-1, 0);
  785. addIndexedFace(1, vertexOffset-vertexInterval, vertexOffset+1);
  786. vertexOffset += 2;
  787. }
  788. }
  789. calculateTangents();
  790. }
  791. void Mesh::createCone(Number height, Number radius, int numSegments) {
  792. setMeshType(Mesh::TRI_MESH);
  793. indexedMesh = true;
  794. Number lastx = 0;
  795. Number lastz = 0;
  796. numSegments *= 2;
  797. if(!(numSegments % 2)) {
  798. numSegments++;
  799. }
  800. addVertexWithUVAndNormal(0,0- (height/2.0f),0,0.5,0.5, 0.0, -1.0, 0.0);
  801. for (int i=0 ; i < numSegments; i++) {
  802. Number pos = ((PI*2.0)/((Number)numSegments-1)) * i;
  803. Number x = sin(pos);
  804. Number z = cos(pos);
  805. if(!(i % 2)) {
  806. addVertexWithUVAndNormal(x*radius,0- (height/2.0f),z*radius, 0.5+(z*0.5), 0.5+(x*0.5), x, 0.0, z);
  807. addVertexWithUVAndNormal(x*radius,0- (height/2.0f),z*radius, 0.5+(z*0.5), 0.5+(x*0.5), 0.0, -1.0, 0.0);
  808. } else {
  809. addVertexWithUVAndNormal(0,height- (height/2.0f),0, 0.5, 0.5, 0.0, 1.0, 0.0);
  810. }
  811. lastx = x;
  812. lastz = z;
  813. }
  814. int vertexOffset = 4;
  815. for (int i=1 ; i <= (numSegments-1)/2; i++) {
  816. addIndexedFace(vertexOffset, vertexOffset-1, vertexOffset-3);
  817. addIndexedFace(vertexOffset+1, vertexOffset-2, 0);
  818. vertexOffset += 3;
  819. }
  820. calculateTangents();
  821. }
  822. void Mesh::addIndex(unsigned int index) {
  823. indexArray.data.push_back(index);
  824. }
  825. void Mesh::addIndexedFace(unsigned int i1, unsigned int i2, unsigned int i3) {
  826. indexArray.data.push_back(i1);
  827. indexArray.data.push_back(i2);
  828. indexArray.data.push_back(i3);
  829. }
  830. void Mesh::addIndexedFace(unsigned int i1, unsigned int i2) {
  831. indexArray.data.push_back(i1);
  832. indexArray.data.push_back(i2);
  833. }
  834. void Mesh::addIndexedFace(unsigned int i1, unsigned int i2, unsigned int i3, unsigned int i4) {
  835. indexArray.data.push_back(i1);
  836. indexArray.data.push_back(i2);
  837. indexArray.data.push_back(i3);
  838. indexArray.data.push_back(i4);
  839. }
  840. void Mesh::removeFace(unsigned int faceIndex) {
  841. unsigned int groupSize = getIndexGroupSize();
  842. unsigned int startOffset = faceIndex * groupSize;
  843. if (indexedMesh) {
  844. std::vector<PolyRendererIndexType>::iterator start = indexArray.data.begin() + startOffset;
  845. indexArray.data.erase(start, start+groupSize);
  846. }
  847. else {
  848. removeVertexRange(startOffset, startOffset + groupSize);
  849. }
  850. }
  851. void Mesh::removeVertexRange(unsigned int beginRemoveVertex, int vertexRemovalCount) {
  852. // TODO: fix
  853. /*
  854. if (!vertices.size()) return;
  855. unsigned int endRemoveVertex = beginRemoveVertex + vertexRemovalCount;
  856. vertices.erase(vertices.begin() + beginRemoveVertex, vertices.begin() + endRemoveVertex);
  857. if (indexedMesh) {
  858. unsigned int groupSize = getIndexGroupSize();
  859. for (unsigned int i = 0; i < indices.size(); ) {
  860. unsigned int faceVertexIndex = indices[i];
  861. //Encountered a face that references an index being removed
  862. if (faceVertexIndex >= beginRemoveVertex && faceVertexIndex < endRemoveVertex) {
  863. //Rewind to beginning of group, going to remove entire face
  864. unsigned int faceIndex = i/groupSize;
  865. i = faceIndex * groupSize;
  866. indices.erase(indices.begin() + i, indices.begin() + i + groupSize);
  867. }
  868. else {
  869. if (faceVertexIndex > beginRemoveVertex) {
  870. indices[i] = faceVertexIndex - vertexRemovalCount;
  871. }
  872. i++;
  873. }
  874. }
  875. }
  876. */
  877. }
  878. int Mesh::removeUnusedVertices() {
  879. int removals = 0;
  880. // TODO: fix
  881. /*
  882. if (indexedMesh) {
  883. std::vector<unsigned int> vertexMap(vertices.size());
  884. //Mark all used vertices first
  885. for (unsigned int i = 0; i < indices.size(); i++) {
  886. vertexMap[indices[i]] = 1;
  887. }
  888. //Create relocation map, move vertices
  889. unsigned int dst = 0;
  890. for (unsigned int src = 0; src < vertexMap.size(); src++) {
  891. if (vertexMap[src]) {
  892. vertices[dst] = vertices[src];
  893. vertexMap[src] = dst;
  894. dst++;
  895. }
  896. }
  897. removals = dst - vertices.size();
  898. vertices.resize(dst);
  899. //Apply map to indices
  900. for (unsigned int i = 0; i < indices.size(); i++) {
  901. indices[i] = vertexMap[indices[i]];
  902. }
  903. }
  904. */
  905. return removals;
  906. }
  907. void Mesh::createBox(Number w, Number d, Number h) {
  908. setMeshType(Mesh::TRI_MESH);
  909. indexedMesh = false;
  910. addVertexWithUV(w,0,h, 1, 1);
  911. addVertexWithUV(0,0,h, 1, 0);
  912. addVertexWithUV(0,0,0,0,0);
  913. addVertexWithUV(w,0,h, 1, 1);
  914. addVertexWithUV(0,0,0,0,0);
  915. addVertexWithUV(w,0,0,0,1);
  916. addVertexWithUV(w,d,h, 1, 1);
  917. addVertexWithUV(w,d,0, 1, 0);
  918. addVertexWithUV(0,d,0,0,0);
  919. addVertexWithUV(w,d,h, 1, 1);
  920. addVertexWithUV(0,d,0,0,0);
  921. addVertexWithUV(0,d,h,0,1);
  922. addVertexWithUV(0,d,0,0,1);
  923. addVertexWithUV(w,d,0, 1, 1);
  924. addVertexWithUV(w,0,0, 1, 0);
  925. addVertexWithUV(0,d,0,0,1);
  926. addVertexWithUV(w,0,0, 1, 0);
  927. addVertexWithUV(0,0,0,0,0);
  928. addVertexWithUV(0,0,h,0,0);
  929. addVertexWithUV(w,0,h, 1, 0);
  930. addVertexWithUV(w,d,h, 1, 1);
  931. addVertexWithUV(0,0,h,0,0);
  932. addVertexWithUV(w,d,h, 1, 1);
  933. addVertexWithUV(0,d,h,0,1);
  934. addVertexWithUV(0,0,h,0,1);
  935. addVertexWithUV(0,d,h, 1, 1);
  936. addVertexWithUV(0,d,0, 1, 0);
  937. addVertexWithUV(0,0,h,0,1);
  938. addVertexWithUV(0,d,0, 1, 0);
  939. addVertexWithUV(0,0,0,0,0);
  940. addVertexWithUV(w,0,h,0,1);
  941. addVertexWithUV(w,0,0, 1, 1);
  942. addVertexWithUV(w,d,0, 1, 0);
  943. addVertexWithUV(w,0,h,0,1);
  944. addVertexWithUV(w,d,0, 1, 0);
  945. addVertexWithUV(w,d,h,0,0);
  946. for(int i=0; i < vertexPositionArray.data.size()-2; i += 3) {
  947. vertexPositionArray.data[i] = vertexPositionArray.data[i] - (w/2.0f);
  948. vertexPositionArray.data[i+1] = vertexPositionArray.data[i+1] - (d/2.0f);
  949. vertexPositionArray.data[i+2] = vertexPositionArray.data[i+2] - (h/2.0f);
  950. }
  951. calculateNormals();
  952. calculateTangents();
  953. }
  954. Vector3 Mesh::calculateFaceTangent(const Vector3 &v1, const Vector3 &v2, const Vector3 &v3, const Vector2 &texCoord1, const Vector2 &texCoord2, const Vector2 &texCoord3) {
  955. Vector3 tangent;
  956. Vector3 side0 = v1 - v2;
  957. Vector3 side1 = v3 - v1;
  958. Vector3 normal = side1.crossProduct(side0);
  959. normal.Normalize();
  960. Number deltaV0 = texCoord1.y - texCoord2.y;
  961. Number deltaV1 = texCoord3.y - texCoord1.y;
  962. tangent = side0 * deltaV1 - side1 * deltaV0;
  963. tangent.Normalize();
  964. Number deltaU0 = texCoord1.x - texCoord2.x;
  965. Number deltaU1 = texCoord3.x - texCoord1.x;
  966. Vector3 binormal = side0 * deltaU1 - side1 * deltaU0;
  967. binormal.Normalize();
  968. Vector3 tangentCross = tangent.crossProduct(binormal);
  969. if (tangentCross.dot(normal) < 0.0f) {
  970. tangent = tangent * -1;
  971. }
  972. return tangent;
  973. }
  974. void Mesh::calculateTangents() {
  975. vertexTangentArray.data.clear();
  976. int polySize = 3;
  977. if(meshType == Mesh::QUAD_MESH) {
  978. polySize = 4;
  979. }
  980. for(int i=0; i < vertexPositionArray.data.size() / 3; i++) {
  981. addTangent(0.0, 0.0, 0.0);
  982. }
  983. if(indexedMesh) {
  984. for(int i=0; i+polySize-1 < indexArray.data.size(); i += polySize) {
  985. Vector3 tangent = calculateFaceTangent(getVertexPositionAtIndex(i), getVertexPositionAtIndex(i+1), getVertexPositionAtIndex(i+2), getVertexTexCoordAtIndex(i), getVertexTexCoordAtIndex(i+1), getVertexTexCoordAtIndex(i+2));
  986. for(int j=0; j < polySize; j++) {
  987. unsigned int index= indexArray.data[i+j];
  988. vertexTangentArray.data[(index*3)] -= tangent.x;
  989. vertexTangentArray.data[(index*3)+1] -= tangent.y;
  990. vertexTangentArray.data[(index*3)+2] -= tangent.z;
  991. }
  992. }
  993. } else {
  994. for(int i=0; i+polySize-1 < vertexPositionArray.data.size() / 3; i += polySize) {
  995. Vector3 tangent = calculateFaceTangent(getVertexPosition(i), getVertexPosition(i+1), getVertexPosition(i+2), getVertexTexCoord(i), getVertexTexCoord(i+1), getVertexTexCoord(i+2));
  996. for(int j=0; j < polySize; j++) {
  997. vertexTangentArray.data[(i+j) * 3] = tangent.x;
  998. vertexTangentArray.data[((i+j) * 3) + 1] = tangent.y;
  999. vertexTangentArray.data[((i+j) * 3) + 2] = tangent.z;
  1000. }
  1001. }
  1002. }
  1003. // normalize tangents
  1004. for(int i=0; i < vertexTangentArray.data.size()-2; i += 3) {
  1005. Vector3 v(vertexTangentArray.data[i], vertexTangentArray.data[i+1], vertexTangentArray.data[i+2]);
  1006. v.Normalize();
  1007. vertexTangentArray.data[i] = v.x;
  1008. vertexTangentArray.data[i+1] = v.y;
  1009. vertexTangentArray.data[i+2] = v.z;
  1010. }
  1011. }
  1012. void Mesh::calculateNormals() {
  1013. int polySize = 3;
  1014. if(meshType == Mesh::QUAD_MESH) {
  1015. polySize = 4;
  1016. }
  1017. vertexNormalArray.data.clear();
  1018. for(int i=0; i < vertexPositionArray.data.size()-2; i += 3) {
  1019. addNormal(0.0, 0.0, 0.0);
  1020. }
  1021. if(indexedMesh) {
  1022. for(int i=0; i+polySize-1 < indexArray.data.size(); i += polySize) {
  1023. const Vector3 e1 = getVertexPositionAtIndex(i) - getVertexPositionAtIndex(i+1);
  1024. const Vector3 e2 = getVertexPositionAtIndex(i+2) - getVertexPositionAtIndex(i+1);
  1025. const Vector3 no = e1.crossProduct(e2);
  1026. for(int j=0; j < polySize; j++) {
  1027. unsigned int index= indexArray.data[i+j];
  1028. vertexNormalArray.data[(index*3)] -= no.x;
  1029. vertexNormalArray.data[(index*3)+1] -= no.y;
  1030. vertexNormalArray.data[(index*3)+2] -= no.z;
  1031. }
  1032. }
  1033. } else {
  1034. for(int i=0; i+polySize-1 < vertexPositionArray.data.size() / 3; i += polySize) {
  1035. const Vector3 e1 = getVertexPosition(i) - getVertexPosition(i+1);
  1036. const Vector3 e2 = getVertexPosition(i+2) - getVertexPosition(i+1);
  1037. const Vector3 no = e1.crossProduct(e2);
  1038. for(int j=0; j < polySize; j++) {
  1039. vertexNormalArray.data[(i+j) * 3] = -no.x;
  1040. vertexNormalArray.data[((i+j) * 3) + 1] = -no.y;
  1041. vertexNormalArray.data[((i+j) * 3) + 2] = -no.z;
  1042. }
  1043. }
  1044. }
  1045. // normalize normals
  1046. for(int i=0; i < vertexNormalArray.data.size()-2; i += 3) {
  1047. Vector3 v(vertexNormalArray.data[i], vertexNormalArray.data[i+1], vertexNormalArray.data[i+2]);
  1048. v.Normalize();
  1049. vertexNormalArray.data[i] = v.x;
  1050. vertexNormalArray.data[i+1] = v.y;
  1051. vertexNormalArray.data[i+2] = v.z;
  1052. }
  1053. }
  1054. int Mesh::getMeshType() {
  1055. return meshType;
  1056. }
  1057. void Mesh::setMeshType(int newType) {
  1058. meshType = newType;
  1059. }