IceIndexedTriangle.cpp 24 KB

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