BsMeshUtility.cpp 26 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948
  1. //********************************** Banshee Engine (www.banshee3d.com) **************************************************//
  2. //**************** Copyright (c) 2016 Marko Pintera ([email protected]). All rights reserved. **********************//
  3. #include "Mesh/BsMeshUtility.h"
  4. #include "Math/BsVector4.h"
  5. #include "Math/BsVector3.h"
  6. #include "Math/BsVector2.h"
  7. #include "Math/BsPlane.h"
  8. namespace bs
  9. {
  10. struct VertexFaces
  11. {
  12. UINT32* faces;
  13. UINT32 numFaces = 0;
  14. };
  15. struct VertexConnectivity
  16. {
  17. VertexConnectivity(UINT8* indices, UINT32 numVertices, UINT32 numFaces, UINT32 indexSize)
  18. :vertexFaces(nullptr), mMaxFacesPerVertex(0), mNumVertices(numVertices), mFaces(nullptr)
  19. {
  20. vertexFaces = bs_newN<VertexFaces>(numVertices);
  21. resizeFaceArray(10);
  22. for (UINT32 i = 0; i < numFaces; i++)
  23. {
  24. for (UINT32 j = 0; j < 3; j++)
  25. {
  26. UINT32 idx = i * 3 + j;
  27. UINT32 vertexIdx = 0;
  28. memcpy(&vertexIdx, indices + idx * indexSize, indexSize);
  29. assert(vertexIdx < mNumVertices);
  30. VertexFaces& faces = vertexFaces[vertexIdx];
  31. if (faces.numFaces >= mMaxFacesPerVertex)
  32. resizeFaceArray(mMaxFacesPerVertex * 2);
  33. faces.faces[faces.numFaces] = i;
  34. faces.numFaces++;
  35. }
  36. }
  37. }
  38. ~VertexConnectivity()
  39. {
  40. if (vertexFaces != nullptr)
  41. bs_deleteN(vertexFaces, mNumVertices);
  42. if (mFaces != nullptr)
  43. bs_free(mFaces);
  44. }
  45. VertexFaces* vertexFaces;
  46. private:
  47. void resizeFaceArray(UINT32 numFaces)
  48. {
  49. UINT32* newFaces = (UINT32*)bs_alloc(numFaces * mNumVertices * sizeof(UINT32));
  50. if (mFaces != nullptr)
  51. {
  52. for (UINT32 i = 0; i < mNumVertices; i++)
  53. memcpy(newFaces + (i * numFaces), mFaces + (i * mMaxFacesPerVertex), mMaxFacesPerVertex * sizeof(UINT32));
  54. bs_free(mFaces);
  55. }
  56. for (UINT32 i = 0; i < mNumVertices; i++)
  57. vertexFaces[i].faces = newFaces + (i * numFaces);
  58. mFaces = newFaces;
  59. mMaxFacesPerVertex = numFaces;
  60. }
  61. UINT32 mMaxFacesPerVertex;
  62. UINT32 mNumVertices;
  63. UINT32* mFaces;
  64. };
  65. /** Provides base methods required for clipping of arbitrary triangles. */
  66. class TriangleClipperBase // Implementation from: http://www.geometrictools.com/Documentation/ClipMesh.pdf
  67. {
  68. protected:
  69. /** Single vertex in the clipped mesh. */
  70. struct ClipVert
  71. {
  72. ClipVert() { }
  73. Vector3 point = Vector3::ZERO;
  74. Vector2 uv = Vector2::ZERO;
  75. float distance = 0.0f;
  76. UINT32 occurs = 0;
  77. bool visible = true;
  78. };
  79. /** Single edge in the clipped mesh. */
  80. struct ClipEdge
  81. {
  82. ClipEdge() { }
  83. UINT32 verts[2];
  84. Vector<UINT32> faces;
  85. bool visible = true;
  86. };
  87. /** Single polygon in the clipped mesh. */
  88. struct ClipFace
  89. {
  90. ClipFace() { }
  91. Vector<UINT32> edges;
  92. bool visible = true;
  93. Vector3 normal = Vector3::ZERO;
  94. };
  95. /** Contains vertices, edges and faces of the clipped mesh. */
  96. struct ClipMesh
  97. {
  98. ClipMesh() { }
  99. Vector<ClipVert> verts;
  100. Vector<ClipEdge> edges;
  101. Vector<ClipFace> faces;
  102. };
  103. protected:
  104. /**
  105. * Register all edges and faces, using the mesh vertices as a basis. Assumes vertices are not indexed and that
  106. * every three vertices form a face
  107. */
  108. void addEdgesAndFaces();
  109. /** Clips the current mesh with the provided plane. */
  110. INT32 clipByPlane(const Plane& plane);
  111. /** Clips vertices of the current mesh by the provided plane. */
  112. INT32 processVertices(const Plane& plane);
  113. /** Clips edges of the current mesh. processVertices() must be called beforehand. */
  114. void processEdges();
  115. /** Clips the faces (polygons) of the current mesh. processEdges() must be called beforehand. */
  116. void processFaces();
  117. /**
  118. * Returns a set of non-culled vertex indices for every visible face in the mesh. This should be called after
  119. * clipping operation is complete to retrieve valid vertices.
  120. */
  121. void getOrderedFaces(FrameVector<FrameVector<UINT32>>& sortedFaces);
  122. /** Returns a set of ordered and non-culled vertices for the provided face of the mesh */
  123. void getOrderedVertices(const ClipFace& face, UINT32* vertices);
  124. /** Calculates the normal for vertices related to the provided vertex indices. */
  125. Vector3 getNormal(UINT32* sortedVertices, UINT32 numVertices);
  126. /**
  127. * Checks is the polygon shape of the provided face open or closed. If open, returns true and outputs endpoints of
  128. * the polyline.
  129. */
  130. bool getOpenPolyline(ClipFace& face, UINT32& start, UINT32& end);
  131. ClipMesh mesh;
  132. };
  133. void TriangleClipperBase::addEdgesAndFaces()
  134. {
  135. UINT32 numTris = (UINT32)mesh.verts.size() / 3;
  136. UINT32 numEdges = numTris * 3;
  137. mesh.edges.resize(numEdges);
  138. mesh.faces.resize(numTris);
  139. for (UINT32 i = 0; i < numTris; i++)
  140. {
  141. UINT32 idx0 = i * 3 + 0;
  142. UINT32 idx1 = i * 3 + 1;
  143. UINT32 idx2 = i * 3 + 2;
  144. ClipEdge& clipEdge0 = mesh.edges[idx0];
  145. clipEdge0.verts[0] = idx0;
  146. clipEdge0.verts[1] = idx1;
  147. ClipEdge& clipEdge1 = mesh.edges[idx1];
  148. clipEdge1.verts[0] = idx1;
  149. clipEdge1.verts[1] = idx2;
  150. ClipEdge& clipEdge2 = mesh.edges[idx2];
  151. clipEdge2.verts[0] = idx2;
  152. clipEdge2.verts[1] = idx0;
  153. ClipFace& clipFace = mesh.faces[i];
  154. clipFace.edges.push_back(idx0);
  155. clipFace.edges.push_back(idx1);
  156. clipFace.edges.push_back(idx2);
  157. clipEdge0.faces.push_back(i);
  158. clipEdge1.faces.push_back(i);
  159. clipEdge2.faces.push_back(i);
  160. UINT32 verts[] = { idx0, idx1, idx2, idx0 };
  161. for (UINT32 j = 0; j < 3; j++)
  162. clipFace.normal += Vector3::cross(mesh.verts[verts[j]].point, mesh.verts[verts[j + 1]].point);
  163. clipFace.normal.normalize();
  164. }
  165. }
  166. INT32 TriangleClipperBase::clipByPlane(const Plane& plane)
  167. {
  168. int state = processVertices(plane);
  169. if (state == 1)
  170. return +1; // Nothing is clipped
  171. else if (state == -1)
  172. return -1; // Everything is clipped
  173. processEdges();
  174. processFaces();
  175. return 0;
  176. }
  177. INT32 TriangleClipperBase::processVertices(const Plane& plane)
  178. {
  179. static const float EPSILON = 0.00001f;
  180. // Compute signed distances from vertices to plane
  181. int positive = 0, negative = 0;
  182. for (UINT32 i = 0; i < (UINT32)mesh.verts.size(); i++)
  183. {
  184. ClipVert& vertex = mesh.verts[i];
  185. if (vertex.visible)
  186. {
  187. vertex.distance = Vector3::dot(plane.normal, vertex.point) - plane.d;
  188. if (vertex.distance >= EPSILON)
  189. {
  190. positive++;
  191. }
  192. else if (vertex.distance <= -EPSILON)
  193. {
  194. negative++;
  195. vertex.visible = false;
  196. }
  197. else
  198. {
  199. // Point on the plane within floating point tolerance
  200. vertex.distance = 0;
  201. }
  202. }
  203. }
  204. if (negative == 0)
  205. {
  206. // All vertices on nonnegative side, no clipping
  207. return +1;
  208. }
  209. if (positive == 0)
  210. {
  211. // All vertices on nonpositive side, everything clipped
  212. return -1;
  213. }
  214. return 0;
  215. }
  216. void TriangleClipperBase::processEdges()
  217. {
  218. for (UINT32 i = 0; i < (UINT32)mesh.edges.size(); i++)
  219. {
  220. ClipEdge& edge = mesh.edges[i];
  221. if (edge.visible)
  222. {
  223. const ClipVert& v0 = mesh.verts[edge.verts[0]];
  224. const ClipVert& v1 = mesh.verts[edge.verts[1]];
  225. float d0 = v0.distance;
  226. float d1 = v1.distance;
  227. if (d0 <= 0 && d1 <= 0)
  228. {
  229. // Edge is culled, remove edge from faces sharing it
  230. for (UINT32 j = 0; j < (UINT32)edge.faces.size(); j++)
  231. {
  232. ClipFace& face = mesh.faces[edge.faces[j]];
  233. auto iterFind = std::find(face.edges.begin(), face.edges.end(), i);
  234. if (iterFind != face.edges.end())
  235. {
  236. face.edges.erase(iterFind);
  237. if (face.edges.empty())
  238. face.visible = false;
  239. }
  240. }
  241. edge.visible = false;
  242. continue;
  243. }
  244. if (d0 >= 0 && d1 >= 0)
  245. {
  246. // Edge is on nonnegative side, faces retain the edge
  247. continue;
  248. }
  249. // The edge is split by the plane. Compute the point of intersection.
  250. // If the old edge is <V0,V1> and I is the intersection point, the new
  251. // edge is <V0,I> when d0 > 0 or <I,V1> when d1 > 0.
  252. float t = d0 / (d0 - d1);
  253. Vector3 intersectPt = (1 - t)*v0.point + t*v1.point;
  254. Vector2 intersectUv = (1 - t)*v0.uv + t*v1.uv;
  255. UINT32 newVertIdx = (UINT32)mesh.verts.size();
  256. mesh.verts.push_back(ClipVert());
  257. ClipVert& newVert = mesh.verts.back();
  258. newVert.point = intersectPt;
  259. newVert.uv = intersectUv;
  260. if (d0 > 0)
  261. mesh.edges[i].verts[1] = newVertIdx;
  262. else
  263. mesh.edges[i].verts[0] = newVertIdx;
  264. }
  265. }
  266. }
  267. void TriangleClipperBase::processFaces()
  268. {
  269. for (UINT32 i = 0; i < (UINT32)mesh.faces.size(); i++)
  270. {
  271. ClipFace& face = mesh.faces[i];
  272. if (face.visible)
  273. {
  274. // The edge is culled. If the edge is exactly on the clip
  275. // plane, it is possible that a visible triangle shares it.
  276. // The edge will be re-added during the face loop.
  277. for (UINT32 j = 0; j < (UINT32)face.edges.size(); j++)
  278. {
  279. ClipEdge& edge = mesh.edges[face.edges[j]];
  280. ClipVert& v0 = mesh.verts[edge.verts[0]];
  281. ClipVert& v1 = mesh.verts[edge.verts[1]];
  282. v0.occurs = 0;
  283. v1.occurs = 0;
  284. }
  285. }
  286. UINT32 start, end;
  287. if (getOpenPolyline(mesh.faces[i], start, end))
  288. {
  289. // Polyline is open, close it
  290. UINT32 closeEdgeIdx = (UINT32)mesh.edges.size();
  291. mesh.edges.push_back(ClipEdge());
  292. ClipEdge& closeEdge = mesh.edges.back();
  293. closeEdge.verts[0] = start;
  294. closeEdge.verts[1] = end;
  295. closeEdge.faces.push_back(i);
  296. face.edges.push_back(closeEdgeIdx);
  297. }
  298. }
  299. }
  300. bool TriangleClipperBase::getOpenPolyline(ClipFace& face, UINT32& start, UINT32& end)
  301. {
  302. // Count the number of occurrences of each vertex in the polyline. The
  303. // resulting "occurs" values must be 1 or 2.
  304. for (UINT32 i = 0; i < (UINT32)face.edges.size(); i++)
  305. {
  306. ClipEdge& edge = mesh.edges[face.edges[i]];
  307. if (edge.visible)
  308. {
  309. ClipVert& v0 = mesh.verts[edge.verts[0]];
  310. ClipVert& v1 = mesh.verts[edge.verts[1]];
  311. v0.occurs++;
  312. v1.occurs++;
  313. }
  314. }
  315. // Determine if the polyline is open
  316. bool gotStart = false;
  317. bool gotEnd = false;
  318. for (UINT32 i = 0; i < (UINT32)face.edges.size(); i++)
  319. {
  320. const ClipEdge& edge = mesh.edges[face.edges[i]];
  321. const ClipVert& v0 = mesh.verts[edge.verts[0]];
  322. const ClipVert& v1 = mesh.verts[edge.verts[1]];
  323. if (v0.occurs == 1)
  324. {
  325. if (!gotStart)
  326. {
  327. start = edge.verts[0];
  328. gotStart = true;
  329. }
  330. else if (!gotEnd)
  331. {
  332. end = edge.verts[0];
  333. gotEnd = true;
  334. }
  335. }
  336. if (v1.occurs == 1)
  337. {
  338. if (!gotStart)
  339. {
  340. start = edge.verts[1];
  341. gotStart = true;
  342. }
  343. else if (!gotEnd)
  344. {
  345. end = edge.verts[1];
  346. gotEnd = true;
  347. }
  348. }
  349. }
  350. return gotStart;
  351. }
  352. void TriangleClipperBase::getOrderedFaces(FrameVector<FrameVector<UINT32>>& sortedFaces)
  353. {
  354. for (UINT32 i = 0; i < (UINT32)mesh.faces.size(); i++)
  355. {
  356. const ClipFace& face = mesh.faces[i];
  357. if (face.visible)
  358. {
  359. // Get the ordered vertices of the face. The first and last
  360. // element of the array are the same since the polyline is
  361. // closed.
  362. UINT32 numSortedVerts = (UINT32)face.edges.size() + 1;
  363. UINT32* sortedVerts = (UINT32*)bs_stack_alloc(sizeof(UINT32) * numSortedVerts);
  364. getOrderedVertices(face, sortedVerts);
  365. FrameVector<UINT32> faceVerts;
  366. // The convention is that the vertices should be counterclockwise
  367. // ordered when viewed from the negative side of the plane of the
  368. // face. If you need the opposite convention, switch the
  369. // inequality in the if-else statement.
  370. Vector3 normal = getNormal(sortedVerts, numSortedVerts);
  371. if (Vector3::dot(mesh.faces[i].normal, normal) < 0)
  372. {
  373. // Clockwise, need to swap
  374. for (INT32 j = (INT32)numSortedVerts - 2; j >= 0; j--)
  375. faceVerts.push_back(sortedVerts[j]);
  376. }
  377. else
  378. {
  379. // Counterclockwise
  380. for (int j = 0; j <= (INT32)numSortedVerts - 2; j++)
  381. faceVerts.push_back(sortedVerts[j]);
  382. }
  383. sortedFaces.push_back(faceVerts);
  384. bs_stack_free(sortedVerts);
  385. }
  386. }
  387. }
  388. void TriangleClipperBase::getOrderedVertices(const ClipFace& face, UINT32* sortedVerts)
  389. {
  390. UINT32 numEdges = (UINT32)face.edges.size();
  391. UINT32* sortedEdges = (UINT32*)bs_stack_alloc(sizeof(UINT32) * numEdges);
  392. for (UINT32 i = 0; i < numEdges; i++)
  393. sortedEdges[i] = face.edges[i];
  394. // Bubble sort to arrange edges in contiguous order
  395. for (UINT32 i0 = 0, i1 = 1, choice = 1; i1 < numEdges - 1; i0 = i1, i1++)
  396. {
  397. const ClipEdge& edge0 = mesh.edges[sortedEdges[i0]];
  398. UINT32 current = edge0.verts[choice];
  399. for (UINT32 j = i1; j < numEdges; j++)
  400. {
  401. const ClipEdge& edge1 = mesh.edges[sortedEdges[j]];
  402. if (edge1.verts[0] == current || edge1.verts[1] == current)
  403. {
  404. std::swap(sortedEdges[i1], sortedEdges[j]);
  405. choice = 1;
  406. break;
  407. }
  408. }
  409. }
  410. // Add the first two vertices
  411. sortedVerts[0] = mesh.edges[sortedEdges[0]].verts[0];
  412. sortedVerts[1] = mesh.edges[sortedEdges[0]].verts[1];
  413. // Add the remaining vertices
  414. for (UINT32 i = 1; i < numEdges; i++)
  415. {
  416. const ClipEdge& edge = mesh.edges[sortedEdges[i]];
  417. if (edge.verts[0] == sortedVerts[i])
  418. sortedVerts[i + 1] = edge.verts[1];
  419. else
  420. sortedVerts[i + 1] = edge.verts[0];
  421. }
  422. bs_stack_free(sortedEdges);
  423. }
  424. Vector3 TriangleClipperBase::getNormal(UINT32* sortedVertices, UINT32 numVertices)
  425. {
  426. Vector3 normal(BsZero);
  427. for (UINT32 i = 0; i <= numVertices - 2; i++)
  428. normal += Vector3::cross(mesh.verts[sortedVertices[i]].point, mesh.verts[sortedVertices[i + 1]].point);
  429. normal.normalize();
  430. return normal;
  431. }
  432. /** Clips two-dimensional triangles against a set of provided planes. */
  433. class TriangleClipper2D : public TriangleClipperBase
  434. {
  435. public:
  436. /** @copydoc MeshUtility::clip2D */
  437. void clip(UINT8* vertices, UINT8* uvs, UINT32 numTris, UINT32 vertexStride, const Vector<Plane>& clipPlanes,
  438. const std::function<void(Vector2*, Vector2*, UINT32)>& writeCallback);
  439. private:
  440. /** Converts clipped vertices back into triangles and outputs them via the provided callback. */
  441. void convertToMesh(const std::function<void(Vector2*, Vector2*, UINT32)>& writeCallback);
  442. static const int BUFFER_SIZE = 64 * 3; // Must be a multiple of three
  443. Vector2 vertexBuffer[BUFFER_SIZE];
  444. Vector2 uvBuffer[BUFFER_SIZE];
  445. };
  446. void TriangleClipper2D::clip(UINT8* vertices, UINT8* uvs, UINT32 numTris, UINT32 vertexStride, const Vector<Plane>& clipPlanes,
  447. const std::function<void(Vector2*, Vector2*, UINT32)>& writeCallback)
  448. {
  449. // Add vertices
  450. UINT32 numVertices = numTris * 3;
  451. mesh.verts.resize(numVertices);
  452. if (uvs != nullptr)
  453. {
  454. for (UINT32 i = 0; i < numVertices; i++)
  455. {
  456. ClipVert& clipVert = mesh.verts[i];
  457. Vector2 vector2D = *(Vector2*)(vertices + vertexStride * i);
  458. clipVert.point = Vector3(vector2D.x, vector2D.y, 0.0f);
  459. clipVert.uv = *(Vector2*)(uvs + vertexStride * i);
  460. }
  461. }
  462. else
  463. {
  464. for (UINT32 i = 0; i < numVertices; i++)
  465. {
  466. ClipVert& clipVert = mesh.verts[i];
  467. Vector2 vector2D = *(Vector2*)(vertices + vertexStride * i);
  468. clipVert.point = Vector3(vector2D.x, vector2D.y, 0.0f);
  469. }
  470. }
  471. addEdgesAndFaces();
  472. for (int i = 0; i < 4; i++)
  473. {
  474. if (clipByPlane(clipPlanes[i]) == -1)
  475. return;
  476. }
  477. convertToMesh(writeCallback);
  478. }
  479. void TriangleClipper2D::convertToMesh(const std::function<void(Vector2*, Vector2*, UINT32)>& writeCallback)
  480. {
  481. bs_frame_mark();
  482. {
  483. FrameVector<FrameVector<UINT32>> allFaces;
  484. getOrderedFaces(allFaces);
  485. // Note: Consider using Delaunay triangulation to avoid skinny triangles
  486. UINT32 numWritten = 0;
  487. assert(BUFFER_SIZE % 3 == 0);
  488. for (auto& face : allFaces)
  489. {
  490. for (UINT32 i = 0; i < (UINT32)face.size() - 2; i++)
  491. {
  492. const Vector3& v0 = mesh.verts[face[0]].point;
  493. const Vector3& v1 = mesh.verts[face[i + 1]].point;
  494. const Vector3& v2 = mesh.verts[face[i + 2]].point;
  495. vertexBuffer[numWritten] = Vector2(v0.x, v0.y);
  496. uvBuffer[numWritten] = mesh.verts[face[0]].uv;
  497. numWritten++;
  498. vertexBuffer[numWritten] = Vector2(v1.x, v1.y);
  499. uvBuffer[numWritten] = mesh.verts[face[i + 1]].uv;
  500. numWritten++;
  501. vertexBuffer[numWritten] = Vector2(v2.x, v2.y);
  502. uvBuffer[numWritten] = mesh.verts[face[i + 2]].uv;
  503. numWritten++;
  504. // Only need to check this here since we guarantee the buffer is in multiples of three
  505. if (numWritten >= BUFFER_SIZE)
  506. {
  507. writeCallback(vertexBuffer, uvBuffer, numWritten);
  508. numWritten = 0;
  509. }
  510. }
  511. }
  512. if (numWritten > 0)
  513. writeCallback(vertexBuffer, uvBuffer, numWritten);
  514. }
  515. bs_frame_clear();
  516. }
  517. /** Clips three-dimensional triangles against a set of provided planes. */
  518. class TriangleClipper3D : public TriangleClipperBase
  519. {
  520. public:
  521. /** @copydoc MeshUtility::clip3D */
  522. void clip(UINT8* vertices, UINT8* uvs, UINT32 numTris, UINT32 vertexStride, const Vector<Plane>& clipPlanes,
  523. const std::function<void(Vector3*, Vector2*, UINT32)>& writeCallback);
  524. private:
  525. /** Converts clipped vertices back into triangles and outputs them via the provided callback. */
  526. void convertToMesh(const std::function<void(Vector3*, Vector2*, UINT32)>& writeCallback);
  527. static const int BUFFER_SIZE = 64 * 3; // Must be a multiple of three
  528. Vector3 vertexBuffer[BUFFER_SIZE];
  529. Vector2 uvBuffer[BUFFER_SIZE];
  530. };
  531. void TriangleClipper3D::clip(UINT8* vertices, UINT8* uvs, UINT32 numTris, UINT32 vertexStride, const Vector<Plane>& clipPlanes,
  532. const std::function<void(Vector3*, Vector2*, UINT32)>& writeCallback)
  533. {
  534. // Add vertices
  535. UINT32 numVertices = numTris * 3;
  536. mesh.verts.resize(numVertices);
  537. if (uvs != nullptr)
  538. {
  539. for (UINT32 i = 0; i < numVertices; i++)
  540. {
  541. ClipVert& clipVert = mesh.verts[i];
  542. clipVert.point = *(Vector3*)(vertices + vertexStride * i);
  543. clipVert.uv = *(Vector2*)(uvs + vertexStride * i);
  544. }
  545. }
  546. else
  547. {
  548. for (UINT32 i = 0; i < numVertices; i++)
  549. {
  550. ClipVert& clipVert = mesh.verts[i];
  551. Vector2 vector2D = *(Vector2*)(vertices + vertexStride * i);
  552. clipVert.point = Vector3(vector2D.x, vector2D.y, 0.0f);
  553. }
  554. }
  555. addEdgesAndFaces();
  556. for (int i = 0; i < 4; i++)
  557. {
  558. if (clipByPlane(clipPlanes[i]) == -1)
  559. return;
  560. }
  561. convertToMesh(writeCallback);
  562. }
  563. void TriangleClipper3D::convertToMesh(const std::function<void(Vector3*, Vector2*, UINT32)>& writeCallback)
  564. {
  565. bs_frame_mark();
  566. {
  567. FrameVector<FrameVector<UINT32>> allFaces;
  568. getOrderedFaces(allFaces);
  569. // Note: Consider using Delaunay triangulation to avoid skinny triangles
  570. UINT32 numWritten = 0;
  571. assert(BUFFER_SIZE % 3 == 0);
  572. for (auto& face : allFaces)
  573. {
  574. for (UINT32 i = 0; i < (UINT32)face.size() - 2; i++)
  575. {
  576. vertexBuffer[numWritten] = mesh.verts[face[0]].point;
  577. uvBuffer[numWritten] = mesh.verts[face[0]].uv;
  578. numWritten++;
  579. vertexBuffer[numWritten] = mesh.verts[face[i + 1]].point;
  580. uvBuffer[numWritten] = mesh.verts[face[i + 1]].uv;
  581. numWritten++;
  582. vertexBuffer[numWritten] = mesh.verts[face[i + 2]].point;
  583. uvBuffer[numWritten] = mesh.verts[face[i + 2]].uv;
  584. numWritten++;
  585. // Only need to check this here since we guarantee the buffer is in multiples of three
  586. if (numWritten >= BUFFER_SIZE)
  587. {
  588. writeCallback(vertexBuffer, uvBuffer, numWritten);
  589. numWritten = 0;
  590. }
  591. }
  592. }
  593. if (numWritten > 0)
  594. writeCallback(vertexBuffer, uvBuffer, numWritten);
  595. }
  596. bs_frame_clear();
  597. }
  598. void MeshUtility::calculateNormals(Vector3* vertices, UINT8* indices, UINT32 numVertices,
  599. UINT32 numIndices, Vector3* normals, UINT32 indexSize)
  600. {
  601. UINT32 numFaces = numIndices / 3;
  602. Vector3* faceNormals = bs_newN<Vector3>(numFaces);
  603. for (UINT32 i = 0; i < numFaces; i++)
  604. {
  605. UINT32 triangle[3];
  606. memcpy(&triangle[0], indices + (i * 3 + 0) * indexSize, indexSize);
  607. memcpy(&triangle[1], indices + (i * 3 + 1) * indexSize, indexSize);
  608. memcpy(&triangle[2], indices + (i * 3 + 2) * indexSize, indexSize);
  609. Vector3 edgeA = vertices[triangle[1]] - vertices[triangle[0]];
  610. Vector3 edgeB = vertices[triangle[2]] - vertices[triangle[0]];
  611. faceNormals[i] = Vector3::normalize(Vector3::cross(edgeA, edgeB));
  612. // Note: Potentially don't normalize here in order to weigh the normals
  613. // by triangle size
  614. }
  615. VertexConnectivity connectivity(indices, numVertices, numFaces, indexSize);
  616. for (UINT32 i = 0; i < numVertices; i++)
  617. {
  618. VertexFaces& faces = connectivity.vertexFaces[i];
  619. normals[i] = Vector3::ZERO;
  620. for (UINT32 j = 0; j < faces.numFaces; j++)
  621. {
  622. UINT32 faceIdx = faces.faces[j];
  623. normals[i] += faceNormals[faceIdx];
  624. }
  625. normals[i].normalize();
  626. }
  627. bs_deleteN(faceNormals, numFaces);
  628. }
  629. void MeshUtility::calculateTangents(Vector3* vertices, Vector3* normals, Vector2* uv, UINT8* indices, UINT32 numVertices,
  630. UINT32 numIndices, Vector3* tangents, Vector3* bitangents, UINT32 indexSize, UINT32 vertexStride)
  631. {
  632. UINT32 numFaces = numIndices / 3;
  633. UINT32 vec2Stride = vertexStride == 0 ? sizeof(Vector2) : vertexStride;
  634. UINT32 vec3Stride = vertexStride == 0 ? sizeof(Vector3) : vertexStride;
  635. UINT8* positionBytes = (UINT8*)vertices;
  636. UINT8* normalBytes = (UINT8*)normals;
  637. UINT8* uvBytes = (UINT8*)uv;
  638. Vector3* faceTangents = bs_newN<Vector3>(numFaces);
  639. Vector3* faceBitangents = bs_newN<Vector3>(numFaces);
  640. for (UINT32 i = 0; i < numFaces; i++)
  641. {
  642. UINT32 triangle[3];
  643. memcpy(&triangle[0], indices + (i * 3 + 0) * indexSize, indexSize);
  644. memcpy(&triangle[1], indices + (i * 3 + 1) * indexSize, indexSize);
  645. memcpy(&triangle[2], indices + (i * 3 + 2) * indexSize, indexSize);
  646. Vector3 p0 = *(Vector3*)&positionBytes[triangle[0] * vec3Stride];
  647. Vector3 p1 = *(Vector3*)&positionBytes[triangle[1] * vec3Stride];
  648. Vector3 p2 = *(Vector3*)&positionBytes[triangle[2] * vec3Stride];
  649. Vector2 uv0 = *(Vector2*)&uvBytes[triangle[0] * vec2Stride];
  650. Vector2 uv1 = *(Vector2*)&uvBytes[triangle[1] * vec2Stride];
  651. Vector2 uv2 = *(Vector2*)&uvBytes[triangle[2] * vec2Stride];
  652. Vector3 q0 = p1 - p0;
  653. Vector3 q1 = p2 - p0;
  654. Vector2 s;
  655. s.x = uv1.x - uv0.x;
  656. s.y = uv2.x - uv0.x;
  657. Vector2 t;
  658. t.x = uv1.y - uv0.y;
  659. t.y = uv2.y - uv0.y;
  660. float denom = s.x*t.y - s.y * t.x;
  661. if (fabs(denom) >= 0e-8f)
  662. {
  663. float r = 1.0f / denom;
  664. s *= r;
  665. t *= r;
  666. faceTangents[i] = t.y * q0 - t.x * q1;
  667. faceBitangents[i] = s.x * q0 - s.y * q1;
  668. faceTangents[i].normalize();
  669. faceBitangents[i].normalize();
  670. }
  671. // Note: Potentially don't normalize here in order to weight the normals by triangle size
  672. }
  673. VertexConnectivity connectivity(indices, numVertices, numFaces, indexSize);
  674. for (UINT32 i = 0; i < numVertices; i++)
  675. {
  676. VertexFaces& faces = connectivity.vertexFaces[i];
  677. tangents[i] = Vector3::ZERO;
  678. bitangents[i] = Vector3::ZERO;
  679. for (UINT32 j = 0; j < faces.numFaces; j++)
  680. {
  681. UINT32 faceIdx = faces.faces[j];
  682. tangents[i] += faceTangents[faceIdx];
  683. bitangents[i] += faceBitangents[faceIdx];
  684. }
  685. tangents[i].normalize();
  686. bitangents[i].normalize();
  687. Vector3 normal = *(Vector3*)&normalBytes[i * vec3Stride];
  688. // Orthonormalize
  689. float dot0 = normal.dot(tangents[i]);
  690. tangents[i] -= dot0*normal;
  691. tangents[i].normalize();
  692. float dot1 = tangents[i].dot(bitangents[i]);
  693. dot0 = normal.dot(bitangents[i]);
  694. bitangents[i] -= dot0*normal + dot1*tangents[i];
  695. bitangents[i].normalize();
  696. }
  697. bs_deleteN(faceTangents, numFaces);
  698. bs_deleteN(faceBitangents, numFaces);
  699. // TODO - Consider weighing tangents by triangle size and/or edge angles
  700. }
  701. void MeshUtility::calculateTangentSpace(Vector3* vertices, Vector2* uv, UINT8* indices, UINT32 numVertices,
  702. UINT32 numIndices, Vector3* normals, Vector3* tangents, Vector3* bitangents, UINT32 indexSize)
  703. {
  704. calculateNormals(vertices, indices, numVertices, numIndices, normals, indexSize);
  705. calculateTangents(vertices, normals, uv, indices, numVertices, numIndices, tangents, bitangents, indexSize);
  706. }
  707. void MeshUtility::clip2D(UINT8* vertices, UINT8* uvs, UINT32 numTris, UINT32 vertexStride, const Vector<Plane>& clipPlanes,
  708. const std::function<void(Vector2*, Vector2*, UINT32)>& writeCallback)
  709. {
  710. TriangleClipper2D clipper;
  711. clipper.clip(vertices, uvs, numTris, vertexStride, clipPlanes, writeCallback);
  712. }
  713. void MeshUtility::clip3D(UINT8* vertices, UINT8* uvs, UINT32 numTris, UINT32 vertexStride, const Vector<Plane>& clipPlanes,
  714. const std::function<void(Vector3*, Vector2*, UINT32)>& writeCallback)
  715. {
  716. TriangleClipper3D clipper;
  717. clipper.clip(vertices, uvs, numTris, vertexStride, clipPlanes, writeCallback);
  718. }
  719. void MeshUtility::packNormals(Vector3* source, UINT8* destination, UINT32 count, UINT32 inStride, UINT32 outStride)
  720. {
  721. UINT8* srcPtr = (UINT8*)source;
  722. UINT8* dstPtr = destination;
  723. for (UINT32 i = 0; i < count; i++)
  724. {
  725. Vector3 src = *(Vector3*)srcPtr;
  726. PackedNormal& packed = *(PackedNormal*)dstPtr;
  727. packed.x = Math::clamp((int)(src.x * 127.5f + 127.5f), 0, 255);
  728. packed.y = Math::clamp((int)(src.y * 127.5f + 127.5f), 0, 255);
  729. packed.z = Math::clamp((int)(src.z * 127.5f + 127.5f), 0, 255);
  730. packed.w = 128;
  731. srcPtr += inStride;
  732. dstPtr += outStride;
  733. }
  734. }
  735. void MeshUtility::packNormals(Vector4* source, UINT8* destination, UINT32 count, UINT32 inStride, UINT32 outStride)
  736. {
  737. UINT8* srcPtr = (UINT8*)source;
  738. UINT8* dstPtr = destination;
  739. for (UINT32 i = 0; i < count; i++)
  740. {
  741. Vector4 src = *(Vector4*)srcPtr;
  742. PackedNormal& packed = *(PackedNormal*)dstPtr;
  743. packed.x = Math::clamp((int)(src.x * 127.5f + 127.5f), 0, 255);
  744. packed.y = Math::clamp((int)(src.y * 127.5f + 127.5f), 0, 255);
  745. packed.z = Math::clamp((int)(src.z * 127.5f + 127.5f), 0, 255);
  746. packed.w = Math::clamp((int)(src.w * 127.5f + 127.5f), 0, 255);
  747. srcPtr += inStride;
  748. dstPtr += outStride;
  749. }
  750. }
  751. void MeshUtility::unpackNormals(UINT8* source, Vector3* destination, UINT32 count, UINT32 stride)
  752. {
  753. UINT8* ptr = source;
  754. for (UINT32 i = 0; i < count; i++)
  755. {
  756. PackedNormal& packed = *(PackedNormal*)ptr;
  757. destination[i].x = (packed.x * 2.0f - 1.0f);
  758. destination[i].y = (packed.y * 2.0f - 1.0f);
  759. destination[i].z = (packed.z * 2.0f - 1.0f);
  760. ptr += stride;
  761. }
  762. }
  763. void MeshUtility::unpackNormals(UINT8* source, Vector4* destination, UINT32 count, UINT32 stride)
  764. {
  765. UINT8* ptr = source;
  766. for (UINT32 i = 0; i < count; i++)
  767. {
  768. PackedNormal& packed = *(PackedNormal*)ptr;
  769. destination[i].x = (packed.x * 2.0f - 1.0f);
  770. destination[i].y = (packed.y * 2.0f - 1.0f);
  771. destination[i].z = (packed.z * 2.0f - 1.0f);
  772. destination[i].w = (packed.w * 2.0f - 1.0f);
  773. ptr += stride;
  774. }
  775. }
  776. }