📄 dxbounds.h
字号:
/*******************************************************************************
* DXBounds.h *
*------------*
* Description:
* This is the header file for the bounds helper class implementation.
*-------------------------------------------------------------------------------
* Created By: Edward W. Connell Date: 07/22/97
* Copyright (C) 1997 Microsoft Corporation
* All Rights Reserved
*
*-------------------------------------------------------------------------------
* Revisions:
*
*******************************************************************************/
#ifndef DXBounds_h
#pragma option push -b -a8 -pc -A- /*P_O_Push*/
#define DXBounds_h
#ifndef _INC_LIMITS
#include <limits.h>
#endif
#ifndef _INC_FLOAT
#include <float.h>
#endif
#ifndef __DXTrans_h__
#include <DXTrans.h>
#endif
#ifndef DXVector_h
#include <DXVector.h>
#endif
//=== Constants ====================================================
#define CHKTYPE() _ASSERT( eType == eBndType )
//=== Class, Enum, Struct and Union Declarations ===================
//=== Enumerated Set Definitions ===================================
//=== Function Type Definitions ====================================
//=== Class, Struct and Union Definitions ==========================
/*** CDXBnds
*
*/
#define CDXB_C CDXBnds<TYPE, USTYPE, STTYPE, eBndType>
#define CDXB_T ((STTYPE*)u.D)
#define CDXB_O( OtherBnd ) ((STTYPE*)(OtherBnd).u.D)
template<class TYPE, class USTYPE, class STTYPE, DXBNDTYPE eBndType>
class CDXBnds : public DXBNDS
{
public:
/*--- Constructors ---*/
CDXBnds() { eType = eBndType; SetEmpty(); }
CDXBnds( BOOL bInit ) { eType = eBndType; if (bInit) SetEmpty(); }
CDXBnds( const DXBNDS& Other ) { eType = eBndType; Copy( Other ); }
CDXBnds( const CDXB_C& Other ) { eType = eBndType; Copy( Other ); }
CDXBnds( const RECT & Rect ) { eType = eBndType; SetXYRect( Rect ); }
CDXBnds( TYPE Width, TYPE Height ) { eType = eBndType; SetXYSize( Width, Height ); }
CDXBnds( IDXSurface *pSurface, HRESULT & hr) { _ASSERT(eBndType == DXBT_DISCRETE); eType = eBndType; hr = pSurface->GetBounds(this); }
CDXBnds( IDirect3DRMMeshBuilder3 *pMesh, HRESULT & hr) { _ASSERT(eBndType == DXBT_CONTINUOUS); eType = eBndType; hr = SetToMeshBounds(pMesh); }
CDXBnds( const CDXV_C& VecPoint ) { eType = eBndType; *this = VecPoint; }
HRESULT InitFromSafeArray( SAFEARRAY *psa);
HRESULT GetSafeArray( SAFEARRAY **ppsa ) const;
void SetEmpty();
void Copy( const DXBNDS& Other );
void Copy( const CDXB_C& Other );
/*--- Type casts ---*/
operator STTYPE * () { CHKTYPE(); return CDXB_T; }
operator DXDBNDS& () { CHKTYPE(); return u.D; }
operator DXDBNDS64& () { CHKTYPE(); return u.LD; }
operator DXCBNDS& () { CHKTYPE(); return u.C; }
operator DXCBNDS64& () { CHKTYPE(); return u.LC; }
//--- Access methods
USTYPE Width( DXBNDID i ) const { CHKTYPE(); return (USTYPE)(CDXB_T[i].Max - CDXB_T[i].Min); }
USTYPE Width() const { CHKTYPE(); return (USTYPE)(CDXB_T[DXB_X].Max - CDXB_T[DXB_X].Min); }
USTYPE Height() const { CHKTYPE(); return (USTYPE)(CDXB_T[DXB_Y].Max - CDXB_T[DXB_Y].Min); }
USTYPE Depth() const { CHKTYPE(); return (USTYPE)(CDXB_T[DXB_Z].Max - CDXB_T[DXB_Z].Min); }
USTYPE Duration() const { CHKTYPE(); return (USTYPE)(CDXB_T[DXB_T].Max - CDXB_T[DXB_T].Min); }
TYPE Left() const { CHKTYPE(); return CDXB_T[DXB_X].Min; }
TYPE Right() const { CHKTYPE(); return CDXB_T[DXB_X].Max; }
TYPE Top() const { CHKTYPE(); return CDXB_T[DXB_Y].Min; }
TYPE Bottom() const { CHKTYPE(); return CDXB_T[DXB_Y].Max; }
void SetBounds( TYPE xmin, TYPE xmax, TYPE ymin, TYPE ymax,
TYPE zmin, TYPE zmax, TYPE tmin, TYPE tmax );
void SetXYRect( const RECT& xyRect);
void SetXYSize( const SIZE& xySize);
void SetXYSize( TYPE width, TYPE height);
void SetXYPoint(const POINT& xyPoint);
void Offset( TYPE x, TYPE y, TYPE z, TYPE t );
void Offset( const CDXV_C& v );
void SetPlacement(const CDXV_C& v);
void SetToSize(void);
void GetXYRect( RECT& xyRect ) const;
void GetXYSize( SIZE& xySize ) const;
void GetMinVector( CDXV_C& v ) const;
void GetMaxVector( CDXV_C& v ) const;
void GetSize( CDXB_C& SizeBounds ) const;
CDXB_C Size( void ) const;
//--- Region Functions
void NormalizeBounds();
BOOL BoundsAreEmpty() const;
BOOL BoundsAreNull() const;
BOOL TestIntersect( const CDXB_C& Other ) const;
BOOL IntersectBounds( const CDXB_C& Bounds1, const CDXB_C& Bounds2 );
BOOL IntersectBounds( const CDXB_C& OtherBounds );
void UnionBounds( const CDXB_C& Bounds1, const CDXB_C& Bounds2 );
// Additional Operations
STTYPE& operator[]( int index ) const { CHKTYPE(); return CDXB_T[index]; }
STTYPE& operator[]( long index ) const { CHKTYPE(); return CDXB_T[index]; }
STTYPE& operator[]( USHORT index ) const { CHKTYPE(); return CDXB_T[index]; }
STTYPE& operator[]( DWORD index ) const { CHKTYPE(); return CDXB_T[index]; }
STTYPE& operator[]( DXBNDID index) const { CHKTYPE(); return CDXB_T[index]; }
void operator=(const CDXB_C& Bounds);
void operator=(const CDXV_C& v);
void operator+=(const POINT& point);
void operator-=(const POINT& point);
void operator+=(const SIZE& size);
void operator-=(const SIZE& size);
void operator+=(const CDXV_C& v);
void operator-=(const CDXV_C& v);
void operator+=(const CDXB_C& Bounds);
void operator-=(const CDXB_C& Bounds);
void operator&=(const CDXB_C& Bounds);
void operator|=(const CDXB_C& Bounds);
BOOL operator==(const CDXB_C& Bounds) const;
BOOL operator!=(const CDXB_C& Bounds) const;
// Operators returning CDXDBnds values
CDXB_C operator+(const POINT& point) const;
CDXB_C operator-(const POINT& point) const;
CDXB_C operator+(const SIZE& size) const;
CDXB_C operator-(const SIZE& size) const;
CDXB_C operator+(const CDXV_C& v) const;
CDXB_C operator-(const CDXV_C& v) const;
CDXB_C operator&(const CDXB_C& Bounds2) const;
CDXB_C operator|(const CDXB_C& Bounds2) const;
//
// Helpers to grow bounds from their midpoints.
//
void Scale(TYPE x, TYPE y = 1, TYPE z = 1, TYPE t = 1);
void Scale(const CDXV_C& v);
void Expand(TYPE x, TYPE y = 0, TYPE z = 0, TYPE t = 0);
void Expand(const CDXV_C& v);
// Helpers for DXSurfaces These functions only work with DISCRETE bounds
HRESULT SetToSurfaceBounds(IDXSurface * pDXSurface);
// Helpers for D3DRM Meshes. These functions only work with CONTINUOUS bounds.
HRESULT SetToMeshBounds(IDirect3DRMMeshBuilder3 * pMesh);
};
template<class TYPE, class USTYPE, class STTYPE, DXBNDTYPE eBndType>
void CDXB_C::SetEmpty()
{
CHKTYPE();
memset(CDXB_T, 0, sizeof(STTYPE) * 4);
} /* CDXBnds::SetEmpty() */
template<class TYPE, class USTYPE, class STTYPE, DXBNDTYPE eBndType>
void CDXB_C::Copy( const CDXB_C& Other )
{
CHKTYPE();
memcpy( CDXB_T, CDXB_O(Other), sizeof( STTYPE ) * 4 );
}
template<class TYPE, class USTYPE, class STTYPE, DXBNDTYPE eBndType>
void CDXB_C::Copy( const DXBNDS& Other )
{
CHKTYPE();
if( eBndType == Other.eType )
{
memcpy( CDXB_T, CDXB_O(Other), sizeof( STTYPE ) * 4 );
}
else
{
int i = 4;
switch( Other.eType )
{
case DXBT_DISCRETE:
while( i-- )
{
CDXB_T[i].Min = (TYPE)Other.u.D[i].Min;
CDXB_T[i].Max = (TYPE)Other.u.D[i].Max;
}
break;
case DXBT_DISCRETE64:
while( i-- )
{
CDXB_T[i].Min = (TYPE)Other.u.LD[i].Min;
CDXB_T[i].Max = (TYPE)Other.u.LD[i].Max;
}
break;
case DXBT_CONTINUOUS:
while( i-- )
{
CDXB_T[i].Min = (TYPE)Other.u.C[i].Min;
CDXB_T[i].Max = (TYPE)Other.u.C[i].Max;
}
break;
case DXBT_CONTINUOUS64:
while( i-- )
{
CDXB_T[i].Min = (TYPE)Other.u.LC[i].Min;
CDXB_T[i].Max = (TYPE)Other.u.LC[i].Max;
}
break;
default:
_ASSERT(0);
}
}
} /* CDXBnds::Copy constructor */
template<class TYPE, class USTYPE, class STTYPE, DXBNDTYPE eBndType>
HRESULT CDXB_C::InitFromSafeArray( SAFEARRAY *pSA )
{
CHKTYPE();
HRESULT hr = S_OK;
TYPE *pData;
if( !pSA || ( pSA->cDims != 1 ) ||
( pSA->cbElements != sizeof(TYPE) ) ||
( pSA->rgsabound->lLbound != 1 ) ||
( pSA->rgsabound->cElements != 8 )
)
{
hr = E_INVALIDARG;
}
else
{
hr = SafeArrayAccessData(pSA, (void **)&pData);
if( SUCCEEDED( hr ) )
{
for( int i = 0; i < 4; ++i )
{
CDXB_T[i].Min = pData[i];
CDXB_T[i].Max = pData[i+4];
}
hr = SafeArrayUnaccessData( pSA );
}
}
return hr;
} /* CDXBnds::InitFromSafeArray */
template<class TYPE, class USTYPE, class STTYPE, DXBNDTYPE eBndType>
HRESULT CDXB_C::GetSafeArray( SAFEARRAY **ppSA ) const
{
CHKTYPE();
HRESULT hr = S_OK;
SAFEARRAY *pSA;
if( !ppSA )
{
hr = E_POINTER;
}
else
{
SAFEARRAYBOUND rgsabound;
rgsabound.lLbound = 1;
rgsabound.cElements = 8;
static VARTYPE VTypes[4] = { VT_I4, VT_I8, VT_R4, VT_R8 };
pSA = SafeArrayCreate( VTypes[eBndType], 1, &rgsabound );
if( pSA == NULL )
{
hr = E_OUTOFMEMORY;
}
else
{
TYPE *pData;
hr = SafeArrayAccessData( pSA, (void **)&pData );
if( SUCCEEDED( hr ) )
{
for( int i = 0; i < 4; ++i )
{
pData[i] = CDXB_T[i].Min;
pData[i+4] = CDXB_T[i].Max;
}
hr = SafeArrayUnaccessData( pSA );
}
}
if( SUCCEEDED( hr ) )
{
*ppSA = pSA;
}
}
return hr;
} /* CDXBnds::GetSafeArray */
template<class TYPE, class USTYPE, class STTYPE, DXBNDTYPE eBndType>
void CDXB_C::NormalizeBounds()
{
CHKTYPE();
for( int i = 0; i < 4; ++i )
{
if( CDXB_T[i].Max < CDXB_T[i].Min )
{
TYPE Temp = CDXB_T[i].Min;
CDXB_T[i].Min = CDXB_T[i].Max;
CDXB_T[i].Max = Temp;
}
}
} /* CDXBnds::NormalizeBounds */
template<class TYPE, class USTYPE, class STTYPE, DXBNDTYPE eBndType>
BOOL CDXB_C::IntersectBounds( const CDXB_C& Bounds1, const CDXB_C& Bounds2 )
{
CHKTYPE();
BOOL bDoesIntersect = TRUE;
for( int i = 0; i < 4; ++i )
{
CDXB_T[i].Min = max( CDXB_O( Bounds1 )[i].Min, CDXB_O( Bounds2 )[i].Min );
CDXB_T[i].Max = min( CDXB_O( Bounds1 )[i].Max, CDXB_O( Bounds2 )[i].Max );
if( CDXB_T[i].Max <= CDXB_T[i].Min )
{
//--- no intersection
SetEmpty();
bDoesIntersect = FALSE;
}
}
return bDoesIntersect;
} /* CDXBnds::IntersectBounds */
template<class TYPE, class USTYPE, class STTYPE, DXBNDTYPE eBndType>
BOOL CDXB_C::TestIntersect( const CDXB_C& Other ) const
{
CHKTYPE();
BOOL bDoesIntersect = TRUE;
TYPE BndMin, BndMax;
for( int i = 0; i < 4; ++i )
{
BndMin = max( CDXB_T[i].Min, CDXB_O( Other )[i].Min );
BndMax = min( CDXB_T[i].Max, CDXB_O( Other )[i].Max );
if( BndMax <= BndMin ) bDoesIntersect = FALSE;
}
return bDoesIntersect;
} /* CDXBnds::TestIntersect */
template<class TYPE, class USTYPE, class STTYPE, DXBNDTYPE eBndType>
void CDXB_C::UnionBounds( const CDXB_C& Bounds1, const CDXB_C& Bounds2 )
{
CHKTYPE();
// This assumes the bounds are already normalized.
for( int i = 0; i < 4; ++i )
{
CDXB_T[i].Min = min( CDXB_O( Bounds1 )[i].Min, CDXB_O( Bounds2 )[i].Min );
CDXB_T[i].Max = max( CDXB_O( Bounds1 )[i].Max, CDXB_O( Bounds2 )[i].Max );
}
} /* CDXDBnds::UnionBounds */
template<class TYPE, class USTYPE, class STTYPE, DXBNDTYPE eBndType>
BOOL CDXB_C::IntersectBounds( const CDXB_C& OtherBounds )
{
CHKTYPE();
return IntersectBounds( *this, OtherBounds );
} /* CDXBnds::IntersectBounds */
template<class TYPE, class USTYPE, class STTYPE, DXBNDTYPE eBndType>
BOOL CDXB_C::BoundsAreEmpty() const
{
CHKTYPE();
//--- Must exist in all dimensions
for( int i = 0; i < 4; ++i )
{
if( CDXB_T[i].Max <= CDXB_T[i].Min ) return TRUE;
}
return FALSE;
} /* CDXBnds::BoundsAreEmpty */
template<class TYPE, class USTYPE, class STTYPE, DXBNDTYPE eBndType>
BOOL CDXB_C::BoundsAreNull() const
{
CHKTYPE();
DWORD *pTest = (DWORD *)CDXB_T;
DWORD *pLimit = pTest + (sizeof(STTYPE) * 4 / sizeof(*pTest));
do
{
if (*pTest) return FALSE;
pTest++;
} while (pTest < pLimit);
return TRUE;
} /* CDXDBnds::BoundsAreNull */
// Additional Operations
template<class TYPE, class USTYPE, class STTYPE, DXBNDTYPE eBndType>
void CDXB_C::operator=( const CDXB_C& srcBounds )
{
CHKTYPE();
memcpy(CDXB_T, CDXB_O(srcBounds), sizeof(STTYPE)*4);
} /* CDXDBnds::operator= */
template<class TYPE, class USTYPE, class STTYPE, DXBNDTYPE eBndType>
void CDXB_C::operator=( const CDXV_C& v )
{
CHKTYPE();
for( int i = 0; i < 4; ++i )
{
CDXB_T[i].Min = v[i];
CDXB_T[i].Max = v[i] + 1;
}
} /* CDXDBnds::operator= */
template<class TYPE, class USTYPE, class STTYPE, DXBNDTYPE eBndType>
BOOL CDXB_C::operator==( const CDXB_C& Bounds ) const
{
CHKTYPE();
for( ULONG i = 0; i < 4; ++i )
{
if( ( CDXB_T[i].Min != CDXB_O( Bounds )[i].Min ) ||
( CDXB_T[i].Max != CDXB_O( Bounds )[i].Max ) )
{
return false;
}
}
return true;
} /* CDXB_C::operator== */
template<class TYPE, class USTYPE, class STTYPE, DXBNDTYPE eBndType>
BOOL CDXB_C::operator!=( const CDXB_C& Bounds ) const
{
CHKTYPE();
for( ULONG i = 0; i < 4; ++i )
{
if( ( CDXB_T[i].Min != CDXB_O( Bounds )[i].Min ) ||
( CDXB_T[i].Max != CDXB_O( Bounds )[i].Max ) )
{
return true;
}
}
return false;
} /* CDXBnds::operator!= */
template<class TYPE, class USTYPE, class STTYPE, DXBNDTYPE eBndType>
CDXB_C CDXB_C::operator&( const CDXB_C& Bounds2 ) const
{
CHKTYPE();
CDXB_C Result;
Result.IntersectBounds( *this, Bounds2 );
return Result;
} /* CDXBnds::operator& */
template<class TYPE, class USTYPE, class STTYPE, DXBNDTYPE eBndType>
CDXB_C CDXB_C::operator|( const CDXB_C& Bounds2 ) const
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -