You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
2477 lines
65 KiB
2477 lines
65 KiB
//========= 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 ); |
|
} |
|
} |
|
} |
|
} |
|
} |
|
} |
|
|
|
|
|
|