/src/FreeImage/Source/OpenEXR/Imath/ImathBox.h

https://bitbucket.org/cabalistic/ogredeps/ · C++ Header · 787 lines · 467 code · 194 blank · 126 comment · 92 complexity · 07ffe004658862ac32d1f71ef4968094 MD5 · raw file

  1. ///////////////////////////////////////////////////////////////////////////
  2. //
  3. // Copyright (c) 2004, Industrial Light & Magic, a division of Lucas
  4. // Digital Ltd. LLC
  5. //
  6. // All rights reserved.
  7. //
  8. // Redistribution and use in source and binary forms, with or without
  9. // modification, are permitted provided that the following conditions are
  10. // met:
  11. // * Redistributions of source code must retain the above copyright
  12. // notice, this list of conditions and the following disclaimer.
  13. // * Redistributions in binary form must reproduce the above
  14. // copyright notice, this list of conditions and the following disclaimer
  15. // in the documentation and/or other materials provided with the
  16. // distribution.
  17. // * Neither the name of Industrial Light & Magic nor the names of
  18. // its contributors may be used to endorse or promote products derived
  19. // from this software without specific prior written permission.
  20. //
  21. // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  22. // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  23. // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
  24. // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
  25. // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  26. // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
  27. // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  28. // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
  29. // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  30. // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
  31. // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  32. //
  33. ///////////////////////////////////////////////////////////////////////////
  34. #ifndef INCLUDED_IMATHBOX_H
  35. #define INCLUDED_IMATHBOX_H
  36. //-------------------------------------------------------------------
  37. //
  38. // class Imath::Box<class T>
  39. // --------------------------------
  40. //
  41. // This class imposes the following requirements on its
  42. // parameter class:
  43. //
  44. // 1) The class T must implement these operators:
  45. // + - < > <= >= =
  46. // with the signature (T,T) and the expected
  47. // return values for a numeric type.
  48. //
  49. // 2) The class T must implement operator=
  50. // with the signature (T,float and/or double)
  51. //
  52. // 3) The class T must have a constructor which takes
  53. // a float (and/or double) for use in initializing the box.
  54. //
  55. // 4) The class T must have a function T::dimensions()
  56. // which returns the number of dimensions in the class
  57. // (since its assumed its a vector) -- preferably, this
  58. // returns a constant expression.
  59. //
  60. //-------------------------------------------------------------------
  61. #include "ImathVec.h"
  62. namespace Imath {
  63. template <class T>
  64. class Box
  65. {
  66. public:
  67. //-------------------------
  68. // Data Members are public
  69. //-------------------------
  70. T min;
  71. T max;
  72. //-----------------------------------------------------
  73. // Constructors - an "empty" box is created by default
  74. //-----------------------------------------------------
  75. Box ();
  76. Box (const T &point);
  77. Box (const T &minT, const T &maxT);
  78. //--------------------
  79. // Operators: ==, !=
  80. //--------------------
  81. bool operator == (const Box<T> &src) const;
  82. bool operator != (const Box<T> &src) const;
  83. //------------------
  84. // Box manipulation
  85. //------------------
  86. void makeEmpty ();
  87. void extendBy (const T &point);
  88. void extendBy (const Box<T> &box);
  89. //---------------------------------------------------
  90. // Query functions - these compute results each time
  91. //---------------------------------------------------
  92. T size () const;
  93. T center () const;
  94. bool intersects (const T &point) const;
  95. bool intersects (const Box<T> &box) const;
  96. unsigned int majorAxis () const;
  97. //----------------
  98. // Classification
  99. //----------------
  100. bool isEmpty () const;
  101. bool hasVolume () const;
  102. };
  103. //--------------------
  104. // Convenient typedefs
  105. //--------------------
  106. typedef Box <V2s> Box2s;
  107. typedef Box <V2i> Box2i;
  108. typedef Box <V2f> Box2f;
  109. typedef Box <V2d> Box2d;
  110. typedef Box <V3s> Box3s;
  111. typedef Box <V3i> Box3i;
  112. typedef Box <V3f> Box3f;
  113. typedef Box <V3d> Box3d;
  114. //----------------
  115. // Implementation
  116. template <class T>
  117. inline Box<T>::Box()
  118. {
  119. makeEmpty();
  120. }
  121. template <class T>
  122. inline Box<T>::Box (const T &point)
  123. {
  124. min = point;
  125. max = point;
  126. }
  127. template <class T>
  128. inline Box<T>::Box (const T &minT, const T &maxT)
  129. {
  130. min = minT;
  131. max = maxT;
  132. }
  133. template <class T>
  134. inline bool
  135. Box<T>::operator == (const Box<T> &src) const
  136. {
  137. return (min == src.min && max == src.max);
  138. }
  139. template <class T>
  140. inline bool
  141. Box<T>::operator != (const Box<T> &src) const
  142. {
  143. return (min != src.min || max != src.max);
  144. }
  145. template <class T>
  146. inline void Box<T>::makeEmpty()
  147. {
  148. min = T(T::baseTypeMax());
  149. max = T(T::baseTypeMin());
  150. }
  151. template <class T>
  152. inline void
  153. Box<T>::extendBy(const T &point)
  154. {
  155. for (unsigned int i = 0; i < min.dimensions(); i++)
  156. {
  157. if (point[i] < min[i])
  158. min[i] = point[i];
  159. if (point[i] > max[i])
  160. max[i] = point[i];
  161. }
  162. }
  163. template <class T>
  164. inline void
  165. Box<T>::extendBy(const Box<T> &box)
  166. {
  167. for (unsigned int i = 0; i < min.dimensions(); i++)
  168. {
  169. if (box.min[i] < min[i])
  170. min[i] = box.min[i];
  171. if (box.max[i] > max[i])
  172. max[i] = box.max[i];
  173. }
  174. }
  175. template <class T>
  176. inline bool
  177. Box<T>::intersects(const T &point) const
  178. {
  179. for (unsigned int i = 0; i < min.dimensions(); i++)
  180. {
  181. if (point[i] < min[i] || point[i] > max[i])
  182. return false;
  183. }
  184. return true;
  185. }
  186. template <class T>
  187. inline bool
  188. Box<T>::intersects(const Box<T> &box) const
  189. {
  190. for (unsigned int i = 0; i < min.dimensions(); i++)
  191. {
  192. if (box.max[i] < min[i] || box.min[i] > max[i])
  193. return false;
  194. }
  195. return true;
  196. }
  197. template <class T>
  198. inline T
  199. Box<T>::size() const
  200. {
  201. if (isEmpty())
  202. return T (0);
  203. return max - min;
  204. }
  205. template <class T>
  206. inline T
  207. Box<T>::center() const
  208. {
  209. return (max + min) / 2;
  210. }
  211. template <class T>
  212. inline bool
  213. Box<T>::isEmpty() const
  214. {
  215. for (unsigned int i = 0; i < min.dimensions(); i++)
  216. {
  217. if (max[i] < min[i])
  218. return true;
  219. }
  220. return false;
  221. }
  222. template <class T>
  223. inline bool
  224. Box<T>::hasVolume() const
  225. {
  226. for (unsigned int i = 0; i < min.dimensions(); i++)
  227. {
  228. if (max[i] <= min[i])
  229. return false;
  230. }
  231. return true;
  232. }
  233. template<class T>
  234. inline unsigned int
  235. Box<T>::majorAxis() const
  236. {
  237. unsigned int major = 0;
  238. T s = size();
  239. for (unsigned int i = 1; i < min.dimensions(); i++)
  240. {
  241. if (s[i] > s[major])
  242. major = i;
  243. }
  244. return major;
  245. }
  246. //-------------------------------------------------------------------
  247. //
  248. // Partial class specializations for Imath::Vec2<T> and Imath::Vec3<T>
  249. //
  250. //-------------------------------------------------------------------
  251. template <typename T> class Box;
  252. template <class T>
  253. class Box<Vec2<T> >
  254. {
  255. public:
  256. //-------------------------
  257. // Data Members are public
  258. //-------------------------
  259. Vec2<T> min;
  260. Vec2<T> max;
  261. //-----------------------------------------------------
  262. // Constructors - an "empty" box is created by default
  263. //-----------------------------------------------------
  264. Box();
  265. Box (const Vec2<T> &point);
  266. Box (const Vec2<T> &minT, const Vec2<T> &maxT);
  267. //--------------------
  268. // Operators: ==, !=
  269. //--------------------
  270. bool operator == (const Box<Vec2<T> > &src) const;
  271. bool operator != (const Box<Vec2<T> > &src) const;
  272. //------------------
  273. // Box manipulation
  274. //------------------
  275. void makeEmpty();
  276. void extendBy (const Vec2<T> &point);
  277. void extendBy (const Box<Vec2<T> > &box);
  278. //---------------------------------------------------
  279. // Query functions - these compute results each time
  280. //---------------------------------------------------
  281. Vec2<T> size() const;
  282. Vec2<T> center() const;
  283. bool intersects (const Vec2<T> &point) const;
  284. bool intersects (const Box<Vec2<T> > &box) const;
  285. unsigned int majorAxis() const;
  286. //----------------
  287. // Classification
  288. //----------------
  289. bool isEmpty() const;
  290. bool hasVolume() const;
  291. };
  292. //----------------
  293. // Implementation
  294. template <class T>
  295. inline Box<Vec2<T> >::Box()
  296. {
  297. makeEmpty();
  298. }
  299. template <class T>
  300. inline Box<Vec2<T> >::Box (const Vec2<T> &point)
  301. {
  302. min = point;
  303. max = point;
  304. }
  305. template <class T>
  306. inline Box<Vec2<T> >::Box (const Vec2<T> &minT, const Vec2<T> &maxT)
  307. {
  308. min = minT;
  309. max = maxT;
  310. }
  311. template <class T>
  312. inline bool
  313. Box<Vec2<T> >::operator == (const Box<Vec2<T> > &src) const
  314. {
  315. return (min == src.min && max == src.max);
  316. }
  317. template <class T>
  318. inline bool
  319. Box<Vec2<T> >::operator != (const Box<Vec2<T> > &src) const
  320. {
  321. return (min != src.min || max != src.max);
  322. }
  323. template <class T>
  324. inline void Box<Vec2<T> >::makeEmpty()
  325. {
  326. min = Vec2<T>(Vec2<T>::baseTypeMax());
  327. max = Vec2<T>(Vec2<T>::baseTypeMin());
  328. }
  329. template <class T>
  330. inline void
  331. Box<Vec2<T> >::extendBy (const Vec2<T> &point)
  332. {
  333. if (point[0] < min[0])
  334. min[0] = point[0];
  335. if (point[0] > max[0])
  336. max[0] = point[0];
  337. if (point[1] < min[1])
  338. min[1] = point[1];
  339. if (point[1] > max[1])
  340. max[1] = point[1];
  341. }
  342. template <class T>
  343. inline void
  344. Box<Vec2<T> >::extendBy (const Box<Vec2<T> > &box)
  345. {
  346. if (box.min[0] < min[0])
  347. min[0] = box.min[0];
  348. if (box.max[0] > max[0])
  349. max[0] = box.max[0];
  350. if (box.min[1] < min[1])
  351. min[1] = box.min[1];
  352. if (box.max[1] > max[1])
  353. max[1] = box.max[1];
  354. }
  355. template <class T>
  356. inline bool
  357. Box<Vec2<T> >::intersects (const Vec2<T> &point) const
  358. {
  359. if (point[0] < min[0] || point[0] > max[0] ||
  360. point[1] < min[1] || point[1] > max[1])
  361. return false;
  362. return true;
  363. }
  364. template <class T>
  365. inline bool
  366. Box<Vec2<T> >::intersects (const Box<Vec2<T> > &box) const
  367. {
  368. if (box.max[0] < min[0] || box.min[0] > max[0] ||
  369. box.max[1] < min[1] || box.min[1] > max[1])
  370. return false;
  371. return true;
  372. }
  373. template <class T>
  374. inline Vec2<T>
  375. Box<Vec2<T> >::size() const
  376. {
  377. if (isEmpty())
  378. return Vec2<T> (0);
  379. return max - min;
  380. }
  381. template <class T>
  382. inline Vec2<T>
  383. Box<Vec2<T> >::center() const
  384. {
  385. return (max + min) / 2;
  386. }
  387. template <class T>
  388. inline bool
  389. Box<Vec2<T> >::isEmpty() const
  390. {
  391. if (max[0] < min[0] ||
  392. max[1] < min[1])
  393. return true;
  394. return false;
  395. }
  396. template <class T>
  397. inline bool
  398. Box<Vec2<T> >::hasVolume() const
  399. {
  400. if (max[0] <= min[0] ||
  401. max[1] <= min[1])
  402. return false;
  403. return true;
  404. }
  405. template <class T>
  406. inline unsigned int
  407. Box<Vec2<T> >::majorAxis() const
  408. {
  409. unsigned int major = 0;
  410. Vec2<T> s = size();
  411. if (s[1] > s[major])
  412. major = 1;
  413. return major;
  414. }
  415. template <class T>
  416. class Box<Vec3<T> >
  417. {
  418. public:
  419. //-------------------------
  420. // Data Members are public
  421. //-------------------------
  422. Vec3<T> min;
  423. Vec3<T> max;
  424. //-----------------------------------------------------
  425. // Constructors - an "empty" box is created by default
  426. //-----------------------------------------------------
  427. Box();
  428. Box (const Vec3<T> &point);
  429. Box (const Vec3<T> &minT, const Vec3<T> &maxT);
  430. //--------------------
  431. // Operators: ==, !=
  432. //--------------------
  433. bool operator == (const Box<Vec3<T> > &src) const;
  434. bool operator != (const Box<Vec3<T> > &src) const;
  435. //------------------
  436. // Box manipulation
  437. //------------------
  438. void makeEmpty();
  439. void extendBy (const Vec3<T> &point);
  440. void extendBy (const Box<Vec3<T> > &box);
  441. //---------------------------------------------------
  442. // Query functions - these compute results each time
  443. //---------------------------------------------------
  444. Vec3<T> size() const;
  445. Vec3<T> center() const;
  446. bool intersects (const Vec3<T> &point) const;
  447. bool intersects (const Box<Vec3<T> > &box) const;
  448. unsigned int majorAxis() const;
  449. //----------------
  450. // Classification
  451. //----------------
  452. bool isEmpty() const;
  453. bool hasVolume() const;
  454. };
  455. //----------------
  456. // Implementation
  457. template <class T>
  458. inline Box<Vec3<T> >::Box()
  459. {
  460. makeEmpty();
  461. }
  462. template <class T>
  463. inline Box<Vec3<T> >::Box (const Vec3<T> &point)
  464. {
  465. min = point;
  466. max = point;
  467. }
  468. template <class T>
  469. inline Box<Vec3<T> >::Box (const Vec3<T> &minT, const Vec3<T> &maxT)
  470. {
  471. min = minT;
  472. max = maxT;
  473. }
  474. template <class T>
  475. inline bool
  476. Box<Vec3<T> >::operator == (const Box<Vec3<T> > &src) const
  477. {
  478. return (min == src.min && max == src.max);
  479. }
  480. template <class T>
  481. inline bool
  482. Box<Vec3<T> >::operator != (const Box<Vec3<T> > &src) const
  483. {
  484. return (min != src.min || max != src.max);
  485. }
  486. template <class T>
  487. inline void Box<Vec3<T> >::makeEmpty()
  488. {
  489. min = Vec3<T>(Vec3<T>::baseTypeMax());
  490. max = Vec3<T>(Vec3<T>::baseTypeMin());
  491. }
  492. template <class T>
  493. inline void
  494. Box<Vec3<T> >::extendBy (const Vec3<T> &point)
  495. {
  496. if (point[0] < min[0])
  497. min[0] = point[0];
  498. if (point[0] > max[0])
  499. max[0] = point[0];
  500. if (point[1] < min[1])
  501. min[1] = point[1];
  502. if (point[1] > max[1])
  503. max[1] = point[1];
  504. if (point[2] < min[2])
  505. min[2] = point[2];
  506. if (point[2] > max[2])
  507. max[2] = point[2];
  508. }
  509. template <class T>
  510. inline void
  511. Box<Vec3<T> >::extendBy (const Box<Vec3<T> > &box)
  512. {
  513. if (box.min[0] < min[0])
  514. min[0] = box.min[0];
  515. if (box.max[0] > max[0])
  516. max[0] = box.max[0];
  517. if (box.min[1] < min[1])
  518. min[1] = box.min[1];
  519. if (box.max[1] > max[1])
  520. max[1] = box.max[1];
  521. if (box.min[2] < min[2])
  522. min[2] = box.min[2];
  523. if (box.max[2] > max[2])
  524. max[2] = box.max[2];
  525. }
  526. template <class T>
  527. inline bool
  528. Box<Vec3<T> >::intersects (const Vec3<T> &point) const
  529. {
  530. if (point[0] < min[0] || point[0] > max[0] ||
  531. point[1] < min[1] || point[1] > max[1] ||
  532. point[2] < min[2] || point[2] > max[2])
  533. return false;
  534. return true;
  535. }
  536. template <class T>
  537. inline bool
  538. Box<Vec3<T> >::intersects (const Box<Vec3<T> > &box) const
  539. {
  540. if (box.max[0] < min[0] || box.min[0] > max[0] ||
  541. box.max[1] < min[1] || box.min[1] > max[1] ||
  542. box.max[2] < min[2] || box.min[2] > max[2])
  543. return false;
  544. return true;
  545. }
  546. template <class T>
  547. inline Vec3<T>
  548. Box<Vec3<T> >::size() const
  549. {
  550. if (isEmpty())
  551. return Vec3<T> (0);
  552. return max - min;
  553. }
  554. template <class T>
  555. inline Vec3<T>
  556. Box<Vec3<T> >::center() const
  557. {
  558. return (max + min) / 2;
  559. }
  560. template <class T>
  561. inline bool
  562. Box<Vec3<T> >::isEmpty() const
  563. {
  564. if (max[0] < min[0] ||
  565. max[1] < min[1] ||
  566. max[2] < min[2])
  567. return true;
  568. return false;
  569. }
  570. template <class T>
  571. inline bool
  572. Box<Vec3<T> >::hasVolume() const
  573. {
  574. if (max[0] <= min[0] ||
  575. max[1] <= min[1] ||
  576. max[2] <= min[2])
  577. return false;
  578. return true;
  579. }
  580. template <class T>
  581. inline unsigned int
  582. Box<Vec3<T> >::majorAxis() const
  583. {
  584. unsigned int major = 0;
  585. Vec3<T> s = size();
  586. if (s[1] > s[major])
  587. major = 1;
  588. if (s[2] > s[major])
  589. major = 2;
  590. return major;
  591. }
  592. } // namespace Imath
  593. #endif