interiorSimpleMesh.cpp 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644
  1. //-----------------------------------------------------------------------------
  2. // Copyright (c) 2012 GarageGames, LLC
  3. //
  4. // Permission is hereby granted, free of charge, to any person obtaining a copy
  5. // of this software and associated documentation files (the "Software"), to
  6. // deal in the Software without restriction, including without limitation the
  7. // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
  8. // sell copies of the Software, and to permit persons to whom the Software is
  9. // furnished to do so, subject to the following conditions:
  10. //
  11. // The above copyright notice and this permission notice shall be included in
  12. // all copies or substantial portions of the Software.
  13. //
  14. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  15. // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  16. // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  17. // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  18. // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
  19. // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
  20. // IN THE SOFTWARE.
  21. //-----------------------------------------------------------------------------
  22. #include "platform/platform.h"
  23. #include "interior/interiorSimpleMesh.h"
  24. #include "interior/interiorLMManager.h"
  25. #include "interior/interior.h"
  26. #include "console/console.h"
  27. #include "scene/sceneObject.h"
  28. #include "math/mathIO.h"
  29. #include "materials/matInstance.h"
  30. #include "materials/materialManager.h"
  31. #include "scene/sceneManager.h"
  32. #include "scene/sceneRenderState.h"
  33. #include "ts/tsShape.h"
  34. #include "gfx/bitmap/gBitmap.h"
  35. Vector<MeshRenderInst *> *InteriorSimpleMesh::renderInstList = new Vector<MeshRenderInst *>();
  36. // Checks for polygon level collision with given planes
  37. U32 _whichSide(PlaneF pln, Point3F* verts)
  38. {
  39. Point3F currv, nextv;
  40. S32 csd, nsd;
  41. // Find out which side the first vert is on
  42. U32 side = PlaneF::On;
  43. currv = verts[0];
  44. csd = pln.whichSide(currv);
  45. if(csd != PlaneF::On)
  46. side = csd;
  47. for(U32 k = 1; k < 3; k++)
  48. {
  49. nextv = verts[k];
  50. nsd = pln.whichSide(nextv);
  51. if((csd == PlaneF::Back && nsd == PlaneF::Front) ||
  52. (csd == PlaneF::Front && nsd == PlaneF::Back))
  53. return 2;
  54. else if (nsd != PlaneF::On)
  55. side = nsd;
  56. currv = nextv;
  57. csd = nsd;
  58. }
  59. // Loop back to the first vert
  60. nextv = verts[0];
  61. nsd = pln.whichSide(nextv);
  62. if((csd == PlaneF::Back && nsd == PlaneF::Front) ||
  63. (csd == PlaneF::Front && nsd == PlaneF::Back))
  64. return 2;
  65. else if(nsd != PlaneF::On)
  66. side = nsd;
  67. return side;
  68. }
  69. //bool InteriorSimpleMesh::castRay(const Point3F &start, const Point3F &end, RayInfo* info)
  70. //{
  71. // bool found = false;
  72. // F32 best_t = F32_MAX;
  73. // Point3F best_normal = Point3F(0, 0, 1);
  74. // Point3F dir = end - start;
  75. //
  76. // for(U32 p=0; p<primitives.size(); p++)
  77. // {
  78. // primitive &prim = primitives[p];
  79. // for(U32 t=2; t<prim.count; t++)
  80. // {
  81. // Point3F &v1 = verts[prim.start+t-2];
  82. // Point3F &v2 = verts[prim.start+t-1];
  83. // Point3F &v3 = verts[prim.start+t];
  84. //
  85. // F32 cur_t = 0;
  86. // Point2F b;
  87. //
  88. // if(castRayTriangle(start, dir, v1, v2, v3, cur_t, b))
  89. // {
  90. // if(cur_t < best_t)
  91. // {
  92. // best_t = cur_t;
  93. // best_normal = norms[prim.start+t];
  94. // found = true;
  95. // }
  96. // }
  97. // }
  98. // }
  99. //
  100. // if(found && info)
  101. // {
  102. // info->t = best_t;
  103. // info->normal = best_normal;
  104. // info->material = 0;
  105. // }
  106. //
  107. // return found;
  108. //}
  109. bool InteriorSimpleMesh::castPlanes(PlaneF left, PlaneF right, PlaneF top, PlaneF bottom)
  110. {
  111. for(U32 p=0; p<primitives.size(); p++)
  112. {
  113. primitive &prim = primitives[p];
  114. for(U32 t=2; t<prim.count; t++)
  115. {
  116. Point3F v[3];
  117. v[0] = verts[prim.start+t-2];
  118. v[1] = verts[prim.start+t-1];
  119. v[2] = verts[prim.start+t];
  120. if(_whichSide(left, v) == PlaneF::Front)
  121. continue;
  122. if(_whichSide(right, v) == PlaneF::Front)
  123. continue;
  124. if(_whichSide(top, v) == PlaneF::Front)
  125. continue;
  126. if(_whichSide(bottom, v) == PlaneF::Front)
  127. continue;
  128. return true;
  129. }
  130. }
  131. return false;
  132. }
  133. void InteriorSimpleMesh::render( SceneRenderState* state,
  134. const MeshRenderInst &copyinst,
  135. U32 interiorlmhandle,
  136. U32 instancelmhandle,
  137. InteriorInstance* intInst )
  138. {
  139. /*
  140. AssertFatal((primBuff->mPrimitiveCount == packedPrimitives.size()), "Primitive mismatch");
  141. renderInstList->clear();
  142. for(S32 i=0; i<packedPrimitives.size(); i++)
  143. {
  144. primitive &draw = packedPrimitives[i];
  145. MeshRenderInst *inst = state->getRenderPass()->allocInst<MeshRenderInst>();
  146. *inst = copyinst;
  147. inst->matInst = materialList->getMaterialInst(draw.diffuseIndex);
  148. if(!inst->matInst)
  149. inst->matInst = MATMGR->getWarningMatInstance();
  150. if(!inst->matInst)
  151. continue;
  152. inst->primBuffIndex = i;
  153. inst->primBuff = &primBuff;
  154. inst->vertBuff = &vertBuff;
  155. if(draw.alpha)
  156. {
  157. inst->translucentSort = true;
  158. inst->type = RenderPassManager::RIT_Translucent;
  159. }
  160. inst->lightmap = gInteriorLMManager.getHandle(interiorlmhandle, instancelmhandle, draw.lightMapIndex);
  161. state->getRenderPass()->addInst(inst);
  162. renderInstList->push_back(inst);
  163. }
  164. if(lightingplugin && renderInstList->size() > 0)
  165. {
  166. if(lightingplugin->interiorInstInit(intInst, this))
  167. {
  168. if(lightingplugin->allZoneInit())
  169. {
  170. Vector<MeshRenderInst *> &list = *renderInstList;
  171. // clone the origial instances to avoid damaging the originals' data
  172. for(int i=0; i<renderInstList->size(); i++)
  173. {
  174. MeshRenderInst *inst = state->getRenderPass()->allocInst<MeshRenderInst>();
  175. const MeshRenderInst *oldinst = list[i];
  176. *inst = *oldinst;
  177. list[i] = inst;
  178. }
  179. lightingplugin->processRI(state, list);
  180. }
  181. }
  182. }
  183. */
  184. }
  185. bool InteriorSimpleMesh::read(Stream& stream)
  186. {
  187. // Simple serialization
  188. S32 vectorSize = 0;
  189. // Primitives
  190. stream.read(&vectorSize);
  191. primitives.setSize(vectorSize);
  192. for (U32 i = 0; i < primitives.size(); i++)
  193. {
  194. stream.read(&primitives[i].alpha);
  195. stream.read(&primitives[i].texS);
  196. stream.read(&primitives[i].texT);
  197. stream.read(&primitives[i].diffuseIndex);
  198. stream.read(&primitives[i].lightMapIndex);
  199. stream.read(&primitives[i].start);
  200. stream.read(&primitives[i].count);
  201. mathRead(stream, &primitives[i].lightMapEquationX);
  202. mathRead(stream, &primitives[i].lightMapEquationY);
  203. mathRead(stream, &primitives[i].lightMapOffset);
  204. mathRead(stream, &primitives[i].lightMapSize);
  205. }
  206. // Indices
  207. stream.read(&vectorSize);
  208. indices.setSize(vectorSize);
  209. for (U32 i = 0; i < indices.size(); i++)
  210. stream.read(&indices[i]);
  211. // Vertices
  212. stream.read(&vectorSize);
  213. verts.setSize(vectorSize);
  214. for (U32 i = 0; i < verts.size(); i++)
  215. mathRead(stream, &verts[i]);
  216. // Normals
  217. stream.read(&vectorSize);
  218. norms.setSize(vectorSize);
  219. for (U32 i = 0; i < norms.size(); i++)
  220. mathRead(stream, &norms[i]);
  221. // Diffuse UVs
  222. stream.read(&vectorSize);
  223. diffuseUVs.setSize(vectorSize);
  224. for (U32 i = 0; i < diffuseUVs.size(); i++)
  225. mathRead(stream, &diffuseUVs[i]);
  226. // Lightmap UVs
  227. stream.read(&vectorSize);
  228. lightmapUVs.setSize(vectorSize);
  229. for (U32 i = 0; i < lightmapUVs.size(); i++)
  230. mathRead(stream, &lightmapUVs[i]);
  231. // Material list
  232. bool hasMaterialList = false;
  233. stream.read(&hasMaterialList);
  234. if (hasMaterialList)
  235. {
  236. // Since we are doing this externally to a TSShape read we need to
  237. // make sure that our read version is the same as our write version.
  238. // It is possible that it was changed along the way by a loaded TSShape.
  239. TSShape::smReadVersion = 25;
  240. if (materialList)
  241. delete materialList;
  242. materialList = new TSMaterialList;
  243. materialList->read(stream);
  244. }
  245. else
  246. materialList = NULL;
  247. // Diffuse bitmaps
  248. stream.read(&vectorSize);
  249. for (U32 i = 0; i < vectorSize; i++)
  250. {
  251. // need to read these
  252. bool hasBitmap = false;
  253. stream.read(&hasBitmap);
  254. if(hasBitmap)
  255. {
  256. GBitmap* bitMap = new GBitmap;
  257. bitMap->readBitmap("png",stream);
  258. delete bitMap;
  259. }
  260. }
  261. // Misc data
  262. stream.read(&hasSolid);
  263. stream.read(&hasTranslucency);
  264. mathRead(stream, &bounds);
  265. mathRead(stream, &transform);
  266. mathRead(stream, &scale);
  267. calculateBounds();
  268. buildBuffers();
  269. return true;
  270. }
  271. bool InteriorSimpleMesh::write(Stream& stream) const
  272. {
  273. // Simple serialization
  274. // Primitives
  275. stream.write(primitives.size());
  276. for (U32 i = 0; i < primitives.size(); i++)
  277. {
  278. stream.write(primitives[i].alpha);
  279. stream.write(primitives[i].texS);
  280. stream.write(primitives[i].texT);
  281. stream.write(primitives[i].diffuseIndex);
  282. stream.write(primitives[i].lightMapIndex);
  283. stream.write(primitives[i].start);
  284. stream.write(primitives[i].count);
  285. mathWrite(stream, primitives[i].lightMapEquationX);
  286. mathWrite(stream, primitives[i].lightMapEquationY);
  287. mathWrite(stream, primitives[i].lightMapOffset);
  288. mathWrite(stream, primitives[i].lightMapSize);
  289. }
  290. // Indices
  291. stream.write(indices.size());
  292. for (U32 i = 0; i < indices.size(); i++)
  293. stream.write(indices[i]);
  294. // Vertices
  295. stream.write(verts.size());
  296. for (U32 i = 0; i < verts.size(); i++)
  297. mathWrite(stream, verts[i]);
  298. // Normals
  299. stream.write(norms.size());
  300. for (U32 i = 0; i < norms.size(); i++)
  301. mathWrite(stream, norms[i]);
  302. // Diffuse UVs
  303. stream.write(diffuseUVs.size());
  304. for (U32 i = 0; i < diffuseUVs.size(); i++)
  305. mathWrite(stream, diffuseUVs[i]);
  306. // Lightmap UVs
  307. stream.write(lightmapUVs.size());
  308. for (U32 i = 0; i < lightmapUVs.size(); i++)
  309. mathWrite(stream, lightmapUVs[i]);
  310. // Material list
  311. if (materialList)
  312. {
  313. stream.write(true);
  314. materialList->write(stream);
  315. }
  316. else
  317. stream.write(false);
  318. // Diffuse bitmaps
  319. if (!materialList)
  320. stream.write(0);
  321. else
  322. {
  323. stream.write(materialList->size());
  324. for (U32 i = 0; i < materialList->size(); i++)
  325. {
  326. GFXTexHandle handle(materialList->getDiffuseTexture(i));
  327. if (handle.isValid())
  328. {
  329. GBitmap* bitMap = handle.getBitmap();
  330. if (bitMap)
  331. {
  332. stream.write(true);
  333. bitMap->writeBitmap("png",stream);
  334. }
  335. else
  336. stream.write(false);
  337. }
  338. else
  339. stream.write(false);
  340. }
  341. }
  342. // Misc data
  343. stream.write(hasSolid);
  344. stream.write(hasTranslucency);
  345. mathWrite(stream, bounds);
  346. mathWrite(stream, transform);
  347. mathWrite(stream, scale);
  348. return true;
  349. }
  350. void InteriorSimpleMesh::buildBuffers()
  351. {
  352. bool flipped = false;
  353. MatrixF trans = transform;
  354. trans.scale(scale);
  355. Point3F r0, r1, r2;
  356. trans.getRow(0, &r0);
  357. trans.getRow(1, &r1);
  358. trans.getRow(2, &r2);
  359. F32 det = r0.x * (r1.y * r2.z - r1.z * r2.y) -
  360. r0.y * (r1.x * r2.z - r1.z * r2.x) +
  361. r0.z * (r1.x * r2.y - r1.y * r2.x);
  362. flipped = det < 0.0f;
  363. // setup the repack vectors
  364. packedIndices.clear();
  365. packedPrimitives.clear();
  366. packedIndices.reserve(indices.size() * 2);
  367. packedPrimitives.reserve(primitives.size());
  368. Vector<bool> addedprim;
  369. addedprim.setSize(primitives.size());
  370. dMemset(addedprim.address(), 0, (addedprim.size() * sizeof(bool)));
  371. Vector<Point3F> tang;
  372. Vector<Point3F> binorm;
  373. tang.setSize(verts.size());
  374. binorm.setSize(verts.size());
  375. dMemset(tang.address(), 0, (tang.size() * sizeof(Point3F)));
  376. dMemset(binorm.address(), 0, (binorm.size() * sizeof(Point3F)));
  377. // fill the repack vectors
  378. for(U32 p=0; p<primitives.size(); p++)
  379. {
  380. if(addedprim[p])
  381. continue;
  382. addedprim[p] = true;
  383. const primitive &primold = primitives[p];
  384. packedPrimitives.increment();
  385. primitive &primnew = packedPrimitives.last();
  386. primnew.start = packedIndices.size();
  387. primnew.count = 0;
  388. primnew.alpha = primold.alpha;
  389. primnew.diffuseIndex = primold.diffuseIndex;
  390. primnew.lightMapIndex = primold.lightMapIndex;
  391. packPrimitive(primnew, primold, packedIndices, flipped, tang, binorm);
  392. for(U32 gp=(p+1); gp<primitives.size(); gp++)
  393. {
  394. if(addedprim[gp])
  395. continue;
  396. const primitive &primgrouped = primitives[gp];
  397. if((primnew.alpha != primgrouped.alpha) || (primnew.diffuseIndex != primgrouped.diffuseIndex) ||
  398. (primnew.lightMapIndex != primgrouped.lightMapIndex))
  399. continue;
  400. addedprim[gp] = true;
  401. packPrimitive(primnew, primgrouped, packedIndices, flipped, tang, binorm);
  402. }
  403. }
  404. // normalize
  405. for(U32 i=0; i<tang.size(); i++)
  406. {
  407. tang[i].normalize();
  408. binorm[i].normalize();
  409. }
  410. // verify...
  411. F32 oldcount = 0;
  412. F32 newcount = 0;
  413. for(U32 i=0; i<primitives.size(); i++)
  414. oldcount += F32(primitives[i].count) - 2.0f;
  415. for(U32 i=0; i<packedPrimitives.size(); i++)
  416. newcount += F32(packedPrimitives[i].count) / 3.0f;
  417. AssertFatal((oldcount == newcount), "Invalid primitive pack.");
  418. // build the GFX buffers...
  419. Vector<GFXPrimitive> packedprims;
  420. packedprims.setSize(packedPrimitives.size());
  421. for(U32 i=0; i<packedprims.size(); i++)
  422. {
  423. GFXPrimitive &p = packedprims[i];
  424. primitive &prim = packedPrimitives[i];
  425. p.type = GFXTriangleList;
  426. p.numPrimitives = prim.count / 3;
  427. p.startIndex = prim.start;
  428. p.minIndex = U32_MAX;
  429. U32 maxindex = 0;
  430. for(U32 ii=0; ii<prim.count; ii++)
  431. {
  432. if(p.minIndex > packedIndices[prim.start + ii])
  433. p.minIndex = packedIndices[prim.start + ii];
  434. if(maxindex < packedIndices[prim.start + ii])
  435. maxindex = packedIndices[prim.start + ii];
  436. }
  437. // D3D voodoo - not the actual numverts, only the max span (maxindex - minindex) - this needs a better variable name...
  438. p.numVertices = (maxindex - p.minIndex) + 1;
  439. }
  440. // create vb style sysmem buffer
  441. Vector<GFXVertexPNTTB> packedverts;
  442. packedverts.setSize(verts.size());
  443. // fill it
  444. for(U32 i=0; i<packedverts.size(); i++)
  445. {
  446. GFXVertexPNTTB &v = packedverts[i];
  447. trans.mulP(verts[i], &v.point);
  448. trans.mulV(norms[i], &v.normal);
  449. trans.mulV(tang[i], &v.T);
  450. trans.mulV(binorm[i], &v.B);
  451. v.texCoord = diffuseUVs[i];
  452. v.texCoord2 = lightmapUVs[i];
  453. v.T = v.T - v.normal * mDot(v.normal, v.T);
  454. v.T.normalize();
  455. Point3F b;
  456. mCross(v.normal, v.T, &b);
  457. b *= (mDot(b, v.B) < 0.0F) ? -1.0F : 1.0F;
  458. v.B = b;
  459. }
  460. // set up the vb and fill all at once
  461. vertBuff.set(GFX, packedverts.size(), GFXBufferTypeStatic);
  462. GFXVertexPNTTB *rawvb = vertBuff.lock();
  463. dMemcpy(rawvb, packedverts.address(), packedverts.size() * sizeof(GFXVertexPNTTB));
  464. vertBuff.unlock();
  465. // set up the pb and fill all at once
  466. U16 *rawi;
  467. GFXPrimitive *rawp;
  468. primBuff.set(GFX, packedIndices.size(), packedprims.size(), GFXBufferTypeStatic);
  469. primBuff.lock(&rawi, &rawp);
  470. dMemcpy(rawi, packedIndices.address(), packedIndices.size() * sizeof(U16));
  471. dMemcpy(rawp, packedprims.address(), packedprims.size() * sizeof(GFXPrimitive));
  472. primBuff.unlock();
  473. }
  474. void InteriorSimpleMesh::buildTangent(U32 i0, U32 i1, U32 i2, Vector<Point3F> &tang, Vector<Point3F> &binorm)
  475. {
  476. const Point3F& va = verts[i0];
  477. const Point3F& vb = verts[i1];
  478. const Point3F& vc = verts[i2];
  479. const Point2F& uva = diffuseUVs[i0];
  480. const Point2F& uvb = diffuseUVs[i1];
  481. const Point2F& uvc = diffuseUVs[i2];
  482. float x1 = vb.x - va.x;
  483. float x2 = vc.x - va.x;
  484. float y1 = vb.y - va.y;
  485. float y2 = vc.y - va.y;
  486. float z1 = vb.z - va.z;
  487. float z2 = vc.z - va.z;
  488. float s1 = uvb.x - uva.x;
  489. float s2 = uvc.x - uva.x;
  490. float t1 = uvb.y - uva.y;
  491. float t2 = uvc.y - uva.y;
  492. F32 denom = (s1 * t2 - s2 * t1);
  493. if(fabs(denom) < 0.0001)
  494. return;
  495. float r = 1.0F / denom;
  496. Point3F s((t2 * x1 - t1 * x2) * r,
  497. (t2 * y1 - t1 * y2) * r,
  498. (t2 * z1 - t1 * z2) * r);
  499. Point3F t((s1 * x2 - s2 * x1) * r,
  500. (s1 * y2 - s2 * y1) * r,
  501. (s1 * z2 - s2 * z1) * r);
  502. tang[i0] += s;
  503. tang[i1] += s;
  504. tang[i2] += s;
  505. binorm[i0] += t;
  506. binorm[i1] += t;
  507. binorm[i2] += t;
  508. }
  509. void InteriorSimpleMesh::packPrimitive(primitive &primnew, const primitive &primold, Vector<U16> &indicesnew,
  510. bool flipped, Vector<Point3F> &tang, Vector<Point3F> &binorm)
  511. {
  512. // convert from strip to list and add to primnew
  513. for(U32 p=2; p<primold.count; p++)
  514. {
  515. bool direction = (p & 0x1);
  516. U32 i0, i1, i2;
  517. if(flipped)
  518. direction = !direction;
  519. if(direction)
  520. {
  521. i0 = indices[p + primold.start - 1];
  522. i1 = indices[p + primold.start - 2];
  523. i2 = indices[p + primold.start];
  524. }
  525. else
  526. {
  527. i0 = indices[p + primold.start - 2];
  528. i1 = indices[p + primold.start - 1];
  529. i2 = indices[p + primold.start];
  530. }
  531. indicesnew.push_back(i0);
  532. indicesnew.push_back(i1);
  533. indicesnew.push_back(i2);
  534. buildTangent(i0, i1, i2, tang, binorm);
  535. primnew.count += 3;
  536. }
  537. }
  538. bool InteriorSimpleMesh::prepForRendering(const char* path)
  539. {
  540. //materialList->load(InteriorTexture, path, false);
  541. materialList->mapMaterials();
  542. // GFX2_RENDER_MERGE
  543. materialList->initMatInstances( MATMGR->getDefaultFeatures(), getGFXVertexFormat<GFXVertexPNTTB>() );
  544. return true;
  545. }