home *** CD-ROM | disk | FTP | other *** search
/ Magazyn Internet 2000 May / MICD_2000_05.iso / CBuilder5 / INSTALL / DATA1.CAB / Program_Built_Files / Include / dxbounds.h < prev    next >
C/C++ Source or Header  |  2000-02-01  |  31KB  |  939 lines

  1. /*******************************************************************************
  2. * DXBounds.h *
  3. *------------*
  4. *   Description:
  5. *       This is the header file for the bounds helper class implementation.
  6. *-------------------------------------------------------------------------------
  7. *  Created By: Edward W. Connell                            Date: 07/22/97
  8. *  Copyright (C) 1997 Microsoft Corporation
  9. *  All Rights Reserved
  10. *
  11. *-------------------------------------------------------------------------------
  12. *  Revisions:
  13. *
  14. *******************************************************************************/
  15. #ifndef DXBounds_h
  16. #pragma option push -b -a8 -pc -A- /*P_O_Push*/
  17. #define DXBounds_h
  18.  
  19. #ifndef _INC_LIMITS
  20. #include <limits.h>
  21. #endif
  22.  
  23. #ifndef _INC_FLOAT
  24. #include <float.h>
  25. #endif
  26.  
  27. #ifndef __DXTrans_h__
  28. #include <DXTrans.h>
  29. #endif
  30.  
  31. #ifndef DXVector_h
  32. #include <DXVector.h>
  33. #endif
  34.  
  35. //=== Constants ====================================================
  36. #define CHKTYPE() _ASSERT( eType == eBndType )
  37.  
  38. //=== Class, Enum, Struct and Union Declarations ===================
  39.  
  40. //=== Enumerated Set Definitions ===================================
  41.  
  42. //=== Function Type Definitions ====================================
  43.  
  44. //=== Class, Struct and Union Definitions ==========================
  45.  
  46. /*** CDXBnds
  47. *
  48. */
  49. #define CDXB_C CDXBnds<TYPE, USTYPE, STTYPE, eBndType>
  50. #define CDXB_T ((STTYPE*)u.D)
  51. #define CDXB_O( OtherBnd ) ((STTYPE*)(OtherBnd).u.D)
  52.  
  53. template<class TYPE, class USTYPE, class STTYPE, DXBNDTYPE eBndType>
  54. class CDXBnds : public DXBNDS
  55. {
  56.   public:
  57.   /*--- Constructors ---*/
  58.     CDXBnds() { eType = eBndType; SetEmpty(); }
  59.     CDXBnds( BOOL bInit ) { eType = eBndType; if (bInit) SetEmpty(); }
  60.     CDXBnds( const DXBNDS& Other ) { eType = eBndType; Copy( Other ); }
  61.     CDXBnds( const CDXB_C& Other ) { eType = eBndType; Copy( Other ); }
  62.     CDXBnds( const RECT & Rect )    { eType = eBndType; SetXYRect( Rect ); }
  63.     CDXBnds( TYPE Width, TYPE Height ) { eType = eBndType; SetXYSize( Width, Height ); }
  64.     CDXBnds( IDXSurface *pSurface, HRESULT & hr) { _ASSERT(eBndType == DXBT_DISCRETE); eType = eBndType; hr = pSurface->GetBounds(this); }
  65.     CDXBnds( IDirect3DRMMeshBuilder3 *pMesh, HRESULT & hr) { _ASSERT(eBndType == DXBT_CONTINUOUS); eType = eBndType; hr = SetToMeshBounds(pMesh); }
  66.     CDXBnds( const CDXV_C& VecPoint ) { eType = eBndType; *this = VecPoint; }
  67.  
  68.     HRESULT InitFromSafeArray( SAFEARRAY *psa);
  69.     HRESULT GetSafeArray( SAFEARRAY **ppsa ) const;
  70.     void SetEmpty();
  71.     void Copy( const DXBNDS& Other );
  72.     void Copy( const CDXB_C& Other );
  73.  
  74.     /*--- Type casts ---*/
  75.     operator STTYPE *   () { CHKTYPE(); return CDXB_T; }
  76.     operator DXDBNDS&   () { CHKTYPE(); return u.D;  }
  77.     operator DXDBNDS64& () { CHKTYPE(); return u.LD; }
  78.     operator DXCBNDS&   () { CHKTYPE(); return u.C;  }
  79.     operator DXCBNDS64& () { CHKTYPE(); return u.LC; }
  80.  
  81.     //--- Access methods
  82.     USTYPE Width( DXBNDID i ) const { CHKTYPE(); return (USTYPE)(CDXB_T[i].Max - CDXB_T[i].Min); }
  83.  
  84.     USTYPE Width()    const { CHKTYPE(); return (USTYPE)(CDXB_T[DXB_X].Max - CDXB_T[DXB_X].Min); }
  85.     USTYPE Height()   const { CHKTYPE(); return (USTYPE)(CDXB_T[DXB_Y].Max - CDXB_T[DXB_Y].Min); }
  86.     USTYPE Depth()    const { CHKTYPE(); return (USTYPE)(CDXB_T[DXB_Z].Max - CDXB_T[DXB_Z].Min); }
  87.     USTYPE Duration() const { CHKTYPE(); return (USTYPE)(CDXB_T[DXB_T].Max - CDXB_T[DXB_T].Min); }
  88.  
  89.     TYPE  Left()     const { CHKTYPE(); return CDXB_T[DXB_X].Min; }
  90.     TYPE  Right()    const { CHKTYPE(); return CDXB_T[DXB_X].Max; }
  91.     TYPE  Top()      const { CHKTYPE(); return CDXB_T[DXB_Y].Min; }
  92.     TYPE  Bottom()   const { CHKTYPE(); return CDXB_T[DXB_Y].Max; }
  93.  
  94.     void SetBounds( TYPE xmin, TYPE xmax, TYPE ymin, TYPE ymax,
  95.                     TYPE zmin, TYPE zmax, TYPE tmin, TYPE tmax );
  96.     void SetXYRect( const RECT& xyRect);
  97.     void SetXYSize( const SIZE& xySize);
  98.     void SetXYSize( TYPE width, TYPE height);
  99.     void SetXYPoint(const POINT& xyPoint);
  100.     void Offset( TYPE x, TYPE y, TYPE z, TYPE t );
  101.     void Offset( const CDXV_C& v );
  102.     void SetPlacement(const CDXV_C& v);
  103.     void SetToSize(void);
  104.     void GetXYRect( RECT& xyRect ) const;
  105.     void GetXYSize( SIZE& xySize ) const;
  106.     void GetMinVector( CDXV_C& v ) const;
  107.     void GetMaxVector( CDXV_C& v ) const;
  108.     void GetSize( CDXB_C& SizeBounds ) const;
  109.     CDXB_C Size( void ) const;
  110.  
  111.  
  112.  
  113.     //--- Region Functions
  114.     void NormalizeBounds();
  115.     BOOL BoundsAreEmpty() const;
  116.     BOOL BoundsAreNull() const;
  117.     BOOL TestIntersect( const CDXB_C& Other ) const;
  118.     BOOL IntersectBounds( const CDXB_C& Bounds1, const CDXB_C& Bounds2 );
  119.     BOOL IntersectBounds( const CDXB_C& OtherBounds );
  120.     void UnionBounds( const CDXB_C& Bounds1, const CDXB_C& Bounds2 );
  121.  
  122. // Additional Operations
  123.     STTYPE& operator[]( int index )    const { CHKTYPE(); return CDXB_T[index]; }
  124.     STTYPE& operator[]( long index )   const { CHKTYPE(); return CDXB_T[index]; }
  125.     STTYPE& operator[]( USHORT index ) const { CHKTYPE(); return CDXB_T[index]; }
  126.     STTYPE& operator[]( DWORD index )  const { CHKTYPE(); return CDXB_T[index]; }
  127.     STTYPE& operator[]( DXBNDID index) const { CHKTYPE(); return CDXB_T[index]; }
  128.  
  129.     void operator=(const CDXB_C& Bounds);
  130.     void operator=(const CDXV_C& v);
  131.     void operator+=(const POINT& point);
  132.     void operator-=(const POINT& point);
  133.     void operator+=(const SIZE& size);
  134.     void operator-=(const SIZE& size);
  135.     void operator+=(const CDXV_C& v);
  136.     void operator-=(const CDXV_C& v);
  137.     void operator+=(const CDXB_C& Bounds);
  138.     void operator-=(const CDXB_C& Bounds);
  139.     void operator&=(const CDXB_C& Bounds);
  140.     void operator|=(const CDXB_C& Bounds);
  141.     BOOL operator==(const CDXB_C& Bounds) const;
  142.     BOOL operator!=(const CDXB_C& Bounds) const;
  143.  
  144. // Operators returning CDXDBnds values
  145.     CDXB_C operator+(const POINT& point) const;
  146.     CDXB_C operator-(const POINT& point) const;
  147.     CDXB_C operator+(const SIZE& size) const;
  148.     CDXB_C operator-(const SIZE& size) const;
  149.     CDXB_C operator+(const CDXV_C& v) const;
  150.     CDXB_C operator-(const CDXV_C& v) const;
  151.     CDXB_C operator&(const CDXB_C& Bounds2) const;
  152.     CDXB_C operator|(const CDXB_C& Bounds2) const;
  153.  
  154. //
  155. // Helpers to grow bounds from their midpoints.
  156. //
  157.     void Scale(TYPE x, TYPE y = 1, TYPE z = 1, TYPE t = 1);
  158.     void Scale(const CDXV_C& v);
  159.     void Expand(TYPE x, TYPE y = 0, TYPE z = 0, TYPE t = 0);
  160.     void Expand(const CDXV_C& v);
  161.  
  162. // Helpers for DXSurfaces  These functions only work with DISCRETE bounds
  163.     HRESULT SetToSurfaceBounds(IDXSurface * pDXSurface);
  164.  
  165. // Helpers for D3DRM Meshes.  These functions only work with CONTINUOUS bounds.
  166.     HRESULT SetToMeshBounds(IDirect3DRMMeshBuilder3 * pMesh);
  167. };
  168.  
  169. template<class TYPE, class USTYPE, class STTYPE, DXBNDTYPE eBndType>
  170. void CDXB_C::SetEmpty()
  171. {
  172.     CHKTYPE(); 
  173.     memset(CDXB_T, 0, sizeof(STTYPE) * 4);
  174. } /* CDXBnds::SetEmpty() */
  175.  
  176. template<class TYPE, class USTYPE, class STTYPE, DXBNDTYPE eBndType>
  177. void CDXB_C::Copy( const CDXB_C& Other )
  178. {
  179.     CHKTYPE();
  180.     memcpy( CDXB_T, CDXB_O(Other), sizeof( STTYPE ) * 4 );
  181. }
  182.  
  183. template<class TYPE, class USTYPE, class STTYPE, DXBNDTYPE eBndType>
  184. void CDXB_C::Copy( const DXBNDS& Other )
  185. {
  186.     CHKTYPE(); 
  187.     if( eBndType == Other.eType )
  188.     {
  189.         memcpy( CDXB_T, CDXB_O(Other), sizeof( STTYPE ) * 4 );
  190.     }
  191.     else
  192.     {
  193.         int i = 4;
  194.         switch( Other.eType )
  195.         {
  196.           case DXBT_DISCRETE:
  197.             while( i-- )
  198.             {
  199.                 CDXB_T[i].Min = (TYPE)Other.u.D[i].Min;
  200.                 CDXB_T[i].Max = (TYPE)Other.u.D[i].Max;
  201.             }
  202.             break;
  203.           case DXBT_DISCRETE64:
  204.             while( i-- )
  205.             {
  206.                 CDXB_T[i].Min = (TYPE)Other.u.LD[i].Min;
  207.                 CDXB_T[i].Max = (TYPE)Other.u.LD[i].Max;
  208.             }
  209.             break;
  210.           case DXBT_CONTINUOUS:
  211.             while( i-- )
  212.             {
  213.                 CDXB_T[i].Min = (TYPE)Other.u.C[i].Min;
  214.                 CDXB_T[i].Max = (TYPE)Other.u.C[i].Max;
  215.             }
  216.             break;
  217.           case DXBT_CONTINUOUS64:
  218.             while( i-- )
  219.             {
  220.                 CDXB_T[i].Min = (TYPE)Other.u.LC[i].Min;
  221.                 CDXB_T[i].Max = (TYPE)Other.u.LC[i].Max;
  222.             }
  223.             break;
  224.           default:
  225.             _ASSERT(0);
  226.         }
  227.     }
  228. } /* CDXBnds::Copy constructor */
  229.  
  230. template<class TYPE, class USTYPE, class STTYPE, DXBNDTYPE eBndType>
  231. HRESULT CDXB_C::InitFromSafeArray( SAFEARRAY *pSA )
  232. {
  233.     CHKTYPE(); 
  234.     HRESULT hr = S_OK;
  235.     TYPE *pData;
  236.  
  237.     if( !pSA || ( pSA->cDims != 1 ) ||
  238.          ( pSA->cbElements != sizeof(TYPE) ) ||
  239.          ( pSA->rgsabound->lLbound   != 1 ) ||
  240.          ( pSA->rgsabound->cElements != 8 ) 
  241.       )
  242.     {
  243.         hr = E_INVALIDARG;
  244.     }
  245.     else
  246.     {
  247.         hr = SafeArrayAccessData(pSA, (void **)&pData);
  248.  
  249.         if( SUCCEEDED( hr ) )
  250.         {
  251.             for( int i = 0; i < 4; ++i )
  252.             {
  253.                 CDXB_T[i].Min = pData[i];
  254.                 CDXB_T[i].Max = pData[i+4];
  255.             }
  256.  
  257.             hr = SafeArrayUnaccessData( pSA );
  258.         }
  259.     }
  260.  
  261.     return hr;
  262. } /* CDXBnds::InitFromSafeArray */
  263.  
  264. template<class TYPE, class USTYPE, class STTYPE, DXBNDTYPE eBndType>
  265. HRESULT CDXB_C::GetSafeArray( SAFEARRAY **ppSA ) const
  266. {
  267.     CHKTYPE(); 
  268.     HRESULT hr = S_OK;
  269.     SAFEARRAY *pSA;
  270.  
  271.     if( !ppSA )
  272.     {
  273.         hr = E_POINTER;
  274.     }
  275.     else
  276.     {
  277.         SAFEARRAYBOUND rgsabound;
  278.         rgsabound.lLbound   = 1;
  279.         rgsabound.cElements = 8;
  280.         static VARTYPE VTypes[4] = { VT_I4, VT_I8, VT_R4, VT_R8 };
  281.  
  282.         pSA = SafeArrayCreate( VTypes[eBndType], 1, &rgsabound );
  283.  
  284.         if( pSA == NULL )
  285.         {
  286.             hr = E_OUTOFMEMORY;
  287.         }
  288.         else
  289.         {
  290.             TYPE *pData;
  291.             hr = SafeArrayAccessData( pSA, (void **)&pData );
  292.  
  293.             if( SUCCEEDED( hr ) )
  294.             {
  295.                 for( int i = 0; i < 4; ++i )
  296.                 {
  297.                     pData[i]   = CDXB_T[i].Min;
  298.                     pData[i+4] = CDXB_T[i].Max;
  299.                 }
  300.  
  301.                 hr = SafeArrayUnaccessData( pSA );
  302.             }
  303.         }
  304.  
  305.         if( SUCCEEDED( hr ) )
  306.         {
  307.             *ppSA = pSA;
  308.         }
  309.     }
  310.  
  311.     return hr;
  312. } /* CDXBnds::GetSafeArray */
  313.  
  314. template<class TYPE, class USTYPE, class STTYPE, DXBNDTYPE eBndType>
  315. void CDXB_C::NormalizeBounds()
  316. {
  317.     CHKTYPE(); 
  318.     for( int i = 0; i < 4; ++i )
  319.     {
  320.         if( CDXB_T[i].Max < CDXB_T[i].Min )
  321.         {
  322.             TYPE Temp = CDXB_T[i].Min;
  323.             CDXB_T[i].Min = CDXB_T[i].Max;
  324.             CDXB_T[i].Max = Temp;
  325.         }
  326.     }
  327. } /* CDXBnds::NormalizeBounds */
  328.  
  329. template<class TYPE, class USTYPE, class STTYPE, DXBNDTYPE eBndType>
  330. BOOL CDXB_C::IntersectBounds( const CDXB_C& Bounds1, const CDXB_C& Bounds2 )
  331. {
  332.     CHKTYPE(); 
  333.     BOOL bDoesIntersect = TRUE;
  334.  
  335.     for( int i = 0; i < 4; ++i )
  336.     {
  337.         CDXB_T[i].Min = max( CDXB_O( Bounds1 )[i].Min, CDXB_O( Bounds2 )[i].Min );
  338.         CDXB_T[i].Max = min( CDXB_O( Bounds1 )[i].Max, CDXB_O( Bounds2 )[i].Max );
  339.  
  340.         if( CDXB_T[i].Max <= CDXB_T[i].Min )
  341.         {
  342.             //--- no intersection
  343.             SetEmpty();
  344.             bDoesIntersect = FALSE;
  345.         }
  346.     }
  347.     return bDoesIntersect;
  348. } /* CDXBnds::IntersectBounds */
  349.  
  350.  
  351. template<class TYPE, class USTYPE, class STTYPE, DXBNDTYPE eBndType>
  352. BOOL CDXB_C::TestIntersect( const CDXB_C& Other ) const
  353. {
  354.     CHKTYPE(); 
  355.     BOOL bDoesIntersect = TRUE;
  356.     TYPE BndMin, BndMax;
  357.     for( int i = 0; i < 4; ++i )
  358.     {
  359.         BndMin = max( CDXB_T[i].Min, CDXB_O( Other )[i].Min );
  360.         BndMax = min( CDXB_T[i].Max, CDXB_O( Other )[i].Max );
  361.         if( BndMax <= BndMin ) bDoesIntersect = FALSE;
  362.     }
  363.     return bDoesIntersect;
  364. } /* CDXBnds::TestIntersect */
  365.  
  366. template<class TYPE, class USTYPE, class STTYPE, DXBNDTYPE eBndType>
  367. void CDXB_C::UnionBounds( const CDXB_C& Bounds1, const CDXB_C& Bounds2 )
  368. {
  369.     CHKTYPE(); 
  370.     // This assumes the bounds are already normalized.
  371.     for( int i = 0; i < 4; ++i )
  372.     {
  373.         CDXB_T[i].Min = min( CDXB_O( Bounds1 )[i].Min, CDXB_O( Bounds2 )[i].Min );
  374.         CDXB_T[i].Max = max( CDXB_O( Bounds1 )[i].Max, CDXB_O( Bounds2 )[i].Max );
  375.     }
  376. } /* CDXDBnds::UnionBounds */
  377.  
  378. template<class TYPE, class USTYPE, class STTYPE, DXBNDTYPE eBndType>
  379. BOOL CDXB_C::IntersectBounds( const CDXB_C& OtherBounds )
  380. {
  381.     CHKTYPE(); 
  382.     return IntersectBounds( *this, OtherBounds );
  383. } /* CDXBnds::IntersectBounds */
  384.  
  385. template<class TYPE, class USTYPE, class STTYPE, DXBNDTYPE eBndType>
  386. BOOL CDXB_C::BoundsAreEmpty() const
  387. {
  388.     CHKTYPE(); 
  389.     //--- Must exist in all dimensions
  390.     for( int i = 0; i < 4; ++i )
  391.     {
  392.         if( CDXB_T[i].Max <= CDXB_T[i].Min ) return TRUE;
  393.     }
  394.     return FALSE;
  395. } /* CDXBnds::BoundsAreEmpty */
  396.  
  397. template<class TYPE, class USTYPE, class STTYPE, DXBNDTYPE eBndType>
  398. BOOL CDXB_C::BoundsAreNull() const
  399. {
  400.     CHKTYPE(); 
  401.     DWORD *pTest = (DWORD *)CDXB_T;
  402.     DWORD *pLimit = pTest + (sizeof(STTYPE) * 4 / sizeof(*pTest));
  403.     do
  404.     {
  405.         if (*pTest) return FALSE;
  406.         pTest++;
  407.     } while (pTest < pLimit);
  408.     return TRUE;
  409. } /* CDXDBnds::BoundsAreNull */
  410.  
  411. // Additional Operations
  412. template<class TYPE, class USTYPE, class STTYPE, DXBNDTYPE eBndType>
  413. void CDXB_C::operator=( const CDXB_C& srcBounds )
  414. {
  415.     CHKTYPE(); 
  416.     memcpy(CDXB_T, CDXB_O(srcBounds), sizeof(STTYPE)*4);
  417. } /* CDXDBnds::operator= */
  418.  
  419. template<class TYPE, class USTYPE, class STTYPE, DXBNDTYPE eBndType>
  420. void CDXB_C::operator=( const CDXV_C& v )
  421. {
  422.     CHKTYPE(); 
  423.     for( int i = 0; i < 4; ++i )
  424.     {
  425.         CDXB_T[i].Min = v[i];
  426.         CDXB_T[i].Max = v[i] + 1;
  427.     }
  428. } /* CDXDBnds::operator= */
  429.  
  430. template<class TYPE, class USTYPE, class STTYPE, DXBNDTYPE eBndType>
  431. BOOL CDXB_C::operator==( const CDXB_C& Bounds ) const
  432. {
  433.     CHKTYPE(); 
  434.     for( ULONG i = 0; i < 4; ++i )
  435.     {
  436.         if( ( CDXB_T[i].Min != CDXB_O( Bounds )[i].Min ) ||
  437.             ( CDXB_T[i].Max != CDXB_O( Bounds )[i].Max ) )
  438.         {
  439.             return false;
  440.         }
  441.     }
  442.     return true;
  443. } /* CDXB_C::operator== */
  444.  
  445. template<class TYPE, class USTYPE, class STTYPE, DXBNDTYPE eBndType>
  446. BOOL CDXB_C::operator!=( const CDXB_C& Bounds ) const
  447. {
  448.     CHKTYPE(); 
  449.     for( ULONG i = 0; i < 4; ++i )
  450.     {
  451.         if( ( CDXB_T[i].Min != CDXB_O( Bounds )[i].Min ) ||
  452.             ( CDXB_T[i].Max != CDXB_O( Bounds )[i].Max ) )
  453.         {
  454.             return true;
  455.         }
  456.     }
  457.     return false;
  458. } /* CDXBnds::operator!= */
  459.  
  460. template<class TYPE, class USTYPE, class STTYPE, DXBNDTYPE eBndType>
  461. CDXB_C CDXB_C::operator&( const CDXB_C& Bounds2 ) const
  462. {
  463.     CHKTYPE(); 
  464.     CDXB_C Result;
  465.     Result.IntersectBounds( *this, Bounds2 );
  466.     return Result;
  467. } /* CDXBnds::operator& */
  468.  
  469. template<class TYPE, class USTYPE, class STTYPE, DXBNDTYPE eBndType>
  470. CDXB_C CDXB_C::operator|( const CDXB_C& Bounds2 ) const
  471. {
  472.     CHKTYPE(); 
  473.     CDXB_C Result;
  474.     Result.UnionBounds( *this, Bounds2 );
  475.     return Result;
  476. } /* CDXBnds::operator| */
  477.  
  478. template<class TYPE, class USTYPE, class STTYPE, DXBNDTYPE eBndType>
  479. void CDXB_C::GetMinVector( CDXV_C& v ) const
  480. {
  481.     CHKTYPE(); 
  482.     for( int i = 0; i < 4; ++i )
  483.     {
  484.         v[i] = CDXB_T[i].Min;
  485.     }
  486. } /* CDXBnds::GetMinVector */
  487.  
  488. template<class TYPE, class USTYPE, class STTYPE, DXBNDTYPE eBndType>
  489. void CDXB_C::GetMaxVector( CDXV_C& v ) const
  490. {
  491.     CHKTYPE(); 
  492.     for( int i = 0; i < 4; ++i )
  493.     {
  494.         v[i] = CDXB_T[i].Max;
  495.     }
  496. } /* CDXBnds::GetMaxVector */
  497.  
  498. template<class TYPE, class USTYPE, class STTYPE, DXBNDTYPE eBndType>
  499. void CDXB_C::GetSize( CDXB_C& SizeBounds ) const
  500. {
  501.     CHKTYPE(); 
  502.     SizeBounds.SetEmpty();
  503.     SizeBounds[DXB_X].Max = CDXB_T[DXB_X].Max - CDXB_T[DXB_X].Min;
  504.     SizeBounds[DXB_Y].Max = CDXB_T[DXB_Y].Max - CDXB_T[DXB_Y].Min;
  505.     SizeBounds[DXB_Z].Max = CDXB_T[DXB_Z].Max - CDXB_T[DXB_Z].Min;
  506.     SizeBounds[DXB_T].Max = CDXB_T[DXB_T].Max - CDXB_T[DXB_T].Min;
  507. } /* CDXBnds::GetSize */
  508.  
  509. template<class TYPE, class USTYPE, class STTYPE, DXBNDTYPE eBndType>
  510. CDXB_C CDXB_C::Size( void ) const
  511. {
  512.     CHKTYPE(); 
  513.     CDXB_C Size;
  514.     Size[DXB_X].Max = CDXB_T[DXB_X].Max - CDXB_T[DXB_X].Min;
  515.     Size[DXB_Y].Max = CDXB_T[DXB_Y].Max - CDXB_T[DXB_Y].Min;
  516.     Size[DXB_Z].Max = CDXB_T[DXB_Z].Max - CDXB_T[DXB_Z].Min;
  517.     Size[DXB_T].Max = CDXB_T[DXB_T].Max - CDXB_T[DXB_T].Min;
  518.     return Size;
  519. } /* CDXBnds::Size */
  520.  
  521. // Operations
  522. template<class TYPE, class USTYPE, class STTYPE, DXBNDTYPE eBndType>
  523. void CDXB_C::SetBounds( TYPE xmin, TYPE xmax, TYPE ymin, TYPE ymax,
  524.                         TYPE zmin, TYPE zmax, TYPE tmin, TYPE tmax )
  525. {
  526.     CHKTYPE(); 
  527.     CDXB_T[DXB_X].Min = xmin;
  528.     CDXB_T[DXB_X].Max = xmax;
  529.     CDXB_T[DXB_Y].Min = ymin;
  530.     CDXB_T[DXB_Y].Max = ymax;
  531.     CDXB_T[DXB_Z].Min = zmin;
  532.     CDXB_T[DXB_Z].Max = zmax;
  533.     CDXB_T[DXB_T].Min = tmin;
  534.     CDXB_T[DXB_T].Max = tmax;
  535. } /* CDXBnds::SetBounds */
  536.  
  537. template<class TYPE, class USTYPE, class STTYPE, DXBNDTYPE eBndType>
  538. void CDXB_C::SetXYRect( const RECT& xyRect )
  539. {
  540.     CHKTYPE(); 
  541.     SetEmpty();
  542.     CDXB_T[DXB_X].Min = (TYPE)xyRect.left;
  543.     CDXB_T[DXB_X].Max = (TYPE)xyRect.right;
  544.     CDXB_T[DXB_Y].Min = (TYPE)xyRect.top;
  545.     CDXB_T[DXB_Y].Max = (TYPE)xyRect.bottom;
  546.     CDXB_T[DXB_Z].Max = 1;
  547.     CDXB_T[DXB_T].Max = (TYPE)LONG_MAX;
  548. } /* CDXBnds::SetXYRect */
  549.  
  550. template<class TYPE, class USTYPE, class STTYPE, DXBNDTYPE eBndType>
  551. void CDXB_C::GetXYRect( RECT& xyRect ) const
  552. {
  553.     CHKTYPE(); 
  554.     xyRect.left   = CDXB_T[DXB_X].Min;
  555.     xyRect.right  = CDXB_T[DXB_X].Max;
  556.     xyRect.top    = CDXB_T[DXB_Y].Min;
  557.     xyRect.bottom = CDXB_T[DXB_Y].Max;
  558. } /* CDXBnds::GetXYRect */
  559.  
  560. template<class TYPE, class USTYPE, class STTYPE, DXBNDTYPE eBndType>
  561. void CDXB_C::GetXYSize( SIZE& xySize ) const
  562. {
  563.     CHKTYPE(); 
  564.     xySize.cx = CDXB_T[DXB_X].Max - CDXB_T[DXB_X].Min;
  565.     xySize.cy = CDXB_T[DXB_Y].Max - CDXB_T[DXB_Y].Min;
  566. } /* CDXBnds::GetXYSize */
  567.  
  568. template<class TYPE, class USTYPE, class STTYPE, DXBNDTYPE eBndType>
  569. void CDXB_C::SetXYSize( const SIZE& xySize )
  570. {
  571.     CHKTYPE(); 
  572.     SetEmpty();
  573.     CDXB_T[DXB_X].Max = (TYPE)xySize.cx;
  574.     CDXB_T[DXB_Y].Max = (TYPE)xySize.cy;
  575.     CDXB_T[DXB_Z].Max = (TYPE)1;
  576.     CDXB_T[DXB_T].Max = (TYPE)LONG_MAX;
  577. } /* CDXBnds::SetXYSize */
  578.  
  579. template<class TYPE, class USTYPE, class STTYPE, DXBNDTYPE eBndType>
  580. void CDXB_C::SetXYSize( TYPE width, TYPE height )
  581. {
  582.     CHKTYPE(); 
  583.     SetEmpty();
  584.     CDXB_T[DXB_X].Max = (TYPE)width;
  585.     CDXB_T[DXB_Y].Max = (TYPE)height;
  586.     CDXB_T[DXB_Z].Max = (TYPE)1;
  587.     CDXB_T[DXB_T].Max = (TYPE)LONG_MAX;
  588. } /* CDXBnds::SetXYSize */
  589.  
  590. template<class TYPE, class USTYPE, class STTYPE, DXBNDTYPE eBndType>
  591. void CDXB_C::SetXYPoint( const POINT& xyPoint )
  592. {
  593.     CHKTYPE(); 
  594.     SetEmpty();
  595.     CDXB_T[DXB_X].Min = (TYPE)xyPoint.x;
  596.     CDXB_T[DXB_X].Max = (TYPE)xyPoint.x + 1;
  597.     CDXB_T[DXB_Y].Min = (TYPE)xyPoint.y;
  598.     CDXB_T[DXB_Y].Max = (TYPE)xyPoint.y + 1;
  599.     CDXB_T[DXB_Z].Max = (TYPE)1;
  600.     CDXB_T[DXB_T].Max = (TYPE)LONG_MAX;
  601. } /* CDXDBnds::SetRect */
  602.  
  603. template<class TYPE, class USTYPE, class STTYPE, DXBNDTYPE eBndType>
  604. void CDXB_C::Offset( TYPE x, TYPE y, TYPE z, TYPE t )
  605. {
  606.     CHKTYPE(); 
  607.     CDXB_T[DXB_X].Min += x;
  608.     CDXB_T[DXB_X].Max += x;    // BUGBUG -- What about infinite?
  609.     CDXB_T[DXB_Y].Min += y;
  610.     CDXB_T[DXB_Y].Max += y;
  611.     CDXB_T[DXB_Z].Min += z;
  612.     CDXB_T[DXB_Z].Max += z;
  613.     CDXB_T[DXB_T].Min += t;
  614.     CDXB_T[DXB_T].Max += t;
  615. } /* CDXBnds::Offset */
  616.  
  617.  
  618. template<class TYPE, class USTYPE, class STTYPE, DXBNDTYPE eBndType>
  619. void CDXB_C::SetToSize(void)
  620. {
  621.     CHKTYPE();
  622.     for( int i = 0; i < 4; ++i )
  623.     {
  624.         CDXB_T[i].Max -= CDXB_T[i].Min;
  625.         CDXB_T[i].Min = 0;
  626.     }
  627. }
  628.  
  629. template<class TYPE, class USTYPE, class STTYPE, DXBNDTYPE eBndType>
  630. void CDXB_C::SetPlacement(const CDXV_C & v)
  631. {
  632.     CHKTYPE(); 
  633.     for( int i = 0; i < 4; ++i )
  634.     {
  635.         CDXB_T[i].Max += (CDXV_O( v )[i] - CDXB_T[i].Min);
  636.         CDXB_T[i].Min = CDXV_O( v )[i];
  637.     }
  638. } /* CDXBnds::Offset */
  639.  
  640.  
  641. template<class TYPE, class USTYPE, class STTYPE, DXBNDTYPE eBndType>
  642. void CDXB_C::Offset( const CDXV_C& v )
  643. {
  644.     CHKTYPE(); 
  645.     for( int i = 0; i < 4; ++i )
  646.     {
  647.         CDXB_T[i].Min += v[i];
  648.         CDXB_T[i].Max += v[i];
  649.     }
  650. } /* CDXBnds::Offset */
  651.  
  652. template<class TYPE, class USTYPE, class STTYPE, DXBNDTYPE eBndType>
  653. void CDXB_C::operator+=(const POINT &point)
  654. {
  655.     CHKTYPE(); 
  656.     CDXB_T[DXB_X].Min += (TYPE)point.x;
  657.     CDXB_T[DXB_X].Max += (TYPE)point.x;
  658.     CDXB_T[DXB_Y].Min += (TYPE)point.y;
  659.     CDXB_T[DXB_Y].Max += (TYPE)point.y;
  660. } /* CDXBnds::operator+= */
  661.  
  662. template<class TYPE, class USTYPE, class STTYPE, DXBNDTYPE eBndType>
  663. void CDXB_C::operator-=(const POINT &point)
  664. {
  665.     CHKTYPE(); 
  666.     CDXB_T[DXB_X].Min -= (TYPE)point.x;
  667.     CDXB_T[DXB_X].Max -= (TYPE)point.x;
  668.     CDXB_T[DXB_Y].Min -= (TYPE)point.y;
  669.     CDXB_T[DXB_Y].Max -= (TYPE)point.y;
  670. } /* CDXBnds::operator-= */
  671.  
  672. template<class TYPE, class USTYPE, class STTYPE, DXBNDTYPE eBndType>
  673. void CDXB_C::operator+=(const SIZE &size)
  674. {
  675.     CHKTYPE(); 
  676.     CDXB_T[DXB_X].Min += (TYPE)size.cx;
  677.     CDXB_T[DXB_X].Max += (TYPE)size.cx;
  678.     CDXB_T[DXB_Y].Min += (TYPE)size.cy;
  679.     CDXB_T[DXB_Y].Max += (TYPE)size.cy;
  680. } /* CDXBnds::operator+= */
  681.  
  682. template<class TYPE, class USTYPE, class STTYPE, DXBNDTYPE eBndType>
  683. void CDXB_C::operator-=(const SIZE &size)
  684. {
  685.     CHKTYPE(); 
  686.     CDXB_T[DXB_X].Min -= (TYPE)size.cx;
  687.     CDXB_T[DXB_X].Max -= (TYPE)size.cx;
  688.     CDXB_T[DXB_Y].Min -= (TYPE)size.cy;
  689.     CDXB_T[DXB_Y].Max -= (TYPE)size.cy;
  690. } /* CDXBnds::operator-= */
  691.  
  692. template<class TYPE, class USTYPE, class STTYPE, DXBNDTYPE eBndType>
  693. void CDXB_C::operator+=(const CDXV_C& v)
  694. {
  695.     CHKTYPE(); 
  696.     CDXB_T[DXB_X].Min += CDXV_O( v )[DXB_X];
  697.     CDXB_T[DXB_X].Max += CDXV_O( v )[DXB_X];
  698.     CDXB_T[DXB_Y].Min += CDXV_O( v )[DXB_Y];
  699.     CDXB_T[DXB_Y].Max += CDXV_O( v )[DXB_Y];
  700.     CDXB_T[DXB_Z].Min += CDXV_O( v )[DXB_Z];
  701.     CDXB_T[DXB_Z].Max += CDXV_O( v )[DXB_Z];
  702.     CDXB_T[DXB_T].Min += CDXV_O( v )[DXB_T];
  703.     CDXB_T[DXB_T].Max += CDXV_O( v )[DXB_T];
  704. } /* CDXBnds::operator+= */
  705.  
  706. template<class TYPE, class USTYPE, class STTYPE, DXBNDTYPE eBndType>
  707. void CDXB_C::operator-=(const CDXV_C& v)
  708. {
  709.     CHKTYPE(); 
  710.     CDXB_T[DXB_X].Min -= CDXV_O( v )[DXB_X];
  711.     CDXB_T[DXB_X].Max -= CDXV_O( v )[DXB_X];
  712.     CDXB_T[DXB_Y].Min -= CDXV_O( v )[DXB_Y];
  713.     CDXB_T[DXB_Y].Max -= CDXV_O( v )[DXB_Y];
  714.     CDXB_T[DXB_Z].Min -= CDXV_O( v )[DXB_Z];
  715.     CDXB_T[DXB_Z].Max -= CDXV_O( v )[DXB_Z];
  716.     CDXB_T[DXB_T].Min -= CDXV_O( v )[DXB_T];
  717.     CDXB_T[DXB_T].Max -= CDXV_O( v )[DXB_T];
  718. } /* CDXBnds::operator-= */
  719.  
  720. template<class TYPE, class USTYPE, class STTYPE, DXBNDTYPE eBndType>
  721. void CDXB_C::operator+=( const CDXB_C& Bounds )
  722. {
  723.     CHKTYPE(); 
  724.     CDXB_T[DXB_X].Min += CDXB_O( Bounds )[DXB_X].Min;
  725.     CDXB_T[DXB_X].Max += CDXB_O( Bounds )[DXB_X].Max;
  726.     CDXB_T[DXB_Y].Min += CDXB_O( Bounds )[DXB_Y].Min;
  727.     CDXB_T[DXB_Y].Max += CDXB_O( Bounds )[DXB_Y].Max;
  728.     CDXB_T[DXB_Z].Min += CDXB_O( Bounds )[DXB_Z].Min;
  729.     CDXB_T[DXB_Z].Max += CDXB_O( Bounds )[DXB_Z].Max;
  730.     CDXB_T[DXB_T].Min += CDXB_O( Bounds )[DXB_T].Min;
  731.     CDXB_T[DXB_T].Max += CDXB_O( Bounds )[DXB_T].Max;
  732. } /* CDXBnds::operator+= */
  733.  
  734. template<class TYPE, class USTYPE, class STTYPE, DXBNDTYPE eBndType>
  735. void CDXB_C::operator-=( const CDXB_C& Bounds )
  736. {
  737.     CHKTYPE(); 
  738.     CDXB_T[DXB_X].Min -= CDXB_O( Bounds )[DXB_X].Min;
  739.     CDXB_T[DXB_X].Max -= CDXB_O( Bounds )[DXB_X].Max;
  740.     CDXB_T[DXB_Y].Min -= CDXB_O( Bounds )[DXB_Y].Min;
  741.     CDXB_T[DXB_Y].Max -= CDXB_O( Bounds )[DXB_Y].Max;
  742.     CDXB_T[DXB_Z].Min -= CDXB_O( Bounds )[DXB_Z].Min;
  743.     CDXB_T[DXB_Z].Max -= CDXB_O( Bounds )[DXB_Z].Max;
  744.     CDXB_T[DXB_T].Min -= CDXB_O( Bounds )[DXB_T].Min;
  745.     CDXB_T[DXB_T].Max -= CDXB_O( Bounds )[DXB_T].Max;
  746. } /* CDXB_C::operator-= */
  747.  
  748. template<class TYPE, class USTYPE, class STTYPE, DXBNDTYPE eBndType>
  749. void CDXB_C::operator&=( const CDXB_C& Bounds )
  750. {
  751.     CHKTYPE(); 
  752.     for( int i = 0; i < 4; ++i )
  753.     {
  754.         CDXB_T[i].Min = max( CDXB_T[i].Min, CDXB_O( Bounds )[i].Min );
  755.         CDXB_T[i].Max = min( CDXB_T[i].Max, CDXB_O( Bounds )[i].Max );
  756.     }
  757. } /* CDXB_C::operator&= */
  758.  
  759. template<class TYPE, class USTYPE, class STTYPE, DXBNDTYPE eBndType>
  760. void CDXB_C::operator|=( const CDXB_C& Bounds )
  761. {
  762.     CHKTYPE(); 
  763.     for( long i = 0; i < 4; ++i )
  764.     {
  765.         CDXB_T[i].Min = min( CDXB_T[i].Min, CDXB_O( Bounds )[i].Min );
  766.         CDXB_T[i].Max = max( CDXB_T[i].Max, CDXB_O( Bounds )[i].Max );
  767.     }
  768. } /* CDXB_C::operator|= */
  769.  
  770.  
  771. // operators returning CDXDBnds values
  772. template<class TYPE, class USTYPE, class STTYPE, DXBNDTYPE eBndType>
  773. CDXB_C CDXB_C::operator+(const POINT &point) const
  774. {
  775.     CHKTYPE(); 
  776.     CDXB_C Result( *this );
  777.     CDXB_O( Result )[DXB_X].Min += point.x;
  778.     CDXB_O( Result )[DXB_X].Max += point.x;
  779.     CDXB_O( Result )[DXB_Y].Min += point.y;
  780.     CDXB_O( Result )[DXB_Y].Max += point.y;
  781.     return Result;
  782. } /* CDXBnds::operator+ */
  783.  
  784. template<class TYPE, class USTYPE, class STTYPE, DXBNDTYPE eBndType>
  785. CDXB_C CDXB_C::operator-(const POINT &point) const
  786. {
  787.     CHKTYPE(); 
  788.     CDXB_C Result( *this );
  789.     CDXB_O( Result )[DXB_X].Min -= point.x;
  790.     CDXB_O( Result )[DXB_X].Max -= point.x;
  791.     CDXB_O( Result )[DXB_Y].Min -= point.y;
  792.     CDXB_O( Result )[DXB_Y].Max -= point.y;
  793.     return Result;
  794. } /* CDXBnds::operator- */
  795.  
  796. template<class TYPE, class USTYPE, class STTYPE, DXBNDTYPE eBndType>
  797. CDXB_C CDXB_C::operator+(const SIZE &size) const
  798. {
  799.     CHKTYPE(); 
  800.     CDXB_C Result( *this );
  801.     CDXB_O( Result )[DXB_X].Min += size.cx;
  802.     CDXB_O( Result )[DXB_X].Max += size.cx;
  803.     CDXB_O( Result )[DXB_Y].Min += size.cy;
  804.     CDXB_O( Result )[DXB_Y].Max += size.cy;
  805.     return Result;
  806. } /* CDXBnds::operator+ */
  807.  
  808. template<class TYPE, class USTYPE, class STTYPE, DXBNDTYPE eBndType>
  809. CDXB_C CDXB_C::operator-( const SIZE &size ) const
  810. {
  811.     CHKTYPE(); 
  812.     CDXB_C Result( *this );
  813.     CDXB_O( Result )[DXB_X].Min -= size.cx;
  814.     CDXB_O( Result )[DXB_X].Max -= size.cx;
  815.     CDXB_O( Result )[DXB_Y].Min -= size.cy;
  816.     CDXB_O( Result )[DXB_Y].Max -= size.cy;
  817.     return Result;
  818. } /* CDXB_C::operator- */
  819.  
  820. template<class TYPE, class USTYPE, class STTYPE, DXBNDTYPE eBndType>
  821. CDXB_C CDXB_C::operator+(const CDXV_C& v) const
  822. {
  823.     CHKTYPE(); 
  824.     CDXB_C Result( *this );
  825.     CDXB_O( Result )[DXB_X].Min += CDXV_O( v )[DXB_X];
  826.     CDXB_O( Result )[DXB_X].Max += CDXV_O( v )[DXB_X];
  827.     CDXB_O( Result )[DXB_Y].Min += CDXV_O( v )[DXB_Y];
  828.     CDXB_O( Result )[DXB_Y].Max += CDXV_O( v )[DXB_Y];
  829.     CDXB_O( Result )[DXB_Z].Min += CDXV_O( v )[DXB_Z];
  830.     CDXB_O( Result )[DXB_Z].Max += CDXV_O( v )[DXB_Z];
  831.     CDXB_O( Result )[DXB_T].Min += CDXV_O( v )[DXB_T];
  832.     CDXB_O( Result )[DXB_T].Max += CDXV_O( v )[DXB_T];
  833.     return Result;
  834. } /* CDXBnds::operator+ */
  835.  
  836. template<class TYPE, class USTYPE, class STTYPE, DXBNDTYPE eBndType>
  837. CDXB_C CDXB_C::operator-(const CDXV_C& v) const
  838. {
  839.     CHKTYPE(); 
  840.     CDXB_C Result( *this );
  841.     CDXB_O( Result )[DXB_X].Min -= CDXV_O( v )[DXB_X];
  842.     CDXB_O( Result )[DXB_X].Max -= CDXV_O( v )[DXB_X];
  843.     CDXB_O( Result )[DXB_Y].Min -= CDXV_O( v )[DXB_Y];
  844.     CDXB_O( Result )[DXB_Y].Max -= CDXV_O( v )[DXB_Y];
  845.     CDXB_O( Result )[DXB_Z].Min -= CDXV_O( v )[DXB_Z];
  846.     CDXB_O( Result )[DXB_Z].Max -= CDXV_O( v )[DXB_Z];
  847.     CDXB_O( Result )[DXB_T].Min -= CDXV_O( v )[DXB_T];
  848.     CDXB_O( Result )[DXB_T].Max -= CDXV_O( v )[DXB_T];
  849.     return Result;
  850. } /* CDXBnds::operator- */
  851.  
  852. template<class TYPE, class USTYPE, class STTYPE, DXBNDTYPE eBndType>
  853. HRESULT CDXB_C::SetToSurfaceBounds(IDXSurface * pDXSurface)
  854. {
  855. #if (eBndType != DXBT_DISCRETE)
  856. #error SetToSurfacBounds requires a continuous bounds.
  857. #endif
  858.     CHKTYPE(); 
  859.     return pDXSurface->GetBounds( this );
  860. }
  861.  
  862. template<class TYPE, class USTYPE, class STTYPE, DXBNDTYPE eBndType>
  863. HRESULT CDXB_C::SetToMeshBounds(IDirect3DRMMeshBuilder3 * pMesh)
  864. {
  865. #if (eBndType != DXBT_CONTINUOUS)
  866. #error SetToMeshBounds requires a continuous bounds.
  867. #endif
  868.     CHKTYPE(); 
  869.     D3DRMBOX Box;
  870.     HRESULT hr = pMesh->GetBox(&Box);
  871.     u.C[DXB_X].Min = Box.min.x;
  872.     u.C[DXB_X].Max = Box.max.x;
  873.     u.C[DXB_Y].Min = Box.min.y;
  874.     u.C[DXB_Y].Max = Box.max.y;
  875.     u.C[DXB_Z].Min = Box.min.z;
  876.     u.C[DXB_Z].Max = Box.max.z;
  877.     u.C[DXB_T].Min = 0;
  878.     u.C[DXB_T].Max = 1.;
  879.     return hr;
  880. }
  881.  
  882.  
  883. template<class TYPE, class USTYPE, class STTYPE, DXBNDTYPE eBndType>
  884. void CDXB_C::Scale(const CDXV_C& v)
  885. {
  886.     CHKTYPE(); 
  887.     for(long i = 0; i < 4; ++i )
  888.     {
  889.         TYPE mid = (CDXB_T[i].Min + CDXB_T[i].Max) / 2;
  890.         TYPE scale = CDXV_O(v)[i] * (CDXB_T[i].Max - mid);
  891.         CDXB_T[i].Min = mid - scale;
  892.         CDXB_T[i].Max = mid + scale;
  893.     }
  894. }
  895.  
  896. template<class TYPE, class USTYPE, class STTYPE, DXBNDTYPE eBndType>
  897. void CDXB_C::Scale(TYPE x, TYPE y, TYPE z, TYPE t)
  898. {
  899.     Scale(CDXV_C(x, y, z, t));
  900. }
  901.  
  902.  
  903. template<class TYPE, class USTYPE, class STTYPE, DXBNDTYPE eBndType>
  904. void CDXB_C::Expand(const CDXV_C& v)
  905. {
  906.     CHKTYPE(); 
  907.     for(long i = 0; i < 4; ++i )
  908.     {
  909.         TYPE scale = CDXV_O(v)[i] / 2;
  910.         CDXB_T[i].Min -= scale;
  911.         CDXB_T[i].Max += scale;
  912.     }
  913. }
  914.  
  915.     
  916. template<class TYPE, class USTYPE, class STTYPE, DXBNDTYPE eBndType>
  917. void CDXB_C::Expand(TYPE x, TYPE y, TYPE z, TYPE t)
  918. {
  919.     Expand(CDXV_C(x, y, z, t));
  920. }
  921.  
  922.  
  923. //---
  924. typedef CDXBnds<long, unsigned long, DXDBND, DXBT_DISCRETE> CDXDBnds;
  925. typedef CDXBnds<LONGLONG, ULONGLONG, DXDBND64, DXBT_DISCRETE64> CDXDBnds64;
  926. typedef CDXBnds<float, float, DXCBND, DXBT_CONTINUOUS> CDXCBnds;
  927. typedef CDXBnds<double, double, DXCBND64, DXBT_CONTINUOUS64> CDXCBnds64;
  928.  
  929. //=== Macro Definitions ============================================
  930.  
  931.  
  932. //=== Global Data Declarations =====================================
  933.  
  934.  
  935. //=== Function Prototypes ==========================================
  936.  
  937. #pragma option pop /*P_O_Pop*/
  938. #endif /* This must be the last line in the file */
  939.