diff options
| author | FluorescentCIAAfricanAmerican <[email protected]> | 2020-04-22 12:56:21 -0400 |
|---|---|---|
| committer | FluorescentCIAAfricanAmerican <[email protected]> | 2020-04-22 12:56:21 -0400 |
| commit | 3bf9df6b2785fa6d951086978a3e66f49427166a (patch) | |
| tree | 2c0f1f0c63c4832882bc93814ebd2c2b1c6224e5 /hammer/dispmapimagefilter.cpp | |
| download | archived-source-engine-2018-hl2-src-master.tar.xz archived-source-engine-2018-hl2-src-master.zip | |
Diffstat (limited to 'hammer/dispmapimagefilter.cpp')
| -rw-r--r-- | hammer/dispmapimagefilter.cpp | 2477 |
1 files changed, 2477 insertions, 0 deletions
diff --git a/hammer/dispmapimagefilter.cpp b/hammer/dispmapimagefilter.cpp new file mode 100644 index 0000000..bdd6743 --- /dev/null +++ b/hammer/dispmapimagefilter.cpp @@ -0,0 +1,2477 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: +// +// $Workfile: $ +// $Date: $ +// +//----------------------------------------------------------------------------- +// $Log: $ +// +// $NoKeywords: $ +//=============================================================================// + +//============================================================================= +// +// NOTE: the painting code in here needs to be cleaned up and a new algorithm +// is needed for handling valence greater than 4 cases (I am not too happy +// with the current one) +// + +#include <stdafx.h> +#include "MapDisp.h" +#include "DispSew.h" +#include "ChunkFile.h" +#include "GlobalFunctions.h" +#include "ToolDisplace.h" + +// memdbgon must be the last include file in a .cpp file!!! +#include <tier0/memdbgon.h> + +#define NULL_VALUE -99999.0f + +//============================================================================= +// +// Displacement Image Filter Functions +// + +//----------------------------------------------------------------------------- +//----------------------------------------------------------------------------- +CDispMapImageFilter::CDispMapImageFilter() +{ + m_Type = (unsigned int)-1; + m_DataType = -1; + + m_Height = 0; + m_Width = 0; + m_pImage = NULL; + + m_Scale = 1.0f; + m_AreaHeight = 0; + m_AreaWidth = 0; +} + + +//----------------------------------------------------------------------------- +//----------------------------------------------------------------------------- +CDispMapImageFilter::~CDispMapImageFilter() +{ + // de-allocate displacement image memory + if( m_pImage ) + { + delete [] m_pImage; + m_pImage = NULL; + } +} + + +//----------------------------------------------------------------------------- +//----------------------------------------------------------------------------- +int CDispMapImageFilter::GetFilterType( CString type ) +{ + if( type == "FILTER_ADD" ) { return DISPPAINT_EFFECT_RAISELOWER; } + if( type == "FILTER_MULT" ) { return DISPPAINT_EFFECT_MODULATE; } + if( type == "FILTER_CONVATTEN" ) { return DISPPAINT_EFFECT_SMOOTH; } + if( type == "FILTER_EQUAL" ) { return DISPPAINT_EFFECT_RAISETO; } + + return -1; +} + + +//----------------------------------------------------------------------------- +//----------------------------------------------------------------------------- +ChunkFileResult_t CDispMapImageFilter::LoadImageCallback( CChunkFile *pFile, + CDispMapImageFilter *pFilter ) +{ + return( pFile->ReadChunk( ( KeyHandler_t )LoadImageKeyCallback, pFilter ) ); +} + +static bool bInitMemory = true; + +//----------------------------------------------------------------------------- +//----------------------------------------------------------------------------- +ChunkFileResult_t CDispMapImageFilter::LoadImageKeyCallback( const char *szKey, const char *szValue, + CDispMapImageFilter *pFilter ) +{ + // + // allocate filter image memory + // + if( bInitMemory ) + { + int size = pFilter->m_Height * pFilter->m_Width; + pFilter->m_pImage = new float[size+1]; + if( !pFilter->m_pImage ) + return( ChunkFile_Fail ); + + bInitMemory = false; + } + + if( !strnicmp( szKey, "row", 3 ) ) + { + char szBuf[MAX_KEYVALUE_LEN]; + strcpy( szBuf, szValue ); + + int row = atoi( &szKey[3] ); + + char *pszNext = strtok( szBuf, " " ); + + int ndx = row * pFilter->m_Height; + while( pszNext != NULL ) + { + float imageValue = ( float )atof( pszNext ); + pFilter->m_pImage[ndx] = imageValue; + pszNext = strtok( NULL, " " ); + ndx++; + } + } + + return( ChunkFile_Ok ); +} + + +//----------------------------------------------------------------------------- +//----------------------------------------------------------------------------- +void CDispMapImageFilter::ValidHeight( int height ) +{ + if( ( height < 1 ) || ( height > 9 ) ) + { + Msg( mwError, "Filter height is out of range - %d\n", height ); + } +} + +//----------------------------------------------------------------------------- +//----------------------------------------------------------------------------- +void CDispMapImageFilter::ValidWidth( int width ) +{ + if( ( width < 1 ) || ( width > 9 ) ) + { + Msg( mwError, "Filter width is out of range - %d\n", width ); + } +} + + +//----------------------------------------------------------------------------- +//----------------------------------------------------------------------------- +ChunkFileResult_t CDispMapImageFilter::LoadFilterKeyCallback( const char *szKey, const char *szValue, + CDispMapImageFilter *pFilter ) +{ + if( !stricmp( szKey, "Height" ) ) + { + CChunkFile::ReadKeyValueInt( szValue, pFilter->m_Height ); + ValidHeight( pFilter->m_Height ); + } + else if( !stricmp( szKey, "Width" ) ) + { + CChunkFile::ReadKeyValueInt( szValue, pFilter->m_Width ); + ValidWidth( pFilter->m_Width ); + } + else if( !stricmp( szKey, "FilterType" ) ) + { + CString strFilterType = szValue; + pFilter->m_Type = GetFilterType( strFilterType ); + } + else if( !stricmp( szKey, "IconName" ) ) + { + pFilter->m_Name = szValue; + } + + return( ChunkFile_Ok ); +} + + +//----------------------------------------------------------------------------- +//----------------------------------------------------------------------------- +ChunkFileResult_t CDispMapImageFilter::LoadFilter( CChunkFile *pFile ) +{ + bInitMemory = true; + + CChunkHandlerMap Handlers; + Handlers.AddHandler( "Image", ( ChunkHandler_t )LoadImageCallback, this ); + + pFile->PushHandlers( &Handlers ); + ChunkFileResult_t eResult = pFile->ReadChunk( ( KeyHandler_t )LoadFilterKeyCallback, this ); + pFile->PopHandlers(); + + return( eResult ); +} + + +//============================================================================= +// +// Displacement Filter Manager Functions +// + + +//----------------------------------------------------------------------------- +//----------------------------------------------------------------------------- +CDispMapImageFilterManager::CDispMapImageFilterManager() +{ + m_FilterCount = 0; + m_ActiveFilter = 0; +} + + +//----------------------------------------------------------------------------- +//----------------------------------------------------------------------------- +void CDispMapImageFilterManager::AddFilterToList( CDispMapImageFilter *pFilter ) +{ + // don't allow overflow! -- should be an error message here!!! + if( m_FilterCount >= FILTERLIST_SIZE ) + return; + + m_pFilterList[m_FilterCount] = pFilter; + m_FilterCount++; +} + + +//----------------------------------------------------------------------------- +//----------------------------------------------------------------------------- +CDispMapImageFilter *CDispMapImageFilterManager::Create( void ) +{ + // allocate filter + CDispMapImageFilter *pFilter = new CDispMapImageFilter; + if( !pFilter ) + return NULL; + + // add filter to list + AddFilterToList( pFilter ); + + return pFilter; +} + + +//----------------------------------------------------------------------------- +//----------------------------------------------------------------------------- +void CDispMapImageFilterManager::Add( CDispMapImageFilter *pFilter ) +{ + AddFilterToList( pFilter ); +} + +//----------------------------------------------------------------------------- +//----------------------------------------------------------------------------- +void CDispMapImageFilterManager::Destroy( void ) +{ + for( int i = 0; i < m_FilterCount; i++ ) + { + // get the current filter + CDispMapImageFilter *pFilter = GetFilter( i ); + if( !pFilter ) + continue; + + delete pFilter; + } +} + + +//----------------------------------------------------------------------------- +//----------------------------------------------------------------------------- +inline void CDispMapImageFilterManager::SetImageValue( CMapDisp *pDisp, CDispMapImageFilter *pFilter, + int ndxDisp, Vector &vPaintValue ) +{ + pDisp->Paint_SetValue( ndxDisp, vPaintValue ); +} + + +//----------------------------------------------------------------------------- +//----------------------------------------------------------------------------- +inline void CDispMapImageFilterManager::GetImageValue( CMapDisp *pDisp, CDispMapImageFilter *pFilter, + int ndxDisp, Vector &vPaintValue ) +{ + if( pFilter->m_DataType == DISPPAINT_CHANNEL_POSITION ) + { + pDisp->GetVert( ndxDisp, vPaintValue ); + } + else if( pFilter->m_DataType == DISPPAINT_CHANNEL_ALPHA ) + { + float alpha = pDisp->GetAlpha( ndxDisp ); + vPaintValue.Init( alpha, 0.0f, 0.0f ); + } +} + + +//----------------------------------------------------------------------------- +//----------------------------------------------------------------------------- +inline void CDispMapImageFilterManager::GetImageFlatSubdivValue( CMapDisp *pDisp, CDispMapImageFilter *pFilter, + int ndxDisp, Vector &vPaintValue ) +{ + if( pFilter->m_DataType == DISPPAINT_CHANNEL_POSITION ) + { + Vector vSPos; + pDisp->GetFlatVert( ndxDisp, vPaintValue ); + pDisp->GetSubdivPosition( ndxDisp, vSPos ); + vPaintValue += vSPos; + } + else if( pFilter->m_DataType == DISPPAINT_CHANNEL_ALPHA ) + { + vPaintValue.Init( 0.0f, 0.0f, 0.0f ); + } +} + + +//----------------------------------------------------------------------------- +//----------------------------------------------------------------------------- +inline void CDispMapImageFilterManager::GetImageFieldData( CMapDisp *pDisp, CDispMapImageFilter *pFilter, + int ndxDisp, Vector &vNormal, float &dist ) +{ + if( pFilter->m_DataType == DISPPAINT_CHANNEL_POSITION ) + { + pDisp->GetFieldVector( ndxDisp, vNormal ); + dist = pDisp->GetFieldDistance( ndxDisp ); + } + else if( pFilter->m_DataType == DISPPAINT_CHANNEL_ALPHA ) + { + vNormal.Init( 0.0f, 0.0f, 0.0f ); + } +} + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +bool CDispMapImageFilterManager::PreApply( CDispMapImageFilter *pFilter, + int nPaintDirType, const Vector &vecPaintDir ) +{ + // Save the paint type and direction locally. + m_PaintType = nPaintDirType; + m_PaintDir = vecPaintDir; + + // Get the displacement manager from the active map document. + IWorldEditDispMgr *pDispMgr = GetActiveWorldEditDispManager(); + if( !pDispMgr ) + return false; + + // Get the displacements in the selection set. + int nDispCount = pDispMgr->SelectCount(); + for ( int iDisp = 0; iDisp < nDispCount; iDisp++ ) + { + CMapDisp *pDisp = pDispMgr->GetFromSelect( iDisp ); + if ( pDisp ) + { + pDisp->Paint_Init( pFilter->m_DataType ); + } + } + + return true; +} + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +bool CDispMapImageFilterManager::PostApply( bool bSew ) +{ + // Get the displacement manager from the active map document. + IWorldEditDispMgr *pDispMgr = GetActiveWorldEditDispManager(); + if( !pDispMgr ) + return false; + + // Get the displacements in the selection set. + int nDispCount = pDispMgr->SelectCount(); + for ( int iDisp = 0; iDisp < nDispCount; iDisp++ ) + { + CMapDisp *pDisp = pDispMgr->GetFromSelect( iDisp ); + if ( pDisp ) + { + pDisp->Paint_Update( false ); + } + } + + // Sew all surfaces post painting. + if( bSew ) + { + FaceListSewEdges(); + } + + return true; +} + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +bool CDispMapImageFilterManager::Apply( CDispMapImageFilter *pFilter, CMapDisp *pDisp, + int paintDirType, Vector const &vPaintDir, bool bSew ) +{ + // Get the index of the vertex on the displacement surface "hit." + int iVert = pDisp->GetTexelHitIndex(); + if( iVert == -1 ) + return false; + + if ( !PreApply( pFilter, paintDirType, vPaintDir ) ) + return false; + + // Apply the filter to the given displacement at the impacted vertex index. + ApplyAt( pFilter, pDisp, iVert ); + + if ( !PostApply( bSew ) ) + return false; + + return true; +} + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +void CDispMapImageFilterManager::ApplyAt( CDispMapImageFilter *pFilter, CMapDisp *pDisp, + int ndxVert ) +{ + // Apply filter appropriately type. + switch( pFilter->m_Type ) + { + case DISPPAINT_EFFECT_RAISELOWER: + { + ApplyAddFilter( pFilter, pDisp, ndxVert ); + return; + } + case DISPPAINT_EFFECT_MODULATE: + { + ApplyMultFilter( pFilter, pDisp, ndxVert ); + return; + } + case DISPPAINT_EFFECT_SMOOTH: + { + ApplySmoothFilter( pFilter, pDisp, ndxVert ); + return; + } + case DISPPAINT_EFFECT_RAISETO: + { + ApplyEqualFilter( pFilter, pDisp, ndxVert ); + return; + } + default: + { + return; + } + } +} + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +bool CDispMapImageFilterManager::IsNeighborInSelectionSet( CMapDisp *pNeighborDisp ) +{ + // Get the displacement manager from the active map document. + IWorldEditDispMgr *pDispMgr = GetActiveWorldEditDispManager(); + if( !pDispMgr ) + return false; + + // Get the displacements in the selection set. + int nDispCount = pDispMgr->SelectCount(); + for ( int iDisp = 0; iDisp < nDispCount; iDisp++ ) + { + CMapDisp *pDisp = pDispMgr->GetFromSelect( iDisp ); + if ( pDisp == pNeighborDisp ) + return true; + } + + return false; +} + +//----------------------------------------------------------------------------- +//----------------------------------------------------------------------------- +void CDispMapImageFilterManager::HitData_Init( PosHitData_t &hitData ) +{ + hitData.m_CornerCount = 0; + hitData.m_ndxCorners[0] = hitData.m_ndxCorners[1] = -1; + hitData.m_EdgeCount = 0; + hitData.m_ndxEdges[0] = hitData.m_ndxEdges[1] = -1; + hitData.m_bMain = false; +} + + +//----------------------------------------------------------------------------- +//----------------------------------------------------------------------------- +void CDispMapImageFilterManager::HitData_Setup( PosHitData_t &hitData, + int ndxHgt, int ndxWid, + int imgHgt, int imgWid ) +{ + // reset the hit data + HitData_Init( hitData ); + + // + // corners + // + + // southwest + if( ( ndxHgt <= 0.0f ) && ( ndxWid <= 0.0f ) ) + { + hitData.m_ndxCorners[hitData.m_CornerCount] = IMAGEFILTER_SOUTHWEST; + hitData.m_CornerCount++; + } + + // northwest + if( ( ndxHgt >= ( imgHgt - 1 ) ) && ( ndxWid <= 0.0f ) ) + { + hitData.m_ndxCorners[hitData.m_CornerCount] = IMAGEFILTER_NORTHWEST; + hitData.m_CornerCount++; + } + + // northeast + if( ( ndxHgt >= ( imgHgt - 1 ) ) && ( ndxWid >= ( imgWid - 1 ) ) ) + { + hitData.m_ndxCorners[hitData.m_CornerCount] = IMAGEFILTER_NORTHEAST; + hitData.m_CornerCount++; + } + + // southeast + if( ( ndxHgt <= 0.0f ) && ( ndxWid >= ( imgWid - 1 ) ) ) + { + hitData.m_ndxCorners[hitData.m_CornerCount] = IMAGEFILTER_SOUTHEAST; + hitData.m_CornerCount++; + } + + // + // edges "images" + // + + // west + if( ( ndxHgt >= 0.0f ) && ( ndxHgt <= ( imgHgt - 1 ) ) && ( ndxWid <= 0.0f ) ) + { + hitData.m_ndxEdges[hitData.m_EdgeCount] = IMAGEFILTER_WEST; + hitData.m_EdgeCount++; + } + + // north + if( ( ndxHgt >= ( imgHgt - 1 ) ) && ( ndxWid >= 0.0f ) && ( ndxWid <= ( imgWid - 1 ) ) ) + { + hitData.m_ndxEdges[hitData.m_EdgeCount] = IMAGEFILTER_NORTH; + hitData.m_EdgeCount++; + } + + // east + if( ( ndxHgt >= 0.0f ) && ( ndxHgt <= ( imgHgt - 1 ) ) && ( ndxWid >= ( imgWid - 1 ) ) ) + { + hitData.m_ndxEdges[hitData.m_EdgeCount] = IMAGEFILTER_EAST; + hitData.m_EdgeCount++; + } + + // south + if( ( ndxHgt <= 0.0f ) && ( ndxWid >= 0.0f ) && ( ndxWid <= ( imgWid - 1 ) ) ) + { + hitData.m_ndxEdges[hitData.m_EdgeCount] = IMAGEFILTER_SOUTH; + hitData.m_EdgeCount++; + } + + // + // main "image" + // + if( ( ndxHgt >= 0.0f ) && ( ndxHgt < imgHgt ) && ( ndxWid >= 0.0f ) && ( ndxWid < imgWid ) ) + { + hitData.m_bMain = true; + } +} + + +//----------------------------------------------------------------------------- +//----------------------------------------------------------------------------- +int CDispMapImageFilterManager::GetCornerImageCount( CMapDisp *pDisp, int ndxCorner ) +{ + switch( ndxCorner ) + { + case IMAGEFILTER_SOUTHWEST: { return pDisp->GetCornerNeighborCount( 0 ); } + case IMAGEFILTER_NORTHWEST: { return pDisp->GetCornerNeighborCount( 2 ); } + case IMAGEFILTER_NORTHEAST: { return pDisp->GetCornerNeighborCount( 3 ); } + case IMAGEFILTER_SOUTHEAST: { return pDisp->GetCornerNeighborCount( 1 ); } + default: { return -1; } + } +} + + +//----------------------------------------------------------------------------- +//----------------------------------------------------------------------------- +CMapDisp *CDispMapImageFilterManager::GetImage( CDispMapImageFilter *pFilter, + CMapDisp *pDisp, int ndxHgt, int ndxWid, + int ndxImg, int imgCount, int &orient ) +{ + CMapDisp *pNeighborDisp = NULL; + EditDispHandle_t neighborHandle; + + switch( ndxImg ) + { + case IMAGEFILTER_SOUTHWEST: + { + int count = pDisp->GetCornerNeighborCount( 0 ); + if( count != 0 ) + { + for( int i = 0; i < count; i++ ) + { + if( i != imgCount ) + continue; + + pDisp->GetCornerNeighbor( 0, i, neighborHandle, orient ); + if( neighborHandle != EDITDISPHANDLE_INVALID ) + { + pNeighborDisp = EditDispMgr()->GetDisp( neighborHandle ); + } + return pNeighborDisp; + } + } + + return NULL; + } + case IMAGEFILTER_WEST: + { + pDisp->GetEdgeNeighbor( 0, neighborHandle, orient ); + if( neighborHandle != EDITDISPHANDLE_INVALID ) + { + pNeighborDisp = EditDispMgr()->GetDisp( neighborHandle ); + } + return pNeighborDisp; + } + case IMAGEFILTER_NORTHWEST: + { + int count = pDisp->GetCornerNeighborCount( 2 ); + if( count != 0 ) + { + for( int i = 0; i < count; i++ ) + { + if( i != imgCount ) + continue; + + pDisp->GetCornerNeighbor( 2, i, neighborHandle, orient ); + if( neighborHandle != EDITDISPHANDLE_INVALID ) + { + pNeighborDisp = EditDispMgr()->GetDisp( neighborHandle ); + } + return pNeighborDisp; + } + } + + return NULL; + } + case IMAGEFILTER_NORTH: + { + pDisp->GetEdgeNeighbor( 1, neighborHandle, orient ); + if( neighborHandle != EDITDISPHANDLE_INVALID ) + { + pNeighborDisp = EditDispMgr()->GetDisp( neighborHandle ); + } + return pNeighborDisp; + } + case IMAGEFILTER_NORTHEAST: + { + int count = pDisp->GetCornerNeighborCount( 3 ); + if( count != 0 ) + { + for( int i = 0; i < count; i++ ) + { + if( i != imgCount ) + continue; + + pDisp->GetCornerNeighbor( 3, i, neighborHandle, orient ); + if( neighborHandle != EDITDISPHANDLE_INVALID ) + { + pNeighborDisp = EditDispMgr()->GetDisp( neighborHandle ); + } + return pNeighborDisp; + } + } + + return NULL; + } + case IMAGEFILTER_EAST: + { + pDisp->GetEdgeNeighbor( 2, neighborHandle, orient ); + if( neighborHandle != EDITDISPHANDLE_INVALID ) + { + pNeighborDisp = EditDispMgr()->GetDisp( neighborHandle ); + } + return pNeighborDisp; + } + case IMAGEFILTER_SOUTHEAST: + { + int count = pDisp->GetCornerNeighborCount( 1 ); + if( count != 0 ) + { + for( int i = 0; i < count; i++ ) + { + if( i != imgCount ) + continue; + + pDisp->GetCornerNeighbor( 1, i, neighborHandle, orient ); + if( neighborHandle != EDITDISPHANDLE_INVALID ) + { + pNeighborDisp = EditDispMgr()->GetDisp( neighborHandle ); + } + return pNeighborDisp; + } + } + + return NULL; + } + case IMAGEFILTER_SOUTH: + { + pDisp->GetEdgeNeighbor( 3, neighborHandle, orient ); + if( neighborHandle != EDITDISPHANDLE_INVALID ) + { + pNeighborDisp = EditDispMgr()->GetDisp( neighborHandle ); + } + return pNeighborDisp; + } + case IMAGEFILTER_MAIN: + { + return pDisp; + } + default: + { + return NULL; + } + } +} + + +//----------------------------------------------------------------------------- +//----------------------------------------------------------------------------- +bool CDispMapImageFilterManager::GetImageFieldValues( CDispMapImageFilter *pFilter, + CMapDisp *pDisp, int ndxHgt, int ndxWid, + int ndxImg, int imgCount, + Vector &vNormal, float &dist ) +{ + // + // get the image (displacement) given a position + // + int orient; + CMapDisp *pNeighborDisp = GetImage( pFilter, pDisp, ndxHgt, ndxWid, ndxImg, imgCount, orient ); + if( !pNeighborDisp ) + return false; + + switch( ndxImg ) + { + case IMAGEFILTER_SOUTHWEST: + { + int ndx = GetSWImageIndex( pNeighborDisp, orient, ndxHgt, ndxWid ); + GetImageFieldData( pNeighborDisp, pFilter, ndx, vNormal, dist ); + return true; + } + case IMAGEFILTER_WEST: + { + int ndx = GetWImageIndex( pNeighborDisp, orient, ndxHgt, ndxWid ); + GetImageFieldData( pNeighborDisp, pFilter, ndx, vNormal, dist ); + return true; + } + case IMAGEFILTER_NORTHWEST: + { + int ndx = GetNWImageIndex( pNeighborDisp, orient, ndxHgt, ndxWid ); + GetImageFieldData( pNeighborDisp, pFilter, ndx, vNormal, dist ); + return true; + } + case IMAGEFILTER_NORTH: + { + int ndx = GetNImageIndex( pNeighborDisp, orient, ndxHgt, ndxWid ); + GetImageFieldData( pNeighborDisp, pFilter, ndx, vNormal, dist ); + return true; + } + case IMAGEFILTER_NORTHEAST: + { + int ndx = GetNEImageIndex( pNeighborDisp, orient, ndxHgt, ndxWid ); + GetImageFieldData( pNeighborDisp, pFilter, ndx, vNormal, dist ); + return true; + } + case IMAGEFILTER_EAST: + { + int ndx = GetEImageIndex( pNeighborDisp, orient, ndxHgt, ndxWid ); + GetImageFieldData( pNeighborDisp, pFilter, ndx, vNormal, dist ); + return true; + } + case IMAGEFILTER_SOUTHEAST: + { + int ndx = GetSEImageIndex( pNeighborDisp, orient, ndxHgt, ndxWid ); + GetImageFieldData( pNeighborDisp, pFilter, ndx, vNormal, dist ); + return true; + } + case IMAGEFILTER_SOUTH: + { + int ndx = GetSImageIndex( pNeighborDisp, orient, ndxHgt, ndxWid ); + GetImageFieldData( pNeighborDisp, pFilter, ndx, vNormal, dist ); + return true; + } + case IMAGEFILTER_MAIN: + { + int ndx = ndxHgt * pDisp->GetWidth() + ndxWid; + GetImageFieldData( pDisp, pFilter, ndx, vNormal, dist ); + return true; + } + default: { return false; } + } +} + + +//----------------------------------------------------------------------------- +//----------------------------------------------------------------------------- +bool CDispMapImageFilterManager::GetImageFlatSubdivValues( CDispMapImageFilter *pFilter, + CMapDisp *pDisp, int ndxHgt, int ndxWid, + int ndxImg, int imgCount, Vector &value ) +{ + // + // get the image (displacement) given a position + // + int orient; + CMapDisp *pNeighborDisp = GetImage( pFilter, pDisp, ndxHgt, ndxWid, ndxImg, imgCount, orient ); + if( !pNeighborDisp ) + return false; + + switch( ndxImg ) + { + case IMAGEFILTER_SOUTHWEST: + { + int ndx = GetSWImageIndex( pNeighborDisp, orient, ndxHgt, ndxWid ); + GetImageFlatSubdivValue( pNeighborDisp, pFilter, ndx, value ); + return true; + } + case IMAGEFILTER_WEST: + { + int ndx = GetWImageIndex( pNeighborDisp, orient, ndxHgt, ndxWid ); + GetImageFlatSubdivValue( pNeighborDisp, pFilter, ndx, value ); + return true; + } + case IMAGEFILTER_NORTHWEST: + { + int ndx = GetNWImageIndex( pNeighborDisp, orient, ndxHgt, ndxWid ); + GetImageFlatSubdivValue( pNeighborDisp, pFilter, ndx, value ); + return true; + } + case IMAGEFILTER_NORTH: + { + int ndx = GetNImageIndex( pNeighborDisp, orient, ndxHgt, ndxWid ); + GetImageFlatSubdivValue( pNeighborDisp, pFilter, ndx, value ); + return true; + } + case IMAGEFILTER_NORTHEAST: + { + int ndx = GetNEImageIndex( pNeighborDisp, orient, ndxHgt, ndxWid ); + GetImageFlatSubdivValue( pNeighborDisp, pFilter, ndx, value ); + return true; + } + case IMAGEFILTER_EAST: + { + int ndx = GetEImageIndex( pNeighborDisp, orient, ndxHgt, ndxWid ); + GetImageFlatSubdivValue( pNeighborDisp, pFilter, ndx, value ); + return true; + } + case IMAGEFILTER_SOUTHEAST: + { + int ndx = GetSEImageIndex( pNeighborDisp, orient, ndxHgt, ndxWid ); + GetImageFlatSubdivValue( pNeighborDisp, pFilter, ndx, value ); + return true; + } + case IMAGEFILTER_SOUTH: + { + int ndx = GetSImageIndex( pNeighborDisp, orient, ndxHgt, ndxWid ); + GetImageFlatSubdivValue( pNeighborDisp, pFilter, ndx, value ); + return true; + } + case IMAGEFILTER_MAIN: + { + int ndx = ndxHgt * pDisp->GetWidth() + ndxWid; + GetImageFlatSubdivValue( pDisp, pFilter, ndx, value ); + return true; + } + default: { return false; } + } +} + + +//----------------------------------------------------------------------------- +//----------------------------------------------------------------------------- +bool CDispMapImageFilterManager::GetImageValues( CDispMapImageFilter *pFilter, + CMapDisp *pDisp, int ndxHgt, int ndxWid, + int ndxImg, int imgCount, Vector &value ) +{ + // Get the image (displacement) given a position + int orient; + CMapDisp *pNeighborDisp = GetImage( pFilter, pDisp, ndxHgt, ndxWid, ndxImg, imgCount, orient ); + if( !pNeighborDisp || !IsNeighborInSelectionSet( pNeighborDisp ) ) + return false; + + switch( ndxImg ) + { + case IMAGEFILTER_SOUTHWEST: { SWImageValue( pFilter, pNeighborDisp, orient, ndxHgt, ndxWid, false, value ); return true; } + case IMAGEFILTER_WEST: { WImageValue( pFilter, pNeighborDisp, orient, ndxHgt, ndxWid, false, value ); return true; } + case IMAGEFILTER_NORTHWEST: { NWImageValue( pFilter, pNeighborDisp, orient, ndxHgt, ndxWid, false, value ); return true; } + case IMAGEFILTER_NORTH: { NImageValue( pFilter, pNeighborDisp, orient, ndxHgt, ndxWid, false, value ); return true; } + case IMAGEFILTER_NORTHEAST: { NEImageValue( pFilter, pNeighborDisp, orient, ndxHgt, ndxWid, false, value ); return true; } + case IMAGEFILTER_EAST: { EImageValue( pFilter, pNeighborDisp, orient, ndxHgt, ndxWid, false, value ); return true; } + case IMAGEFILTER_SOUTHEAST: { SEImageValue( pFilter, pNeighborDisp, orient, ndxHgt, ndxWid, false, value ); return true; } + case IMAGEFILTER_SOUTH: { SImageValue( pFilter, pNeighborDisp, orient, ndxHgt, ndxWid, false, value ); return true; } + case IMAGEFILTER_MAIN: { MainImageValue( pFilter, pDisp, ndxHgt, ndxWid, false, value ); return true; } + default: { return false; } + } +} + + +//----------------------------------------------------------------------------- +//----------------------------------------------------------------------------- +int CDispMapImageFilterManager::GetAdjustedIndex( CMapDisp *pDisp, int orient, + int ndxHgt, int ndxWid, int ndxImg ) +{ + switch( ndxImg ) + { + case IMAGEFILTER_SOUTHWEST: + { + return GetSWImageIndex( pDisp, orient, ndxHgt, ndxWid ); + } + case IMAGEFILTER_WEST: + { + return GetWImageIndex( pDisp, orient, ndxHgt, ndxWid ); + } + case IMAGEFILTER_NORTHWEST: + { + return GetNWImageIndex( pDisp, orient, ndxHgt, ndxWid ); + } + case IMAGEFILTER_NORTH: + { + return GetNImageIndex( pDisp, orient, ndxHgt, ndxWid ); + } + case IMAGEFILTER_NORTHEAST: + { + return GetNEImageIndex( pDisp, orient, ndxHgt, ndxWid ); + } + case IMAGEFILTER_EAST: + { + return GetEImageIndex( pDisp, orient, ndxHgt, ndxWid ); + } + case IMAGEFILTER_SOUTHEAST: + { + return GetSEImageIndex( pDisp, orient, ndxHgt, ndxWid ); + } + case IMAGEFILTER_SOUTH: + { + return GetSImageIndex( pDisp, orient, ndxHgt, ndxWid ); + } + case IMAGEFILTER_MAIN: + { + int imgWid = pDisp->GetWidth(); + return( ndxHgt * imgWid + ndxWid ); + } + default: + { + return -1; + } + } +} + + +//----------------------------------------------------------------------------- +//----------------------------------------------------------------------------- +void CDispMapImageFilterManager::SetImageValues( CDispMapImageFilter *pFilter, + CMapDisp *pDisp, int ndxHgt, int ndxWid, + int ndxImg, int imgCount, Vector &value ) +{ + CMapDisp *pNeighborDisp = NULL; + int orient; + EditDispHandle_t neighborHandle; + + switch( ndxImg ) + { + case IMAGEFILTER_SOUTHWEST: + { + int count = pDisp->GetCornerNeighborCount( 0 ); + if( count != 0 ) + { + for( int i = 0; i < count; i++ ) + { + if( i != imgCount ) + continue; + + pDisp->GetCornerNeighbor( 0, i, neighborHandle, orient ); + if( neighborHandle != EDITDISPHANDLE_INVALID ) + { + pNeighborDisp = EditDispMgr()->GetDisp( neighborHandle ); + SWImageValue( pFilter, pNeighborDisp, orient, ndxHgt, ndxWid, true, value ); + } + return; + } + } + + return; + } + case IMAGEFILTER_WEST: + { + pDisp->GetEdgeNeighbor( 0, neighborHandle, orient ); + if( neighborHandle != EDITDISPHANDLE_INVALID ) + { + pNeighborDisp = EditDispMgr()->GetDisp( neighborHandle ); + WImageValue( pFilter, pNeighborDisp, orient, ndxHgt, ndxWid, true, value ); + return; + } + + return; + } + case IMAGEFILTER_NORTHWEST: + { + int count = pDisp->GetCornerNeighborCount( 2 ); + if( count != 0 ) + { + for( int i = 0; i < count; i++ ) + { + if( i != imgCount ) + continue; + + pDisp->GetCornerNeighbor( 2, i, neighborHandle, orient ); + if( neighborHandle != EDITDISPHANDLE_INVALID ) + { + pNeighborDisp = EditDispMgr()->GetDisp( neighborHandle ); + NWImageValue( pFilter, pNeighborDisp, orient, ndxHgt, ndxWid, true, value ); + } + return; + } + } + + return; + } + case IMAGEFILTER_NORTH: + { + pDisp->GetEdgeNeighbor( 1, neighborHandle, orient ); + if( neighborHandle != EDITDISPHANDLE_INVALID ) + { + pNeighborDisp = EditDispMgr()->GetDisp( neighborHandle ); + NImageValue( pFilter, pNeighborDisp, orient, ndxHgt, ndxWid, true, value ); + return; + } + + // shouldn't be here!! + return; + } + case IMAGEFILTER_NORTHEAST: + { + int count = pDisp->GetCornerNeighborCount( 3 ); + if( count != 0 ) + { + for( int i = 0; i < count; i++ ) + { + if( i != imgCount ) + continue; + + pDisp->GetCornerNeighbor( 3, i, neighborHandle, orient ); + if( neighborHandle != EDITDISPHANDLE_INVALID ) + { + pNeighborDisp = EditDispMgr()->GetDisp( neighborHandle ); + NEImageValue( pFilter, pNeighborDisp, orient, ndxHgt, ndxWid, true, value ); + } + return; + } + } + + return; + } + case IMAGEFILTER_EAST: + { + pDisp->GetEdgeNeighbor( 2, neighborHandle, orient ); + if( neighborHandle != EDITDISPHANDLE_INVALID ) + { + pNeighborDisp = EditDispMgr()->GetDisp( neighborHandle ); + EImageValue( pFilter, pNeighborDisp, orient, ndxHgt, ndxWid, true, value ); + return; + } + + return; + } + case IMAGEFILTER_SOUTHEAST: + { + int count = pDisp->GetCornerNeighborCount( 1 ); + if( count != 0 ) + { + for( int i = 0; i < count; i++ ) + { + if( i != imgCount ) + continue; + + pDisp->GetCornerNeighbor( 1, i, neighborHandle, orient ); + if( neighborHandle != EDITDISPHANDLE_INVALID ) + { + pNeighborDisp = EditDispMgr()->GetDisp( neighborHandle ); + SEImageValue( pFilter, pNeighborDisp, orient, ndxHgt, ndxWid, true, value ); + } + return; + } + } + + return; + } + case IMAGEFILTER_SOUTH: + { + pDisp->GetEdgeNeighbor( 3, neighborHandle, orient ); + if( neighborHandle != EDITDISPHANDLE_INVALID ) + { + pNeighborDisp = EditDispMgr()->GetDisp( neighborHandle ); + SImageValue( pFilter, pNeighborDisp, orient, ndxHgt, ndxWid, true, value ); + return; + } + + return; + } + case IMAGEFILTER_MAIN: + { + MainImageValue( pFilter, pDisp, ndxHgt, ndxWid, true, value ); + return; + } + } +} + + +//----------------------------------------------------------------------------- +//----------------------------------------------------------------------------- +void CDispMapImageFilterManager::MainImageValue( CDispMapImageFilter *pFilter, + CMapDisp *pDisp, int ndxHgt, int ndxWid, + bool bSet, Vector &value ) +{ + // get the image height and width + int height = pDisp->GetHeight(); + + // calc index value + int index = ndxHgt * height + ndxWid; + // + // return the value at this position + // + if( bSet ) + { + SetImageValue( pDisp, pFilter, index, value ); + } + else + { + GetImageValue( pDisp, pFilter, index, value ); + } +} + + +//----------------------------------------------------------------------------- +//----------------------------------------------------------------------------- +int CDispMapImageFilterManager::GetSWImageIndex( CMapDisp *pDisp, int orient, int ndxHgt, int ndxWid ) +{ + // + // get the image height and width + // + int height = pDisp->GetHeight(); + int width = pDisp->GetWidth(); + + // + // + // + int hIndex, wIndex; + switch( orient ) + { + case IMAGEFILTER_ORIENT_SOUTHWEST: + { + hIndex = -ndxHgt; + wIndex = -ndxWid; + break; + } + case IMAGEFILTER_ORIENT_SOUTHEAST: + { + hIndex = -ndxWid; + wIndex = ( width - 1 ) + ndxHgt; + break; + } + case IMAGEFILTER_ORIENT_NORTHWEST: + { + hIndex = ( height - 1 ) + ndxWid; + wIndex = -ndxHgt; + break; + } + case IMAGEFILTER_ORIENT_NORTHEAST: + { + hIndex = ( height - 1 ) + ndxHgt; + wIndex = ( width - 1 ) + ndxWid; + break; + } + default: + { + hIndex = 0; + wIndex = 0; + } + } + + // + // clamp height and width index values + // + if( hIndex < 0 ) { hIndex = 0; } + if( wIndex < 0 ) { wIndex = 0; } + if( hIndex > ( height - 1 ) ) { hIndex = ( height - 1 ); } + if( wIndex > ( width - 1 ) ) { wIndex = ( width - 1 ); } + + // calc index value + return( hIndex * height + wIndex ); + +} + + +//----------------------------------------------------------------------------- +//----------------------------------------------------------------------------- +void CDispMapImageFilterManager::SWImageValue( CDispMapImageFilter *pFilter, + CMapDisp *pDisp, int orient, + int ndxHgt, int ndxWid, bool bSet, + Vector &value ) +{ + // get the index + int index = GetSWImageIndex( pDisp, orient, ndxHgt, ndxWid ); + + // + // return the value at this position + // + if( bSet ) + { + SetImageValue( pDisp, pFilter, index, value ); + } + else + { + GetImageValue( pDisp, pFilter, index, value ); + } +} + + +//----------------------------------------------------------------------------- +//----------------------------------------------------------------------------- +int CDispMapImageFilterManager::GetWImageIndex( CMapDisp *pDisp, int orient, int ndxHgt, int ndxWid ) +{ + // + // get the image height and width + // + int height = pDisp->GetHeight(); + int width = pDisp->GetWidth(); + + // + // + // + int hIndex, wIndex; + switch( orient ) + { + case IMAGEFILTER_ORIENT_WEST: + { + hIndex = ( height - 1 ) - ndxHgt; + wIndex = -ndxWid; + break; + } + case IMAGEFILTER_ORIENT_NORTH: + { + hIndex = ( height - 1 ) + ndxWid; + wIndex = ( width - 1 ) - ndxHgt; + break; + } + case IMAGEFILTER_ORIENT_EAST: + { + hIndex = ndxHgt; + wIndex = ( width - 1 ) + ndxWid; + break; + } + case IMAGEFILTER_ORIENT_SOUTH: + { + hIndex = -ndxWid; + wIndex = ndxHgt; + break; + } + default: + { + hIndex = 0; + wIndex = 0; + } + } + + // + // clamp height and width index values + // + if( hIndex < 0 ) { hIndex = 0; } + if( wIndex < 0 ) { wIndex = 0; } + if( hIndex > ( height - 1 ) ) { hIndex = ( height - 1 ); } + if( wIndex > ( width - 1 ) ) { wIndex = ( width - 1 ); } + + // calc index value + return( hIndex * height + wIndex ); + +} + + +//----------------------------------------------------------------------------- +//----------------------------------------------------------------------------- +void CDispMapImageFilterManager::WImageValue( CDispMapImageFilter *pFilter, + CMapDisp *pDisp, int orient, + int ndxHgt, int ndxWid, bool bSet, Vector &value ) +{ + // get image index + int index = GetWImageIndex( pDisp, orient, ndxHgt, ndxWid ); + + // + // return the value at this position + // + if( bSet ) + { + SetImageValue( pDisp, pFilter, index, value ); + } + else + { + GetImageValue( pDisp, pFilter, index, value ); + } +} + + +//----------------------------------------------------------------------------- +//----------------------------------------------------------------------------- +int CDispMapImageFilterManager::GetNWImageIndex( CMapDisp *pDisp, int orient, int ndxHgt, int ndxWid ) +{ + // + // get the image height and width + // + int height = pDisp->GetHeight(); + int width = pDisp->GetWidth(); + + // + // + // + int hIndex, wIndex; + switch( orient ) + { + case IMAGEFILTER_ORIENT_SOUTHWEST: + { + hIndex = ndxHgt - ( height - 1 ); + wIndex = -ndxWid; + break; + } + case IMAGEFILTER_ORIENT_SOUTHEAST: + { + hIndex = ndxHgt - ( height - 1 ); + wIndex = ( width - 1 ) + ndxWid; + break; + } + case IMAGEFILTER_ORIENT_NORTHWEST: + { + hIndex = ( 2 * ( height - 1 ) ) - ndxHgt; + wIndex = -ndxWid; + break; + } + case IMAGEFILTER_ORIENT_NORTHEAST: + { + hIndex = ( height - 1 ) + ndxWid; + wIndex = ( 2 * ( width - 1 ) ) - ndxHgt; + break; + } + default: + { + hIndex = 0; + wIndex = 0; + } + } + + // + // clamp height and width index values + // + if( hIndex < 0 ) { hIndex = 0; } + if( wIndex < 0 ) { wIndex = 0; } + if( hIndex > ( height - 1 ) ) { hIndex = ( height - 1 ); } + if( wIndex > ( width - 1 ) ) { wIndex = ( width - 1 ); } + + // calc index value + return( hIndex * height + wIndex ); +} + + +//----------------------------------------------------------------------------- +//----------------------------------------------------------------------------- +void CDispMapImageFilterManager::NWImageValue( CDispMapImageFilter *pFilter, + CMapDisp *pDisp, int orient, + int ndxHgt, int ndxWid, bool bSet, Vector &value ) +{ + // get image index + int index = GetNWImageIndex( pDisp, orient, ndxHgt, ndxWid ); + + // + // return the value at this position + // + if( bSet ) + { + SetImageValue( pDisp, pFilter, index, value ); + } + else + { + GetImageValue( pDisp, pFilter, index, value ); + } +} + + +//----------------------------------------------------------------------------- +//----------------------------------------------------------------------------- +int CDispMapImageFilterManager::GetNImageIndex( CMapDisp *pDisp, int orient, int ndxHgt, int ndxWid ) +{ + // + // get the image height and width + // + int height = pDisp->GetHeight(); + int width = pDisp->GetWidth(); + + // + // + // + int hIndex, wIndex; + switch( orient ) + { + case IMAGEFILTER_ORIENT_WEST: + { + hIndex = ( height - 1 ) - ndxWid; + wIndex = ndxHgt - ( width - 1 ); + break; + } + case IMAGEFILTER_ORIENT_NORTH: + { + hIndex = ( 2 * ( height - 1 ) ) - ndxHgt; + wIndex = ( width - 1 ) - ndxWid; + break; + } + case IMAGEFILTER_ORIENT_EAST: + { + hIndex = ndxWid; + wIndex = ( 2 * ( width - 1 ) ) - ndxHgt; + break; + } + case IMAGEFILTER_ORIENT_SOUTH: + { + hIndex = ndxHgt - ( height - 1 ); + wIndex = ndxWid; + break; + } + default: + { + hIndex = 0; + wIndex = 0; + } + } + + // + // clamp height and width index values + // + if( hIndex < 0 ) { hIndex = 0; } + if( wIndex < 0 ) { wIndex = 0; } + if( hIndex > ( height - 1 ) ) { hIndex = ( height - 1 ); } + if( wIndex > ( width - 1 ) ) { wIndex = ( width - 1 ); } + + // calc index value + return( hIndex * height + wIndex ); +} + + +//----------------------------------------------------------------------------- +//----------------------------------------------------------------------------- +void CDispMapImageFilterManager::NImageValue( CDispMapImageFilter *pFilter, + CMapDisp *pDisp, int orient, + int ndxHgt, int ndxWid, bool bSet, Vector &value ) +{ + // get image index + int index = GetNImageIndex( pDisp, orient, ndxHgt, ndxWid ); + + // + // return the value at this position + // + if( bSet ) + { + SetImageValue( pDisp, pFilter, index, value ); + } + else + { + GetImageValue( pDisp, pFilter, index, value ); + } +} + + +//----------------------------------------------------------------------------- +//----------------------------------------------------------------------------- +int CDispMapImageFilterManager::GetNEImageIndex( CMapDisp *pDisp, int orient, int ndxHgt, int ndxWid ) +{ + // + // get the image height and width + // + int height = pDisp->GetHeight(); + int width = pDisp->GetWidth(); + + // + // + // + int hIndex, wIndex; + switch( orient ) + { + case IMAGEFILTER_ORIENT_SOUTHWEST: + { + hIndex = ndxHgt - ( height - 1 ); + wIndex = ndxWid - ( width - 1 ); + break; + } + case IMAGEFILTER_ORIENT_SOUTHEAST: + { + hIndex = ndxWid - ( height - 1 ); + wIndex = ( 2 * ( width - 1 ) ) - ndxHgt; + break; + } + case IMAGEFILTER_ORIENT_NORTHWEST: + { + hIndex = ( 2 * ( height - 1 ) ) - ndxWid; + wIndex = ndxHgt - ( width - 1 ); + break; + } + case IMAGEFILTER_ORIENT_NORTHEAST: + { + hIndex = ( 2 * ( height - 1 ) ) - ndxHgt; + wIndex = ( 2 * ( width - 1 ) ) - ndxWid; + break; + } + default: + { + hIndex = 0; + wIndex = 0; + } + } + + // + // clamp height and width index values + // + if( hIndex < 0 ) { hIndex = 0; } + if( wIndex < 0 ) { wIndex = 0; } + if( hIndex > ( height - 1 ) ) { hIndex = ( height - 1 ); } + if( wIndex > ( width - 1 ) ) { wIndex = ( width - 1 ); } + + // calc index value + return( hIndex * height + wIndex ); +} + + +//----------------------------------------------------------------------------- +//----------------------------------------------------------------------------- +void CDispMapImageFilterManager::NEImageValue( CDispMapImageFilter *pFilter, + CMapDisp *pDisp, int orient, + int ndxHgt, int ndxWid, bool bSet, Vector &value ) +{ + // get image index + int index = GetNEImageIndex( pDisp, orient, ndxHgt, ndxWid ); + + // + // return the value at this position + // + if( bSet ) + { + SetImageValue( pDisp, pFilter, index, value ); + } + else + { + GetImageValue( pDisp, pFilter, index, value ); + } +} + + +//----------------------------------------------------------------------------- +//----------------------------------------------------------------------------- +int CDispMapImageFilterManager::GetEImageIndex( CMapDisp *pDisp, int orient, int ndxHgt, int ndxWid ) +{ + // + // get the image height and width + // + int height = pDisp->GetHeight(); + int width = pDisp->GetWidth(); + + // + // + // + int hIndex, wIndex; + switch( orient ) + { + case IMAGEFILTER_ORIENT_WEST: + { + hIndex = ndxHgt; + wIndex = ndxWid - ( width - 1 ); + break; + } + case IMAGEFILTER_ORIENT_NORTH: + { + hIndex = ( 2 * ( height - 1 ) ) - ndxWid; + wIndex = ndxHgt; + break; + } + case IMAGEFILTER_ORIENT_EAST: + { + hIndex = ( height - 1 ) - ndxHgt; + wIndex = ( 2 * ( width - 1 ) ) - ndxWid; + break; + } + case IMAGEFILTER_ORIENT_SOUTH: + { + hIndex = ndxWid - ( height - 1 ); + wIndex = ( width - 1 ) - ndxHgt; + break; + } + default: + { + hIndex = 0; + wIndex = 0; + } + } + + // + // clamp height and width index values + // + if( hIndex < 0 ) { hIndex = 0; } + if( wIndex < 0 ) { wIndex = 0; } + if( hIndex > ( height - 1 ) ) { hIndex = ( height - 1 ); } + if( wIndex > ( width - 1 ) ) { wIndex = ( width - 1 ); } + + // calc index value + return( hIndex * height + wIndex ); +} + + +//----------------------------------------------------------------------------- +//----------------------------------------------------------------------------- +void CDispMapImageFilterManager::EImageValue( CDispMapImageFilter *pFilter, + CMapDisp *pDisp, int orient, + int ndxHgt, int ndxWid, bool bSet, Vector &value ) +{ + // get image index + int index = GetEImageIndex( pDisp, orient, ndxHgt, ndxWid ); + + // + // return the value at this position + // + if( bSet ) + { + SetImageValue( pDisp, pFilter, index, value ); + } + else + { + GetImageValue( pDisp, pFilter, index, value ); + } +} + + +//----------------------------------------------------------------------------- +//----------------------------------------------------------------------------- +int CDispMapImageFilterManager::GetSEImageIndex( CMapDisp *pDisp, int orient, int ndxHgt, int ndxWid ) +{ + // + // get the image height and width + // + int height = pDisp->GetHeight(); + int width = pDisp->GetWidth(); + + // + // + // + int hIndex, wIndex; + switch( orient ) + { + case IMAGEFILTER_ORIENT_SOUTHWEST: + { + hIndex = ndxWid - ( height - 1 ); + wIndex = -ndxHgt; + break; + } + case IMAGEFILTER_ORIENT_SOUTHEAST: + { + hIndex = -ndxHgt; + wIndex = ( 2 * ( width - 1 ) ) - ndxWid; + break; + } + case IMAGEFILTER_ORIENT_NORTHWEST: + { + hIndex = ( height - 1 ) + ndxHgt; + wIndex = ndxWid - ( width - 1 ); + break; + } + case IMAGEFILTER_ORIENT_NORTHEAST: + { + hIndex = ( 2 * ( height - 1 ) ) - ndxWid; + wIndex = ( width - 1 ) + ndxHgt; + break; + } + default: + { + hIndex = 0; + wIndex = 0; + } + } + + // + // clamp height and width index values + // + if( hIndex < 0 ) { hIndex = 0; } + if( wIndex < 0 ) { wIndex = 0; } + if( hIndex > ( height - 1 ) ) { hIndex = ( height - 1 ); } + if( wIndex > ( width - 1 ) ) { wIndex = ( width - 1 ); } + + // calc index value + return( hIndex * height + wIndex ); +} + + +//----------------------------------------------------------------------------- +//----------------------------------------------------------------------------- +void CDispMapImageFilterManager::SEImageValue( CDispMapImageFilter *pFilter, + CMapDisp *pDisp, int orient, + int ndxHgt, int ndxWid, bool bSet, Vector &value ) +{ + // get image index + int index = GetSEImageIndex( pDisp, orient, ndxHgt, ndxWid ); + // + // return the value at this position + // + if( bSet ) + { + SetImageValue( pDisp, pFilter, index, value ); + } + else + { + GetImageValue( pDisp, pFilter, index, value ); + } +} + + +//----------------------------------------------------------------------------- +//----------------------------------------------------------------------------- +int CDispMapImageFilterManager::GetSImageIndex( CMapDisp *pDisp, int orient, int ndxHgt, int ndxWid ) +{ + // + // get the image height and width + // + int height = pDisp->GetHeight(); + int width = pDisp->GetWidth(); + + // + // + // + int hIndex, wIndex; + switch( orient ) + { + case IMAGEFILTER_ORIENT_WEST: + { + hIndex = ndxWid; + wIndex = -ndxHgt; + break; + } + case IMAGEFILTER_ORIENT_NORTH: + { + hIndex = ( height - 1 ) + ndxHgt; + wIndex = ndxWid; + break; + } + case IMAGEFILTER_ORIENT_EAST: + { + hIndex = ( height - 1 ) - ndxWid; + wIndex = ( width - 1 ) + ndxHgt; + break; + } + case IMAGEFILTER_ORIENT_SOUTH: + { + hIndex = -ndxHgt; + wIndex = ( width - 1 ) - ndxWid; + break; + } + default: + { + hIndex = 0; + wIndex = 0; + } + } + + // + // clamp height and width index values + // + if( hIndex < 0 ) { hIndex = 0; } + if( wIndex < 0 ) { wIndex = 0; } + if( hIndex > ( height - 1 ) ) { hIndex = ( height - 1 ); } + if( wIndex > ( width - 1 ) ) { wIndex = ( width - 1 ); } + + // calc index value + return( hIndex * height + wIndex ); +} + + +//----------------------------------------------------------------------------- +//----------------------------------------------------------------------------- +void CDispMapImageFilterManager::SImageValue( CDispMapImageFilter *pFilter, + CMapDisp *pDisp, int orient, + int ndxHgt, int ndxWid, bool bSet, Vector &value ) +{ + // get image index + int index = GetSImageIndex( pDisp, orient, ndxHgt, ndxWid ); + + // + // return the value at this position + // + if( bSet ) + { + SetImageValue( pDisp, pFilter, index, value ); + } + else + { + GetImageValue( pDisp, pFilter, index, value ); + } +} + + +//----------------------------------------------------------------------------- +//----------------------------------------------------------------------------- +void CDispMapImageFilterManager::ClampValues( CDispMapImageFilter *pFilter, Vector &v ) +{ + if( pFilter->m_DataType == DISPPAINT_CHANNEL_ALPHA ) + { + if( v.x < 0.0f ) { v.x = 0.0f; } + if( v.x > 255.0f ) { v.x = 255.0f; } + } +} + + +//----------------------------------------------------------------------------- +//----------------------------------------------------------------------------- +bool CDispMapImageFilterManager::GetFilterVector( CDispMapImageFilter *pFilter, + CMapDisp *pDisp, int ndxHgt, int ndxWid, + int ndxImg, int imgCount, int ndxFilter, + Vector &vFilterDir ) +{ + // + // handle the alpha case + // + if( pFilter->m_DataType == DISPPAINT_CHANNEL_ALPHA ) + { + vFilterDir.Init( ( pFilter->m_pImage[ndxFilter] * pFilter->m_Scale ), 0.0f, 0.0f ); + return true; + } + + // + // get the image (displacement) given a position + // + int orient; + CMapDisp *pNeighborDisp = GetImage( pFilter, pDisp, ndxHgt, ndxWid, ndxImg, imgCount, orient ); + if( !pNeighborDisp ) + return false; + + Vector normal; + normal = m_PaintDir; + + if( m_PaintType == DISPPAINT_AXIS_SUBDIV ) + { + switch( ndxImg ) + { + case IMAGEFILTER_SOUTHWEST: + { + int ndx = GetSWImageIndex( pNeighborDisp, orient, ndxHgt, ndxWid ); + pNeighborDisp->GetSubdivNormal( ndx, normal ); + break; + } + case IMAGEFILTER_WEST: + { + int ndx = GetWImageIndex( pNeighborDisp, orient, ndxHgt, ndxWid ); + pNeighborDisp->GetSubdivNormal( ndx, normal ); + break; + } + case IMAGEFILTER_NORTHWEST: + { + int ndx = GetNWImageIndex( pNeighborDisp, orient, ndxHgt, ndxWid ); + pNeighborDisp->GetSubdivNormal( ndx, normal ); + break; + } + case IMAGEFILTER_NORTH: + { + int ndx = GetNImageIndex( pNeighborDisp, orient, ndxHgt, ndxWid ); + pNeighborDisp->GetSubdivNormal( ndx, normal ); + break; + } + case IMAGEFILTER_NORTHEAST: + { + int ndx = GetNEImageIndex( pNeighborDisp, orient, ndxHgt, ndxWid ); + pNeighborDisp->GetSubdivNormal( ndx, normal ); + break; + } + case IMAGEFILTER_EAST: + { + int ndx = GetEImageIndex( pNeighborDisp, orient, ndxHgt, ndxWid ); + pNeighborDisp->GetSubdivNormal( ndx, normal ); + break; + } + case IMAGEFILTER_SOUTHEAST: + { + int ndx = GetSEImageIndex( pNeighborDisp, orient, ndxHgt, ndxWid ); + pNeighborDisp->GetSubdivNormal( ndx, normal ); + break; + } + case IMAGEFILTER_SOUTH: + { + int ndx = GetSImageIndex( pNeighborDisp, orient, ndxHgt, ndxWid ); + pNeighborDisp->GetSubdivNormal( ndx, normal ); + break; + } + case IMAGEFILTER_MAIN: + { + int ndx = ndxHgt * pDisp->GetWidth() + ndxWid; + pDisp->GetSubdivNormal( ndx, normal ); + break; + } + default: + { + return false; + } + } + } + + vFilterDir = normal * ( pFilter->m_pImage[ndxFilter] * pFilter->m_Scale ); + return true; +} + + +//----------------------------------------------------------------------------- +//----------------------------------------------------------------------------- +void CDispMapImageFilterManager::ApplyAddFilter( CDispMapImageFilter *pFilter, + CMapDisp *pDisp, int iVert ) +{ + // Get displacement image and filter height and width data + int nImageHeight = pDisp->GetHeight(); + int nImageWidth = pDisp->GetWidth(); + + int nFilterHeight = pFilter->m_Height; + int nFilterWidth = pFilter->m_Width; + + // Calculate filter mid point. + int nFilterMidHeight = ( nFilterHeight - 1 ) / 2; + int nFilterMidWidth = ( nFilterWidth - 1 ) / 2; + + // Componentize image index. + int iVertHeight = iVert / nImageHeight; + int iVertWidth = iVert % nImageWidth; + + // For all positions in filter + Vector vecImage; + for( int iHgt = 0; iHgt < nFilterHeight; ++iHgt ) + { + for( int iWid = 0; iWid < nFilterWidth; ++iWid ) + { + // Position relative to the center of the filter. + int nHeight = iHgt - nFilterMidHeight; + int nWidth = iWid - nFilterMidWidth; + + // Adjusted height and width. + int nAdjHeight = iVertHeight + nHeight; + int nAdjWidth = iVertWidth + nWidth; + + // Setup the hit data. + PosHitData_t hitData; + HitData_Setup( hitData, nAdjHeight, nAdjWidth, nImageHeight, nImageWidth ); + + // Update corners. + if( hitData.m_CornerCount != 0 ) + { + for( int iCorner = 0; iCorner < hitData.m_CornerCount; ++iCorner ) + { + int nCount = GetCornerImageCount( pDisp, hitData.m_ndxCorners[iCorner] ); + for( int iCurCorner = 0; iCurCorner < nCount; ++iCurCorner ) + { + if( GetImageValues( pFilter, pDisp, nAdjHeight, nAdjWidth, hitData.m_ndxCorners[iCorner], iCurCorner, vecImage ) ) + { + Vector vecFilter; + GetFilterVector( pFilter, pDisp, nAdjHeight, nAdjWidth, hitData.m_ndxCorners[iCorner], iCurCorner, ( iHgt * nFilterHeight + iWid ), vecFilter ); + vecImage += vecFilter; + + // Clamp values (for alpha). + ClampValues( pFilter, vecImage ); + + SetImageValues( pFilter, pDisp, nAdjHeight, nAdjWidth, hitData.m_ndxCorners[iCorner], iCurCorner, vecImage ); + } + } + } + } + + // Update edges. + if( hitData.m_EdgeCount != 0 ) + { + for( int iEdge = 0; iEdge < hitData.m_EdgeCount; ++iEdge ) + { + if( GetImageValues( pFilter, pDisp, nAdjHeight, nAdjWidth, hitData.m_ndxEdges[iEdge], 0, vecImage ) ) + { + Vector vecFilter; + GetFilterVector( pFilter, pDisp, nAdjHeight, nAdjWidth, hitData.m_ndxEdges[iEdge], 0, ( iHgt * nFilterHeight + iWid ), vecFilter ); + vecImage += vecFilter; + + // Clamp values (for alpha). + ClampValues( pFilter, vecImage ); + + SetImageValues( pFilter, pDisp, nAdjHeight, nAdjWidth, hitData.m_ndxEdges[iEdge], 0, vecImage ); + } + } + } + + // Update main. + if( hitData.m_bMain ) + { + if( GetImageValues( pFilter, pDisp, nAdjHeight, nAdjWidth, IMAGEFILTER_MAIN, 0, vecImage ) ) + { + Vector vecFilter; + GetFilterVector( pFilter, pDisp, nAdjHeight, nAdjWidth, IMAGEFILTER_MAIN, 0, ( iHgt * nFilterHeight + iWid ), vecFilter ); + vecImage += vecFilter; + + // Clamp values (for alpha). + ClampValues( pFilter, vecImage ); + + SetImageValues( pFilter, pDisp, nAdjHeight, nAdjWidth, IMAGEFILTER_MAIN, 0, vecImage ); + } + } + } + } +} + + +//----------------------------------------------------------------------------- +//----------------------------------------------------------------------------- +void CDispMapImageFilterManager::ApplyMultFilter( CDispMapImageFilter *pFilter, + CMapDisp *pDisp, int ndxVert ) +{ + // + // get displacement image and filter height and width data + // + int imgHgt = pDisp->GetHeight(); + int imgWid = pDisp->GetWidth(); + + int filterHgt = pFilter->m_Height; + int filterWid = pFilter->m_Width; + + // + // get filter mid point + // + int filterMidHgt = ( filterHgt - 1 ) / 2; + int filterMidWid = ( filterWid - 1 ) / 2; + + // + // componentize image index + // + int ndxVertHgt = ndxVert / imgHgt; + int ndxVertWid = ndxVert % imgWid; + + // + // for all positions in filter + // + Vector vImg; + for( int ndxHgt = 0; ndxHgt < filterHgt; ndxHgt++ ) + { + for( int ndxWid = 0; ndxWid < filterWid; ndxWid++ ) + { + // position relative to the center of the filter + int height = ndxHgt - filterMidHgt; + int width = ndxWid - filterMidWid; + + // adjusted height and width + int adjHgt = ndxVertHgt + height; + int adjWid = ndxVertWid + width; + + // setup the hit data + PosHitData_t hitData; + HitData_Setup( hitData, adjHgt, adjWid, imgHgt, imgWid ); + + // update corners + if( hitData.m_CornerCount != 0 ) + { + for( int i = 0; i < hitData.m_CornerCount; i++ ) + { + int count = GetCornerImageCount( pDisp, hitData.m_ndxCorners[i] ); + for( int j = 0; j < count; j++ ) + { + if( GetImageValues( pFilter, pDisp, adjHgt, adjWid, hitData.m_ndxCorners[i], j, vImg ) ) + { + Vector vFilter; + GetFilterVector( pFilter, pDisp, adjHgt, adjWid, hitData.m_ndxCorners[i], j, (ndxHgt*filterHgt+ndxWid), vFilter ); + vImg *= vFilter; + + // clamp values (for alpha) + ClampValues( pFilter, vImg ); + + SetImageValues( pFilter, pDisp, adjHgt, adjWid, hitData.m_ndxCorners[i], j, vImg ); + } + } + } + } + + // update edges + if( hitData.m_EdgeCount != 0 ) + { + for( int i = 0; i < hitData.m_EdgeCount; i++ ) + { + if( GetImageValues( pFilter, pDisp, adjHgt, adjWid, hitData.m_ndxEdges[i], 0, vImg ) ) + { + Vector vFilter; + GetFilterVector( pFilter, pDisp, adjHgt, adjWid, hitData.m_ndxEdges[i], 0, (ndxHgt*filterHgt+ndxWid), vFilter ); + vImg += vFilter; + + // clamp values (for alpha) + ClampValues( pFilter, vImg ); + + SetImageValues( pFilter, pDisp, adjHgt, adjWid, hitData.m_ndxEdges[i], 0, vImg ); + } + } + } + + // update main + if( hitData.m_bMain ) + { + if( GetImageValues( pFilter, pDisp, adjHgt, adjWid, IMAGEFILTER_MAIN, 0, vImg ) ) + { + Vector vFilter; + GetFilterVector( pFilter, pDisp, adjHgt, adjWid, IMAGEFILTER_MAIN, 0, (ndxHgt*filterHgt+ndxWid), vFilter ); + vImg += vFilter; + + // clamp values (for alpha) + ClampValues( pFilter, vImg ); + + SetImageValues( pFilter, pDisp, adjHgt, adjWid, IMAGEFILTER_MAIN, 0, vImg ); + } + } + } + } +} + + +//----------------------------------------------------------------------------- +//----------------------------------------------------------------------------- +void CDispMapImageFilterManager::Apply3x3SmoothFilter( CDispMapImageFilter *pFilter, + CMapDisp *pDisp, int ndxVert, + Vector &vPos ) +{ + // + // get displacement image and filter height and width data + // + int imgHgt = pDisp->GetHeight(); + int imgWid = pDisp->GetWidth(); + + int filterHgt = pFilter->m_Height; + int filterWid = pFilter->m_Width; + + int filterMidHgt = ( pFilter->m_Height - 1 ) / 2; + int filterMidWid = ( pFilter->m_Width - 1 ) / 2; + + // + // componentize image index + // + int ndxVertHgt = ndxVert / imgHgt; + int ndxVertWid = ndxVert % imgWid; + + Vector vNormal; + Vector vNormals( 0.0f, 0.0f, 0.0f ); + float dist; + float dists = 0.0f; + float totalFrac = 0.0f; + + for( int ndxHgt = 0; ndxHgt < filterHgt; ndxHgt++ ) + { + for( int ndxWid = 0; ndxWid < filterWid; ndxWid++ ) + { + // position relative to the center of the filter + int height = ndxHgt - filterMidHgt; + int width = ndxWid - filterMidWid; + + // adjusted height and width + int adjHgt = ndxVertHgt + height; + int adjWid = ndxVertWid + width; + + // setup the hit data + PosHitData_t hitData; + HitData_Setup( hitData, adjHgt, adjWid, imgHgt, imgWid ); + + // update corners + if( hitData.m_CornerCount != 0 ) + { + for( int i = 0; i < hitData.m_CornerCount; i++ ) + { + int count = GetCornerImageCount( pDisp, hitData.m_ndxCorners[i] ); + for( int j = 0; j < count; j++ ) + { + if( GetImageFieldValues( pFilter, pDisp, adjHgt, adjWid, hitData.m_ndxCorners[i], j, vNormal, dist ) ) + { + vNormals += ( vNormal * pFilter->m_pImage[ndxHgt*filterHgt+ndxWid] ); + dists += ( dist * pFilter->m_pImage[ndxHgt*filterHgt+ndxWid] ); + totalFrac += pFilter->m_pImage[ndxHgt*filterHgt+ndxWid]; + } + } + } + } + + // update edges + if( hitData.m_EdgeCount != 0 ) + { + for( int i = 0; i < hitData.m_EdgeCount; i++ ) + { + if( GetImageFieldValues( pFilter, pDisp, adjHgt, adjWid, hitData.m_ndxEdges[i], 0, vNormal, dist ) ) + { + vNormals += ( vNormal * pFilter->m_pImage[ndxHgt*filterHgt+ndxWid] ); + dists += ( dist * pFilter->m_pImage[ndxHgt*filterHgt+ndxWid] ); + totalFrac += pFilter->m_pImage[ndxHgt*filterHgt+ndxWid]; + } + } + } + + // update main + if( hitData.m_bMain ) + { + if( GetImageFieldValues( pFilter, pDisp, adjHgt, adjWid, IMAGEFILTER_MAIN, 0, vNormal, dist ) ) + { + vNormals += ( vNormal * pFilter->m_pImage[ndxHgt*filterHgt+ndxWid] ); + dists += ( dist * pFilter->m_pImage[ndxHgt*filterHgt+ndxWid] ); + totalFrac += pFilter->m_pImage[ndxHgt*filterHgt+ndxWid]; + } + } + } + } + + VectorNormalize( vNormals ); + dists /= totalFrac; + + vPos = vNormals * dists; +} + + +//----------------------------------------------------------------------------- +//----------------------------------------------------------------------------- +void CDispMapImageFilterManager::ApplySmoothFilter( CDispMapImageFilter *pFilter, + CMapDisp *pDisp, int ndxVert ) +{ + // + // get displacement image and filter height and width data + // + int imgHgt = pDisp->GetHeight(); + int imgWid = pDisp->GetWidth(); + + int areaHgt = pFilter->m_AreaHeight; + int areaWid = pFilter->m_AreaWidth; + + int areaMidHgt = ( areaHgt - 1 ) / 2; + int areaMidWid = ( areaWid - 1 ) / 2; + + // + // componentize image index + // + int ndxVertHgt = ndxVert / imgHgt; + int ndxVertWid = ndxVert % imgWid; + + // + // for all positions in filter + // + Vector vPos; + for( int ndxHgt = 0; ndxHgt < areaHgt; ndxHgt++ ) + { + for( int ndxWid = 0; ndxWid < areaWid; ndxWid++ ) + { + // position relative to the center of the area of effect + int height = ndxHgt - areaMidHgt; + int width = ndxWid - areaMidWid; + + // adjusted height and width + int adjHgt = ndxVertHgt + height; + int adjWid = ndxVertWid + width; + + // setup the hit data + PosHitData_t hitData; + HitData_Setup( hitData, adjHgt, adjWid, imgHgt, imgWid ); + + // update corners + if( hitData.m_CornerCount != 0 ) + { + for( int i = 0; i < hitData.m_CornerCount; i++ ) + { + int count = GetCornerImageCount( pDisp, hitData.m_ndxCorners[i] ); + for( int j = 0; j < count; j++ ) + { + // + // get the current corner + // + int orient; + CMapDisp *pAdjDisp = GetImage( pFilter, pDisp, adjHgt, adjWid, hitData.m_ndxCorners[i], j, orient ); + if( pAdjDisp ) + { + int adjIndex = GetAdjustedIndex( pAdjDisp, orient, adjHgt, adjWid, hitData.m_ndxCorners[i] ); + + // apply a 3x3 box filter at each position + Apply3x3SmoothFilter( pFilter, pAdjDisp, adjIndex, vPos ); + + // get the flat/subdivision position + Vector vFlat, vSubPos; + pAdjDisp->GetFlatVert( adjIndex, vFlat ); + pAdjDisp->GetSubdivPosition( adjIndex, vSubPos ); + + vPos += vFlat; + vPos += vSubPos; + + SetImageValue( pAdjDisp, pFilter, adjIndex, vPos ); + } + } + } + } + + // update edges + if( hitData.m_EdgeCount != 0 ) + { + for( int i = 0; i < hitData.m_EdgeCount; i++ ) + { + // + // get the current corner + // + int orient; + CMapDisp *pAdjDisp = GetImage( pFilter, pDisp, adjHgt, adjWid, hitData.m_ndxEdges[i], 0, orient ); + if( pAdjDisp ) + { + int adjIndex = GetAdjustedIndex( pAdjDisp, orient, adjHgt, adjWid, hitData.m_ndxEdges[i] ); + + // apply a 3x3 box filter at each position + Apply3x3SmoothFilter( pFilter, pAdjDisp, adjIndex, vPos ); + + // get the flat/subdivision position + Vector vFlat, vSubPos; + pAdjDisp->GetFlatVert( adjIndex, vFlat ); + pAdjDisp->GetSubdivPosition( adjIndex, vSubPos ); + + vPos += vFlat; + vPos += vSubPos; + + SetImageValue( pAdjDisp, pFilter, adjIndex, vPos ); + } + } + } + + // update main + if( hitData.m_bMain ) + { + // + // get the current corner + // + int orient; + CMapDisp *pAdjDisp = GetImage( pFilter, pDisp, adjHgt, adjWid, IMAGEFILTER_MAIN, 0, orient ); + if( pAdjDisp ) + { + int adjIndex = GetAdjustedIndex( pAdjDisp, orient, adjHgt, adjWid, IMAGEFILTER_MAIN ); + + // apply a 3x3 box filter at each position + Apply3x3SmoothFilter( pFilter, pAdjDisp, adjIndex, vPos ); + + // get the flat/subdivision position + Vector vFlat, vSubPos; + pAdjDisp->GetFlatVert( adjIndex, vFlat ); + pAdjDisp->GetSubdivPosition( adjIndex, vSubPos ); + + vPos += vFlat; + vPos += vSubPos; + + SetImageValue( pAdjDisp, pFilter, adjIndex, vPos ); + } + } + } + } +} + + +//----------------------------------------------------------------------------- +//----------------------------------------------------------------------------- +bool CDispMapImageFilterManager::IsEqualMask( CDispMapImageFilter *pFilter, int ndxFilter ) +{ + if( pFilter->m_pImage[ndxFilter] == IMAGEFILTER_EQUALMASK ) + return true; + + return false; +} + + +//----------------------------------------------------------------------------- +//----------------------------------------------------------------------------- +void CDispMapImageFilterManager::ApplyEqualFilter( CDispMapImageFilter *pFilter, + CMapDisp *pDisp, int ndxVert ) +{ + // + // get displacement image and filter height and width data + // + int imgHgt = pDisp->GetHeight(); + int imgWid = pDisp->GetWidth(); + + int filterHgt = pFilter->m_Height; + int filterWid = pFilter->m_Width; + + // + // get filter mid point + // + int filterMidHgt = ( filterHgt - 1 ) / 2; + int filterMidWid = ( filterWid - 1 ) / 2; + + // + // componentize image index + // + int ndxVertHgt = ndxVert / imgHgt; + int ndxVertWid = ndxVert % imgWid; + + // + // for all positions in filter + // + Vector vImg; + for( int ndxHgt = 0; ndxHgt < filterHgt; ndxHgt++ ) + { + for( int ndxWid = 0; ndxWid < filterWid; ndxWid++ ) + { + // position relative to the center of the filter + int height = ndxHgt - filterMidHgt; + int width = ndxWid - filterMidWid; + + // adjusted height and width + int adjHgt = ndxVertHgt + height; + int adjWid = ndxVertWid + width; + + // setup the hit data + PosHitData_t hitData; + HitData_Setup( hitData, adjHgt, adjWid, imgHgt, imgWid ); + + // update corners + if( hitData.m_CornerCount != 0 ) + { + for( int i = 0; i < hitData.m_CornerCount; i++ ) + { + int count = GetCornerImageCount( pDisp, hitData.m_ndxCorners[i] ); + for( int j = 0; j < count; j++ ) + { + if( GetImageFlatSubdivValues( pFilter, pDisp, adjHgt, adjWid, hitData.m_ndxCorners[i], j, vImg ) ) + { + if( !IsEqualMask( pFilter, (ndxHgt*filterHgt+ndxWid) ) ) + { + Vector vFilter; + GetFilterVector( pFilter, pDisp, adjHgt, adjWid, hitData.m_ndxCorners[i], j, (ndxHgt*filterHgt+ndxWid), vFilter ); + vImg += vFilter; + + ClampValues( pFilter, vImg ); + + SetImageValues( pFilter, pDisp, adjHgt, adjWid, hitData.m_ndxCorners[i], j, vImg ); + } + } + } + } + } + + // update edges + if( hitData.m_EdgeCount != 0 ) + { + for( int i = 0; i < hitData.m_EdgeCount; i++ ) + { + if( GetImageFlatSubdivValues( pFilter, pDisp, adjHgt, adjWid, hitData.m_ndxEdges[i], 0, vImg ) ) + { + if( !IsEqualMask( pFilter, (ndxHgt*filterHgt+ndxWid) ) ) + { + Vector vFilter; + GetFilterVector( pFilter, pDisp, adjHgt, adjWid, hitData.m_ndxEdges[i], 0, (ndxHgt*filterHgt+ndxWid), vFilter ); + vImg += vFilter; + + ClampValues( pFilter, vImg ); + + SetImageValues( pFilter, pDisp, adjHgt, adjWid, hitData.m_ndxEdges[i], 0, vImg ); + } + } + } + } + + // update main + if( hitData.m_bMain ) + { + if( GetImageFlatSubdivValues( pFilter, pDisp, adjHgt, adjWid, IMAGEFILTER_MAIN, 0, vImg ) ) + { + if( !IsEqualMask( pFilter, (ndxHgt*filterHgt+ndxWid) ) ) + { + Vector vFilter; + GetFilterVector( pFilter, pDisp, adjHgt, adjWid, IMAGEFILTER_MAIN, 0, (ndxHgt*filterHgt+ndxWid), vFilter ); + vImg += vFilter; + + ClampValues( pFilter, vImg ); + + SetImageValues( pFilter, pDisp, adjHgt, adjWid, IMAGEFILTER_MAIN, 0, vImg ); + } + } + } + } + } +} + + |