BsMeshUtility.cpp 23 KB

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