//========= 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 #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 #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 ); } } } } } }