IceIndexedTriangle.cpp 24 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547
  1. ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  2. /**
  3. * Contains a handy indexed triangle class.
  4. * \file IceIndexedTriangle.cpp
  5. * \author Pierre Terdiman
  6. * \date January, 17, 2000
  7. */
  8. ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  9. ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  10. #include "../Opcode.h"
  11. using namespace IceMaths;
  12. ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  13. /**
  14. * Contains an indexed triangle class.
  15. *
  16. * \class Triangle
  17. * \author Pierre Terdiman
  18. * \version 1.0
  19. * \date 08.15.98
  20. */
  21. ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  22. ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  23. /**
  24. * Flips the winding order.
  25. */
  26. ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  27. void IndexedTriangle::Flip()
  28. {
  29. Swap(mVRef[1], mVRef[2]);
  30. }
  31. ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  32. /**
  33. * Computes the triangle area.
  34. * \param verts [in] the list of indexed vertices
  35. * \return the area
  36. */
  37. ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  38. float IndexedTriangle::Area(const Point* verts) const
  39. {
  40. if(!verts) return 0.0f;
  41. const Point& p0 = verts[0];
  42. const Point& p1 = verts[1];
  43. const Point& p2 = verts[2];
  44. return ((p0-p1)^(p0-p2)).Magnitude() * 0.5f;
  45. }
  46. ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  47. /**
  48. * Computes the triangle perimeter.
  49. * \param verts [in] the list of indexed vertices
  50. * \return the perimeter
  51. */
  52. ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  53. float IndexedTriangle::Perimeter(const Point* verts) const
  54. {
  55. if(!verts) return 0.0f;
  56. const Point& p0 = verts[0];
  57. const Point& p1 = verts[1];
  58. const Point& p2 = verts[2];
  59. return p0.Distance(p1)
  60. + p0.Distance(p2)
  61. + p1.Distance(p2);
  62. }
  63. ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  64. /**
  65. * Computes the triangle compacity.
  66. * \param verts [in] the list of indexed vertices
  67. * \return the compacity
  68. */
  69. ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  70. float IndexedTriangle::Compacity(const Point* verts) const
  71. {
  72. if(!verts) return 0.0f;
  73. float P = Perimeter(verts);
  74. if(P==0.0f) return 0.0f;
  75. return (4.0f*PI*Area(verts)/(P*P));
  76. }
  77. ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  78. /**
  79. * Computes the triangle normal.
  80. * \param verts [in] the list of indexed vertices
  81. * \param normal [out] the computed normal
  82. */
  83. ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  84. void IndexedTriangle::Normal(const Point* verts, Point& normal) const
  85. {
  86. if(!verts) return;
  87. const Point& p0 = verts[mVRef[0]];
  88. const Point& p1 = verts[mVRef[1]];
  89. const Point& p2 = verts[mVRef[2]];
  90. normal = ((p2-p1)^(p0-p1)).Normalize();
  91. }
  92. ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  93. /**
  94. * Computes the triangle denormalized normal.
  95. * \param verts [in] the list of indexed vertices
  96. * \param normal [out] the computed normal
  97. */
  98. ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  99. void IndexedTriangle::DenormalizedNormal(const Point* verts, Point& normal) const
  100. {
  101. if(!verts) return;
  102. const Point& p0 = verts[mVRef[0]];
  103. const Point& p1 = verts[mVRef[1]];
  104. const Point& p2 = verts[mVRef[2]];
  105. normal = ((p2-p1)^(p0-p1));
  106. }
  107. ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  108. /**
  109. * Computes the triangle center.
  110. * \param verts [in] the list of indexed vertices
  111. * \param center [out] the computed center
  112. */
  113. ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  114. void IndexedTriangle::Center(const Point* verts, Point& center) const
  115. {
  116. if(!verts) return;
  117. const Point& p0 = verts[mVRef[0]];
  118. const Point& p1 = verts[mVRef[1]];
  119. const Point& p2 = verts[mVRef[2]];
  120. center = (p0+p1+p2)*INV3;
  121. }
  122. ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  123. /**
  124. * Computes the centered normal
  125. * \param verts [in] the list of indexed vertices
  126. * \param normal [out] the computed centered normal
  127. */
  128. ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  129. void IndexedTriangle::CenteredNormal(const Point* verts, Point& normal) const
  130. {
  131. if(!verts) return;
  132. const Point& p0 = verts[mVRef[0]];
  133. const Point& p1 = verts[mVRef[1]];
  134. const Point& p2 = verts[mVRef[2]];
  135. Point Center = (p0+p1+p2)*INV3;
  136. normal = Center + ((p2-p1)^(p0-p1)).Normalize();
  137. }
  138. ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  139. /**
  140. * Computes a random point within the triangle.
  141. * \param verts [in] the list of indexed vertices
  142. * \param normal [out] the computed centered normal
  143. */
  144. ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  145. void IndexedTriangle::RandomPoint(const Point* verts, Point& random) const
  146. {
  147. if(!verts) return;
  148. // Random barycentric coords
  149. float Alpha = UnitRandomFloat();
  150. float Beta = UnitRandomFloat();
  151. float Gamma = UnitRandomFloat();
  152. float OneOverTotal = 1.0f / (Alpha + Beta + Gamma);
  153. Alpha *= OneOverTotal;
  154. Beta *= OneOverTotal;
  155. Gamma *= OneOverTotal;
  156. const Point& p0 = verts[mVRef[0]];
  157. const Point& p1 = verts[mVRef[1]];
  158. const Point& p2 = verts[mVRef[2]];
  159. random = Alpha*p0 + Beta*p1 + Gamma*p2;
  160. }
  161. ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  162. /**
  163. * Computes backface culling.
  164. * \param verts [in] the list of indexed vertices
  165. * \param source [in] source point (in local space) from which culling must be computed
  166. * \return true if the triangle is visible from the source point
  167. */
  168. ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  169. bool IndexedTriangle::IsVisible(const Point* verts, const Point& source) const
  170. {
  171. // Checkings
  172. if(!verts) return false;
  173. const Point& p0 = verts[mVRef[0]];
  174. const Point& p1 = verts[mVRef[1]];
  175. const Point& p2 = verts[mVRef[2]];
  176. // Compute denormalized normal
  177. Point Normal = (p2 - p1)^(p0 - p1);
  178. // Backface culling
  179. return (Normal | source) >= 0.0f;
  180. // Same as:
  181. // Plane PL(verts[mVRef[0]], verts[mVRef[1]], verts[mVRef[2]]);
  182. // return PL.Distance(source) > PL.d;
  183. }
  184. ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  185. /**
  186. * Computes backface culling.
  187. * \param verts [in] the list of indexed vertices
  188. * \param source [in] source point (in local space) from which culling must be computed
  189. * \return true if the triangle is visible from the source point
  190. */
  191. ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  192. bool IndexedTriangle::BackfaceCulling(const Point* verts, const Point& source) const
  193. {
  194. // Checkings
  195. if(!verts) return false;
  196. const Point& p0 = verts[mVRef[0]];
  197. const Point& p1 = verts[mVRef[1]];
  198. const Point& p2 = verts[mVRef[2]];
  199. // Compute base
  200. // Point Base = (p0 + p1 + p2)*INV3;
  201. // Compute denormalized normal
  202. Point Normal = (p2 - p1)^(p0 - p1);
  203. // Backface culling
  204. // return (Normal | (source - Base)) >= 0.0f;
  205. return (Normal | (source - p0)) >= 0.0f;
  206. // Same as: (but a bit faster)
  207. // Plane PL(verts[mVRef[0]], verts[mVRef[1]], verts[mVRef[2]]);
  208. // return PL.Distance(source)>0.0f;
  209. }
  210. ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  211. /**
  212. * Computes the occlusion potential of the triangle.
  213. * \param verts [in] the list of indexed vertices
  214. * \param source [in] source point (in local space) from which occlusion potential must be computed
  215. * \return the occlusion potential
  216. */
  217. ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  218. float IndexedTriangle::ComputeOcclusionPotential(const Point* verts, const Point& view) const
  219. {
  220. if(!verts) return 0.0f;
  221. // Occlusion potential: -(A * (N|V) / d^2)
  222. // A = polygon area
  223. // N = polygon normal
  224. // V = view vector
  225. // d = distance viewpoint-center of polygon
  226. float A = Area(verts);
  227. Point N; Normal(verts, N);
  228. Point C; Center(verts, C);
  229. float d = view.Distance(C);
  230. return -(A*(N|view))/(d*d);
  231. }
  232. ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  233. /**
  234. * Replaces a vertex reference with another one.
  235. * \param oldref [in] the vertex reference to replace
  236. * \param newref [in] the new vertex reference
  237. * \return true if success, else false if the input vertex reference doesn't belong to the triangle
  238. */
  239. ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  240. bool IndexedTriangle::ReplaceVertex(udword oldref, udword newref)
  241. {
  242. if(mVRef[0]==oldref) { mVRef[0] = newref; return true; }
  243. else if(mVRef[1]==oldref) { mVRef[1] = newref; return true; }
  244. else if(mVRef[2]==oldref) { mVRef[2] = newref; return true; }
  245. return false;
  246. }
  247. ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  248. /**
  249. * Checks whether the triangle is degenerate or not. A degenerate triangle has two common vertex references. This is a zero-area triangle.
  250. * \return true if the triangle is degenerate
  251. */
  252. ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  253. bool IndexedTriangle::IsDegenerate() const
  254. {
  255. if(mVRef[0]==mVRef[1]) return true;
  256. if(mVRef[1]==mVRef[2]) return true;
  257. if(mVRef[2]==mVRef[0]) return true;
  258. return false;
  259. }
  260. ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  261. /**
  262. * Checks whether the input vertex reference belongs to the triangle or not.
  263. * \param ref [in] the vertex reference to look for
  264. * \return true if the triangle contains the vertex reference
  265. */
  266. ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  267. bool IndexedTriangle::HasVertex(udword ref) const
  268. {
  269. if(mVRef[0]==ref) return true;
  270. if(mVRef[1]==ref) return true;
  271. if(mVRef[2]==ref) return true;
  272. return false;
  273. }
  274. ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  275. /**
  276. * Checks whether the input vertex reference belongs to the triangle or not.
  277. * \param ref [in] the vertex reference to look for
  278. * \param index [out] the corresponding index in the triangle
  279. * \return true if the triangle contains the vertex reference
  280. */
  281. ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  282. bool IndexedTriangle::HasVertex(udword ref, udword* index) const
  283. {
  284. if(mVRef[0]==ref) { *index = 0; return true; }
  285. if(mVRef[1]==ref) { *index = 1; return true; }
  286. if(mVRef[2]==ref) { *index = 2; return true; }
  287. return false;
  288. }
  289. ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  290. /**
  291. * Finds an edge in a tri, given two vertex references.
  292. * \param vref0 [in] the edge's first vertex reference
  293. * \param vref1 [in] the edge's second vertex reference
  294. * \return the edge number between 0 and 2, or 0xff if input refs are wrong.
  295. */
  296. ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  297. ubyte IndexedTriangle::FindEdge(udword vref0, udword vref1) const
  298. {
  299. if(mVRef[0]==vref0 && mVRef[1]==vref1) return 0;
  300. else if(mVRef[0]==vref1 && mVRef[1]==vref0) return 0;
  301. else if(mVRef[0]==vref0 && mVRef[2]==vref1) return 1;
  302. else if(mVRef[0]==vref1 && mVRef[2]==vref0) return 1;
  303. else if(mVRef[1]==vref0 && mVRef[2]==vref1) return 2;
  304. else if(mVRef[1]==vref1 && mVRef[2]==vref0) return 2;
  305. return 0xff;
  306. }
  307. ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  308. /**
  309. * Gets the last reference given the first two.
  310. * \param vref0 [in] the first vertex reference
  311. * \param vref1 [in] the second vertex reference
  312. * \return the last reference, or INVALID_ID_OPC if input refs are wrong.
  313. */
  314. ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  315. udword IndexedTriangle::OppositeVertex(udword vref0, udword vref1) const
  316. {
  317. if(mVRef[0]==vref0 && mVRef[1]==vref1) return mVRef[2];
  318. else if(mVRef[0]==vref1 && mVRef[1]==vref0) return mVRef[2];
  319. else if(mVRef[0]==vref0 && mVRef[2]==vref1) return mVRef[1];
  320. else if(mVRef[0]==vref1 && mVRef[2]==vref0) return mVRef[1];
  321. else if(mVRef[1]==vref0 && mVRef[2]==vref1) return mVRef[0];
  322. else if(mVRef[1]==vref1 && mVRef[2]==vref0) return mVRef[0];
  323. return INVALID_ID_OPC;
  324. }
  325. ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  326. /**
  327. * Gets the three sorted vertex references according to an edge number.
  328. * edgenb = 0 => edge 0-1, returns references 0, 1, 2
  329. * edgenb = 1 => edge 0-2, returns references 0, 2, 1
  330. * edgenb = 2 => edge 1-2, returns references 1, 2, 0
  331. *
  332. * \param edgenb [in] the edge number, 0, 1 or 2
  333. * \param vref0 [out] the returned first vertex reference
  334. * \param vref1 [out] the returned second vertex reference
  335. * \param vref2 [out] the returned third vertex reference
  336. */
  337. ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  338. void IndexedTriangle::GetVRefs(ubyte edgenb, udword& vref0, udword& vref1, udword& vref2) const
  339. {
  340. if(edgenb==0)
  341. {
  342. vref0 = mVRef[0];
  343. vref1 = mVRef[1];
  344. vref2 = mVRef[2];
  345. }
  346. else if(edgenb==1)
  347. {
  348. vref0 = mVRef[0];
  349. vref1 = mVRef[2];
  350. vref2 = mVRef[1];
  351. }
  352. else if(edgenb==2)
  353. {
  354. vref0 = mVRef[1];
  355. vref1 = mVRef[2];
  356. vref2 = mVRef[0];
  357. }
  358. }
  359. ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  360. /**
  361. * Computes the triangle's smallest edge length.
  362. * \param verts [in] the list of indexed vertices
  363. * \return the smallest edge length
  364. */
  365. ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  366. float IndexedTriangle::MinEdgeLength(const Point* verts) const
  367. {
  368. if(!verts) return 0.0f;
  369. float Min = MAX_FLOAT;
  370. float Length01 = verts[0].Distance(verts[1]);
  371. float Length02 = verts[0].Distance(verts[2]);
  372. float Length12 = verts[1].Distance(verts[2]);
  373. if(Length01 < Min) Min = Length01;
  374. if(Length02 < Min) Min = Length02;
  375. if(Length12 < Min) Min = Length12;
  376. return Min;
  377. }
  378. ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  379. /**
  380. * Computes the triangle's largest edge length.
  381. * \param verts [in] the list of indexed vertices
  382. * \return the largest edge length
  383. */
  384. ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  385. float IndexedTriangle::MaxEdgeLength(const Point* verts) const
  386. {
  387. if(!verts) return 0.0f;
  388. float Max = MIN_FLOAT;
  389. float Length01 = verts[0].Distance(verts[1]);
  390. float Length02 = verts[0].Distance(verts[2]);
  391. float Length12 = verts[1].Distance(verts[2]);
  392. if(Length01 > Max) Max = Length01;
  393. if(Length02 > Max) Max = Length02;
  394. if(Length12 > Max) Max = Length12;
  395. return Max;
  396. }
  397. ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  398. /**
  399. * Computes a point on the triangle according to the stabbing information.
  400. * \param verts [in] the list of indexed vertices
  401. * \param u,v [in] point's barycentric coordinates
  402. * \param pt [out] point on triangle
  403. * \param nearvtx [out] index of nearest vertex
  404. */
  405. ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  406. void IndexedTriangle::ComputePoint(const Point* verts, float u, float v, Point& pt, udword* nearvtx) const
  407. {
  408. // Checkings
  409. if(!verts) return;
  410. // Get face in local or global space
  411. const Point& p0 = verts[mVRef[0]];
  412. const Point& p1 = verts[mVRef[1]];
  413. const Point& p2 = verts[mVRef[2]];
  414. // Compute point coordinates
  415. pt = (1.0f - u - v)*p0 + u*p1 + v*p2;
  416. // Compute nearest vertex if needed
  417. if(nearvtx)
  418. {
  419. // Compute distance vector
  420. Point d(p0.SquareDistance(pt), // Distance^2 from vertex 0 to point on the face
  421. p1.SquareDistance(pt), // Distance^2 from vertex 1 to point on the face
  422. p2.SquareDistance(pt)); // Distance^2 from vertex 2 to point on the face
  423. // Get smallest distance
  424. *nearvtx = mVRef[d.SmallestAxis()];
  425. }
  426. }
  427. //**************************************
  428. // Angle between two vectors (in radians)
  429. // we use this formula
  430. // uv = |u||v| cos(u,v)
  431. // u ^ v = w
  432. // |w| = |u||v| |sin(u,v)|
  433. //**************************************
  434. float Angle(const Point& u, const Point& v)
  435. {
  436. float NormU = u.Magnitude(); // |u|
  437. float NormV = v.Magnitude(); // |v|
  438. float Product = NormU*NormV; // |u||v|
  439. if(Product==0.0f) return 0.0f;
  440. float OneOverProduct = 1.0f / Product;
  441. // Cosinus
  442. float Cosinus = (u|v) * OneOverProduct;
  443. // Sinus
  444. Point w = u^v;
  445. float NormW = w.Magnitude();
  446. float AbsSinus = NormW * OneOverProduct;
  447. // Remove degeneracy
  448. if(AbsSinus > 1.0f) AbsSinus = 1.0f;
  449. if(AbsSinus < -1.0f) AbsSinus = -1.0f;
  450. if(Cosinus>=0.0f) return asinf(AbsSinus);
  451. else return (PI-asinf(AbsSinus));
  452. }
  453. ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  454. /**
  455. * Computes the angle between two triangles.
  456. * \param tri [in] the other triangle
  457. * \param verts [in] the list of indexed vertices
  458. * \return the angle in radians
  459. */
  460. ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  461. float IndexedTriangle::Angle(const IndexedTriangle& tri, const Point* verts) const
  462. {
  463. // Checkings
  464. if(!verts) return 0.0f;
  465. // Compute face normals
  466. Point n0, n1;
  467. Normal(verts, n0);
  468. tri.Normal(verts, n1);
  469. // Compute angle
  470. float dp = n0|n1;
  471. if(dp>1.0f) return 0.0f;
  472. if(dp<-1.0f) return PI;
  473. return acosf(dp);
  474. // return ::Angle(n0,n1);
  475. }
  476. ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  477. /**
  478. * Checks a triangle is the same as another one.
  479. * \param tri [in] the other triangle
  480. * \return true if same triangle
  481. */
  482. ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  483. bool IndexedTriangle::Equal(const IndexedTriangle& tri) const
  484. {
  485. // Test all vertex references
  486. return (HasVertex(tri.mVRef[0]) &&
  487. HasVertex(tri.mVRef[1]) &&
  488. HasVertex(tri.mVRef[2]));
  489. }