ImathBox.h 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849
  1. ///////////////////////////////////////////////////////////////////////////
  2. //
  3. // Copyright (c) 2004-2012, 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. #include "ImathNamespace.h"
  63. IMATH_INTERNAL_NAMESPACE_HEADER_ENTER
  64. template <class T>
  65. class Box
  66. {
  67. public:
  68. //-------------------------
  69. // Data Members are public
  70. //-------------------------
  71. T min;
  72. T max;
  73. //-----------------------------------------------------
  74. // Constructors - an "empty" box is created by default
  75. //-----------------------------------------------------
  76. Box ();
  77. Box (const T &point);
  78. Box (const T &minT, const T &maxT);
  79. //--------------------
  80. // Operators: ==, !=
  81. //--------------------
  82. bool operator == (const Box<T> &src) const;
  83. bool operator != (const Box<T> &src) const;
  84. //------------------
  85. // Box manipulation
  86. //------------------
  87. void makeEmpty ();
  88. void extendBy (const T &point);
  89. void extendBy (const Box<T> &box);
  90. void makeInfinite ();
  91. //---------------------------------------------------
  92. // Query functions - these compute results each time
  93. //---------------------------------------------------
  94. T size () const;
  95. T center () const;
  96. bool intersects (const T &point) const;
  97. bool intersects (const Box<T> &box) const;
  98. unsigned int majorAxis () const;
  99. //----------------
  100. // Classification
  101. //----------------
  102. bool isEmpty () const;
  103. bool hasVolume () const;
  104. bool isInfinite () const;
  105. };
  106. //--------------------
  107. // Convenient typedefs
  108. //--------------------
  109. typedef Box <V2s> Box2s;
  110. typedef Box <V2i> Box2i;
  111. typedef Box <V2f> Box2f;
  112. typedef Box <V2d> Box2d;
  113. typedef Box <V3s> Box3s;
  114. typedef Box <V3i> Box3i;
  115. typedef Box <V3f> Box3f;
  116. typedef Box <V3d> Box3d;
  117. //----------------
  118. // Implementation
  119. template <class T>
  120. inline Box<T>::Box()
  121. {
  122. makeEmpty();
  123. }
  124. template <class T>
  125. inline Box<T>::Box (const T &point)
  126. {
  127. min = point;
  128. max = point;
  129. }
  130. template <class T>
  131. inline Box<T>::Box (const T &minT, const T &maxT)
  132. {
  133. min = minT;
  134. max = maxT;
  135. }
  136. template <class T>
  137. inline bool
  138. Box<T>::operator == (const Box<T> &src) const
  139. {
  140. return (min == src.min && max == src.max);
  141. }
  142. template <class T>
  143. inline bool
  144. Box<T>::operator != (const Box<T> &src) const
  145. {
  146. return (min != src.min || max != src.max);
  147. }
  148. template <class T>
  149. inline void Box<T>::makeEmpty()
  150. {
  151. min = T(T::baseTypeMax());
  152. max = T(T::baseTypeMin());
  153. }
  154. template <class T>
  155. inline void Box<T>::makeInfinite()
  156. {
  157. min = T(T::baseTypeMin());
  158. max = T(T::baseTypeMax());
  159. }
  160. template <class T>
  161. inline void
  162. Box<T>::extendBy(const T &point)
  163. {
  164. for (unsigned int i = 0; i < min.dimensions(); i++)
  165. {
  166. if (point[i] < min[i])
  167. min[i] = point[i];
  168. if (point[i] > max[i])
  169. max[i] = point[i];
  170. }
  171. }
  172. template <class T>
  173. inline void
  174. Box<T>::extendBy(const Box<T> &box)
  175. {
  176. for (unsigned int i = 0; i < min.dimensions(); i++)
  177. {
  178. if (box.min[i] < min[i])
  179. min[i] = box.min[i];
  180. if (box.max[i] > max[i])
  181. max[i] = box.max[i];
  182. }
  183. }
  184. template <class T>
  185. inline bool
  186. Box<T>::intersects(const T &point) const
  187. {
  188. for (unsigned int i = 0; i < min.dimensions(); i++)
  189. {
  190. if (point[i] < min[i] || point[i] > max[i])
  191. return false;
  192. }
  193. return true;
  194. }
  195. template <class T>
  196. inline bool
  197. Box<T>::intersects(const Box<T> &box) const
  198. {
  199. for (unsigned int i = 0; i < min.dimensions(); i++)
  200. {
  201. if (box.max[i] < min[i] || box.min[i] > max[i])
  202. return false;
  203. }
  204. return true;
  205. }
  206. template <class T>
  207. inline T
  208. Box<T>::size() const
  209. {
  210. if (isEmpty())
  211. return T (0);
  212. return max - min;
  213. }
  214. template <class T>
  215. inline T
  216. Box<T>::center() const
  217. {
  218. return (max + min) / 2;
  219. }
  220. template <class T>
  221. inline bool
  222. Box<T>::isEmpty() const
  223. {
  224. for (unsigned int i = 0; i < min.dimensions(); i++)
  225. {
  226. if (max[i] < min[i])
  227. return true;
  228. }
  229. return false;
  230. }
  231. template <class T>
  232. inline bool
  233. Box<T>::isInfinite() const
  234. {
  235. for (unsigned int i = 0; i < min.dimensions(); i++)
  236. {
  237. if (min[i] != T::baseTypeMin() || max[i] != T::baseTypeMax())
  238. return false;
  239. }
  240. return true;
  241. }
  242. template <class T>
  243. inline bool
  244. Box<T>::hasVolume() const
  245. {
  246. for (unsigned int i = 0; i < min.dimensions(); i++)
  247. {
  248. if (max[i] <= min[i])
  249. return false;
  250. }
  251. return true;
  252. }
  253. template<class T>
  254. inline unsigned int
  255. Box<T>::majorAxis() const
  256. {
  257. unsigned int major = 0;
  258. T s = size();
  259. for (unsigned int i = 1; i < min.dimensions(); i++)
  260. {
  261. if (s[i] > s[major])
  262. major = i;
  263. }
  264. return major;
  265. }
  266. //-------------------------------------------------------------------
  267. //
  268. // Partial class specializations for Imath::Vec2<T> and Imath::Vec3<T>
  269. //
  270. //-------------------------------------------------------------------
  271. template <typename T> class Box;
  272. template <class T>
  273. class Box<Vec2<T> >
  274. {
  275. public:
  276. //-------------------------
  277. // Data Members are public
  278. //-------------------------
  279. Vec2<T> min;
  280. Vec2<T> max;
  281. //-----------------------------------------------------
  282. // Constructors - an "empty" box is created by default
  283. //-----------------------------------------------------
  284. Box();
  285. Box (const Vec2<T> &point);
  286. Box (const Vec2<T> &minT, const Vec2<T> &maxT);
  287. //--------------------
  288. // Operators: ==, !=
  289. //--------------------
  290. bool operator == (const Box<Vec2<T> > &src) const;
  291. bool operator != (const Box<Vec2<T> > &src) const;
  292. //------------------
  293. // Box manipulation
  294. //------------------
  295. void makeEmpty();
  296. void extendBy (const Vec2<T> &point);
  297. void extendBy (const Box<Vec2<T> > &box);
  298. void makeInfinite();
  299. //---------------------------------------------------
  300. // Query functions - these compute results each time
  301. //---------------------------------------------------
  302. Vec2<T> size() const;
  303. Vec2<T> center() const;
  304. bool intersects (const Vec2<T> &point) const;
  305. bool intersects (const Box<Vec2<T> > &box) const;
  306. unsigned int majorAxis() const;
  307. //----------------
  308. // Classification
  309. //----------------
  310. bool isEmpty() const;
  311. bool hasVolume() const;
  312. bool isInfinite() const;
  313. };
  314. //----------------
  315. // Implementation
  316. template <class T>
  317. inline Box<Vec2<T> >::Box()
  318. {
  319. makeEmpty();
  320. }
  321. template <class T>
  322. inline Box<Vec2<T> >::Box (const Vec2<T> &point)
  323. {
  324. min = point;
  325. max = point;
  326. }
  327. template <class T>
  328. inline Box<Vec2<T> >::Box (const Vec2<T> &minT, const Vec2<T> &maxT)
  329. {
  330. min = minT;
  331. max = maxT;
  332. }
  333. template <class T>
  334. inline bool
  335. Box<Vec2<T> >::operator == (const Box<Vec2<T> > &src) const
  336. {
  337. return (min == src.min && max == src.max);
  338. }
  339. template <class T>
  340. inline bool
  341. Box<Vec2<T> >::operator != (const Box<Vec2<T> > &src) const
  342. {
  343. return (min != src.min || max != src.max);
  344. }
  345. template <class T>
  346. inline void Box<Vec2<T> >::makeEmpty()
  347. {
  348. min = Vec2<T>(Vec2<T>::baseTypeMax());
  349. max = Vec2<T>(Vec2<T>::baseTypeMin());
  350. }
  351. template <class T>
  352. inline void Box<Vec2<T> >::makeInfinite()
  353. {
  354. min = Vec2<T>(Vec2<T>::baseTypeMin());
  355. max = Vec2<T>(Vec2<T>::baseTypeMax());
  356. }
  357. template <class T>
  358. inline void
  359. Box<Vec2<T> >::extendBy (const Vec2<T> &point)
  360. {
  361. if (point[0] < min[0])
  362. min[0] = point[0];
  363. if (point[0] > max[0])
  364. max[0] = point[0];
  365. if (point[1] < min[1])
  366. min[1] = point[1];
  367. if (point[1] > max[1])
  368. max[1] = point[1];
  369. }
  370. template <class T>
  371. inline void
  372. Box<Vec2<T> >::extendBy (const Box<Vec2<T> > &box)
  373. {
  374. if (box.min[0] < min[0])
  375. min[0] = box.min[0];
  376. if (box.max[0] > max[0])
  377. max[0] = box.max[0];
  378. if (box.min[1] < min[1])
  379. min[1] = box.min[1];
  380. if (box.max[1] > max[1])
  381. max[1] = box.max[1];
  382. }
  383. template <class T>
  384. inline bool
  385. Box<Vec2<T> >::intersects (const Vec2<T> &point) const
  386. {
  387. if (point[0] < min[0] || point[0] > max[0] ||
  388. point[1] < min[1] || point[1] > max[1])
  389. return false;
  390. return true;
  391. }
  392. template <class T>
  393. inline bool
  394. Box<Vec2<T> >::intersects (const Box<Vec2<T> > &box) const
  395. {
  396. if (box.max[0] < min[0] || box.min[0] > max[0] ||
  397. box.max[1] < min[1] || box.min[1] > max[1])
  398. return false;
  399. return true;
  400. }
  401. template <class T>
  402. inline Vec2<T>
  403. Box<Vec2<T> >::size() const
  404. {
  405. if (isEmpty())
  406. return Vec2<T> (0);
  407. return max - min;
  408. }
  409. template <class T>
  410. inline Vec2<T>
  411. Box<Vec2<T> >::center() const
  412. {
  413. return (max + min) / 2;
  414. }
  415. template <class T>
  416. inline bool
  417. Box<Vec2<T> >::isEmpty() const
  418. {
  419. if (max[0] < min[0] ||
  420. max[1] < min[1])
  421. return true;
  422. return false;
  423. }
  424. template <class T>
  425. inline bool
  426. Box<Vec2<T> > ::isInfinite() const
  427. {
  428. if (min[0] != limits<T>::min() || max[0] != limits<T>::max() ||
  429. min[1] != limits<T>::min() || max[1] != limits<T>::max())
  430. return false;
  431. return true;
  432. }
  433. template <class T>
  434. inline bool
  435. Box<Vec2<T> >::hasVolume() const
  436. {
  437. if (max[0] <= min[0] ||
  438. max[1] <= min[1])
  439. return false;
  440. return true;
  441. }
  442. template <class T>
  443. inline unsigned int
  444. Box<Vec2<T> >::majorAxis() const
  445. {
  446. unsigned int major = 0;
  447. Vec2<T> s = size();
  448. if (s[1] > s[major])
  449. major = 1;
  450. return major;
  451. }
  452. template <class T>
  453. class Box<Vec3<T> >
  454. {
  455. public:
  456. //-------------------------
  457. // Data Members are public
  458. //-------------------------
  459. Vec3<T> min;
  460. Vec3<T> max;
  461. //-----------------------------------------------------
  462. // Constructors - an "empty" box is created by default
  463. //-----------------------------------------------------
  464. Box();
  465. Box (const Vec3<T> &point);
  466. Box (const Vec3<T> &minT, const Vec3<T> &maxT);
  467. //--------------------
  468. // Operators: ==, !=
  469. //--------------------
  470. bool operator == (const Box<Vec3<T> > &src) const;
  471. bool operator != (const Box<Vec3<T> > &src) const;
  472. //------------------
  473. // Box manipulation
  474. //------------------
  475. void makeEmpty();
  476. void extendBy (const Vec3<T> &point);
  477. void extendBy (const Box<Vec3<T> > &box);
  478. void makeInfinite ();
  479. //---------------------------------------------------
  480. // Query functions - these compute results each time
  481. //---------------------------------------------------
  482. Vec3<T> size() const;
  483. Vec3<T> center() const;
  484. bool intersects (const Vec3<T> &point) const;
  485. bool intersects (const Box<Vec3<T> > &box) const;
  486. unsigned int majorAxis() const;
  487. //----------------
  488. // Classification
  489. //----------------
  490. bool isEmpty() const;
  491. bool hasVolume() const;
  492. bool isInfinite() const;
  493. };
  494. //----------------
  495. // Implementation
  496. template <class T>
  497. inline Box<Vec3<T> >::Box()
  498. {
  499. makeEmpty();
  500. }
  501. template <class T>
  502. inline Box<Vec3<T> >::Box (const Vec3<T> &point)
  503. {
  504. min = point;
  505. max = point;
  506. }
  507. template <class T>
  508. inline Box<Vec3<T> >::Box (const Vec3<T> &minT, const Vec3<T> &maxT)
  509. {
  510. min = minT;
  511. max = maxT;
  512. }
  513. template <class T>
  514. inline bool
  515. Box<Vec3<T> >::operator == (const Box<Vec3<T> > &src) const
  516. {
  517. return (min == src.min && max == src.max);
  518. }
  519. template <class T>
  520. inline bool
  521. Box<Vec3<T> >::operator != (const Box<Vec3<T> > &src) const
  522. {
  523. return (min != src.min || max != src.max);
  524. }
  525. template <class T>
  526. inline void Box<Vec3<T> >::makeEmpty()
  527. {
  528. min = Vec3<T>(Vec3<T>::baseTypeMax());
  529. max = Vec3<T>(Vec3<T>::baseTypeMin());
  530. }
  531. template <class T>
  532. inline void Box<Vec3<T> >::makeInfinite()
  533. {
  534. min = Vec3<T>(Vec3<T>::baseTypeMin());
  535. max = Vec3<T>(Vec3<T>::baseTypeMax());
  536. }
  537. template <class T>
  538. inline void
  539. Box<Vec3<T> >::extendBy (const Vec3<T> &point)
  540. {
  541. if (point[0] < min[0])
  542. min[0] = point[0];
  543. if (point[0] > max[0])
  544. max[0] = point[0];
  545. if (point[1] < min[1])
  546. min[1] = point[1];
  547. if (point[1] > max[1])
  548. max[1] = point[1];
  549. if (point[2] < min[2])
  550. min[2] = point[2];
  551. if (point[2] > max[2])
  552. max[2] = point[2];
  553. }
  554. template <class T>
  555. inline void
  556. Box<Vec3<T> >::extendBy (const Box<Vec3<T> > &box)
  557. {
  558. if (box.min[0] < min[0])
  559. min[0] = box.min[0];
  560. if (box.max[0] > max[0])
  561. max[0] = box.max[0];
  562. if (box.min[1] < min[1])
  563. min[1] = box.min[1];
  564. if (box.max[1] > max[1])
  565. max[1] = box.max[1];
  566. if (box.min[2] < min[2])
  567. min[2] = box.min[2];
  568. if (box.max[2] > max[2])
  569. max[2] = box.max[2];
  570. }
  571. template <class T>
  572. inline bool
  573. Box<Vec3<T> >::intersects (const Vec3<T> &point) const
  574. {
  575. if (point[0] < min[0] || point[0] > max[0] ||
  576. point[1] < min[1] || point[1] > max[1] ||
  577. point[2] < min[2] || point[2] > max[2])
  578. return false;
  579. return true;
  580. }
  581. template <class T>
  582. inline bool
  583. Box<Vec3<T> >::intersects (const Box<Vec3<T> > &box) const
  584. {
  585. if (box.max[0] < min[0] || box.min[0] > max[0] ||
  586. box.max[1] < min[1] || box.min[1] > max[1] ||
  587. box.max[2] < min[2] || box.min[2] > max[2])
  588. return false;
  589. return true;
  590. }
  591. template <class T>
  592. inline Vec3<T>
  593. Box<Vec3<T> >::size() const
  594. {
  595. if (isEmpty())
  596. return Vec3<T> (0);
  597. return max - min;
  598. }
  599. template <class T>
  600. inline Vec3<T>
  601. Box<Vec3<T> >::center() const
  602. {
  603. return (max + min) / 2;
  604. }
  605. template <class T>
  606. inline bool
  607. Box<Vec3<T> >::isEmpty() const
  608. {
  609. if (max[0] < min[0] ||
  610. max[1] < min[1] ||
  611. max[2] < min[2])
  612. return true;
  613. return false;
  614. }
  615. template <class T>
  616. inline bool
  617. Box<Vec3<T> >::isInfinite() const
  618. {
  619. if (min[0] != limits<T>::min() || max[0] != limits<T>::max() ||
  620. min[1] != limits<T>::min() || max[1] != limits<T>::max() ||
  621. min[2] != limits<T>::min() || max[2] != limits<T>::max())
  622. return false;
  623. return true;
  624. }
  625. template <class T>
  626. inline bool
  627. Box<Vec3<T> >::hasVolume() const
  628. {
  629. if (max[0] <= min[0] ||
  630. max[1] <= min[1] ||
  631. max[2] <= min[2])
  632. return false;
  633. return true;
  634. }
  635. template <class T>
  636. inline unsigned int
  637. Box<Vec3<T> >::majorAxis() const
  638. {
  639. unsigned int major = 0;
  640. Vec3<T> s = size();
  641. if (s[1] > s[major])
  642. major = 1;
  643. if (s[2] > s[major])
  644. major = 2;
  645. return major;
  646. }
  647. IMATH_INTERNAL_NAMESPACE_HEADER_EXIT
  648. #endif // INCLUDED_IMATHBOX_H