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.
767 lines
22 KiB
767 lines
22 KiB
/*==LICENSE==* |
|
|
|
CyanWorlds.com Engine - MMOG client, server and tools |
|
Copyright (C) 2011 Cyan Worlds, Inc. |
|
|
|
This program is free software: you can redistribute it and/or modify |
|
it under the terms of the GNU General Public License as published by |
|
the Free Software Foundation, either version 3 of the License, or |
|
(at your option) any later version. |
|
|
|
This program is distributed in the hope that it will be useful, |
|
but WITHOUT ANY WARRANTY; without even the implied warranty of |
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|
GNU General Public License for more details. |
|
|
|
You should have received a copy of the GNU General Public License |
|
along with this program. If not, see <http://www.gnu.org/licenses/>. |
|
|
|
Additional permissions under GNU GPL version 3 section 7 |
|
|
|
If you modify this Program, or any covered work, by linking or |
|
combining it with any of RAD Game Tools Bink SDK, Autodesk 3ds Max SDK, |
|
NVIDIA PhysX SDK, Microsoft DirectX SDK, OpenSSL library, Independent |
|
JPEG Group JPEG library, Microsoft Windows Media SDK, or Apple QuickTime SDK |
|
(or a modified version of those libraries), |
|
containing parts covered by the terms of the Bink SDK EULA, 3ds Max EULA, |
|
PhysX SDK EULA, DirectX SDK EULA, OpenSSL and SSLeay licenses, IJG |
|
JPEG Library README, Windows Media SDK EULA, or QuickTime SDK EULA, the |
|
licensors of this Program grant you additional |
|
permission to convey the resulting work. Corresponding Source for a |
|
non-source form of such a combination shall include the source code for |
|
the parts of OpenSSL and IJG JPEG Library used as well as that of the covered |
|
work. |
|
|
|
You can contact Cyan Worlds, Inc. by email legal@cyan.com |
|
or by snail mail at: |
|
Cyan Worlds, Inc. |
|
14617 N Newport Hwy |
|
Mead, WA 99021 |
|
|
|
*==LICENSE==*/ |
|
#include "hsTypes.h" |
|
#include "plLayerTex.h" |
|
#include "plLayerTexBitmapPB.h" |
|
#include "plDetailCurveCtrl.h" |
|
|
|
#if 1 |
|
class BMTexPBAccessor; |
|
extern BMTexPBAccessor bmtex_accessor; |
|
|
|
class BitmapDlgProc; |
|
extern BitmapDlgProc gBitmapDlgProc; |
|
|
|
static ParamBlockDesc2 gBitmapParamBlk |
|
( |
|
plLayerTex::kBlkBitmap, _T("bitmap"), 0, GetLayerTexDesc(),//NULL, |
|
P_AUTO_CONSTRUCT + P_AUTO_UI, plLayerTex::kRefBitmap, |
|
|
|
IDD_LAYER_TEX, IDS_LAYER_TEX, 0, 0, &gBitmapDlgProc, |
|
|
|
// Bitmap |
|
kBmpUseBitmap, _T("useBitmap"), TYPE_BOOL, 0, 0, |
|
p_default, TRUE, |
|
p_ui, TYPE_SINGLECHEKBOX, IDC_USE_BITMAP, |
|
end, |
|
kBmpBitmap, _T("bitmap"), TYPE_BITMAP, P_SHORT_LABELS, 0, |
|
p_accessor, &bmtex_accessor, |
|
end, |
|
|
|
// Crop/Place |
|
kBmpApply, _T("apply"), TYPE_BOOL, 0, 0, |
|
p_default, FALSE, |
|
p_ui, TYPE_SINGLECHEKBOX, IDC_BM_CLIP, |
|
end, |
|
kBmpCropPlace, _T("cropPlace"), TYPE_INT, 0, 0, |
|
p_default, 0, |
|
p_range, 0, 1, |
|
p_ui, TYPE_RADIO, 2, IDC_BM_CROP,IDC_BM_PLACE, |
|
end, |
|
kBmpClipU, _T("clipU"), TYPE_FLOAT, P_ANIMATABLE, IDS_BITMAP_CLIPU, |
|
p_default, 0.0, |
|
p_range, 0.0, 1.0, |
|
p_ui, TYPE_SPINNER, EDITTYPE_FLOAT, IDC_CLIP_X, IDC_CLIP_XSPIN, 0.001f, |
|
p_accessor, &bmtex_accessor, |
|
end, |
|
kBmpClipV, _T("clipV"), TYPE_FLOAT, P_ANIMATABLE, IDS_BITMAP_CLIPV, |
|
p_default, 0.0, |
|
p_range, 0.0, 1.0, |
|
p_ui, TYPE_SPINNER, EDITTYPE_FLOAT, IDC_CLIP_Y, IDC_CLIP_YSPIN, 0.001f, |
|
p_accessor, &bmtex_accessor, |
|
end, |
|
kBmpClipW, _T("clipW"), TYPE_FLOAT, P_ANIMATABLE, IDS_BITMAP_CLIPW, |
|
p_default, 1.0, |
|
p_range, 0.0, 1.0, |
|
p_ui, TYPE_SPINNER, EDITTYPE_FLOAT, IDC_CLIP_W, IDC_CLIP_WSPIN, 0.001f, |
|
p_accessor, &bmtex_accessor, |
|
end, |
|
kBmpClipH, _T("clipH"), TYPE_FLOAT, P_ANIMATABLE, IDS_BITMAP_CLIPH, |
|
p_default, 1.0, |
|
p_range, 0.0, 1.0, |
|
p_ui, TYPE_SPINNER, EDITTYPE_FLOAT, IDC_CLIP_H, IDC_CLIP_HSPIN, 0.001f, |
|
p_accessor, &bmtex_accessor, |
|
end, |
|
|
|
// Texture Color/Alpha |
|
kBmpDiscardColor, _T("discardColor"), TYPE_BOOL, 0, 0, |
|
p_ui, TYPE_SINGLECHEKBOX, IDC_BLEND_NO_COLOR, |
|
end, |
|
kBmpInvertColor, _T("invertColor"), TYPE_BOOL, 0, 0, |
|
p_ui, TYPE_SINGLECHEKBOX, IDC_BLEND_INV_COLOR, |
|
end, |
|
kBmpDiscardAlpha, _T("discardAlpha"), TYPE_BOOL, 0, 0, |
|
p_ui, TYPE_SINGLECHEKBOX, IDC_DISCARD_ALPHA, |
|
end, |
|
kBmpInvertAlpha, _T("invertAlpha"), TYPE_BOOL, 0, 0, |
|
p_ui, TYPE_SINGLECHEKBOX, IDC_BLEND_INV_ALPHA, |
|
end, |
|
|
|
// Texture Quality |
|
kBmpNonCompressed, _T("nonCompressed"),TYPE_BOOL, 0, 0, |
|
p_ui, TYPE_SINGLECHEKBOX, IDC_FORCE_NONCOMPRESSED, |
|
end, |
|
kBmpScaling, _T("scaling"), TYPE_INT, 0, 0, |
|
p_ui, TYPE_RADIO, 3, IDC_SCALE_ALL, IDC_SCALE_HALF, IDC_SCALE_NONE, |
|
end, |
|
|
|
// Max Only |
|
kBmpMonoOutput, _T("monoOutput"), TYPE_INT, 0, 0, |
|
p_ui, TYPE_RADIO, 2, IDC_HSMAX_LAYER_RGBOUT, IDC_HSMAX_LAYER_ALPHAOUT, |
|
end, |
|
kBmpRGBOutput, _T("rgbOutput"), TYPE_INT, 0, 0, |
|
p_ui, TYPE_RADIO, 2, IDC_HSMAX_LAYER_RGBOUT2, IDC_HSMAX_LAYER_ALPHAOUT2, |
|
end, |
|
|
|
// Mipmap |
|
kBmpNoFilter, _T("noFilter"), TYPE_BOOL, 0, 0, |
|
p_ui, TYPE_SINGLECHEKBOX, IDC_NO_FILTERING, |
|
end, |
|
kBmpMipBlur, _T("mipBlur"), TYPE_FLOAT, 0, 0, |
|
p_ui, TYPE_SPINNER, EDITTYPE_FLOAT, IDC_MIPBLUR_EDIT, IDC_MIPBLUR_SPIN, 0.4, |
|
p_range, 0.01f, 100.0f, |
|
p_default, 1.0, |
|
end, |
|
kBmpMipBias, _T("mipBias"), TYPE_BOOL, 0, 0, |
|
p_ui, TYPE_SINGLECHEKBOX, IDC_USE_MIPBIAS, |
|
p_enable_ctrls, 1, kBmpMipBiasAmt, |
|
end, |
|
kBmpMipBiasAmt, _T("mipBiasAmt"), TYPE_FLOAT, 0, 0, |
|
p_ui, TYPE_SPINNER, EDITTYPE_FLOAT, IDC_MIPBIAS_EDIT, IDC_MIPBIAS_SPIN, 0.7, |
|
p_range, -100.0, 100.0, |
|
p_default, 1.0, |
|
end, |
|
|
|
// Detail |
|
kBmpUseDetail, _T("useDetail"), TYPE_BOOL, 0, 0, |
|
p_ui, TYPE_SINGLECHEKBOX, IDC_USE_DETAIL, |
|
p_default, FALSE, |
|
p_enable_ctrls, 4, kBmpDetailStartSize, kBmpDetailStopSize, kBmpDetailStartOpac, kBmpDetailStopOpac, |
|
p_accessor, &bmtex_accessor, |
|
end, |
|
|
|
kBmpDetailStartSize,_T("dropOffStart"), TYPE_INT, 0, 0, |
|
p_ui, TYPE_SPINNER, EDITTYPE_INT, IDC_DETAIL_START_SIZE_EDIT, IDC_DETAIL_START_SIZE_SPIN, 0.4, |
|
p_range, 0, 100, |
|
p_default, 0, |
|
p_accessor, &bmtex_accessor, |
|
end, |
|
kBmpDetailStopSize, _T("dropOffStop"), TYPE_INT, 0, 0, |
|
p_ui, TYPE_SPINNER, EDITTYPE_INT, IDC_DETAIL_STOP_SIZE_EDIT, IDC_DETAIL_STOP_SIZE_SPIN, 0.4, |
|
p_range, 0, 100, |
|
p_default, 100, |
|
p_accessor, &bmtex_accessor, |
|
end, |
|
kBmpDetailStartOpac, _T("detailMax"), TYPE_INT, 0, 0, |
|
p_ui, TYPE_SPINNER, EDITTYPE_INT, IDC_DETAIL_START_OPAC_EDIT, IDC_DETAIL_START_OPAC_SPIN, 0.4, |
|
p_range, 0, 100, |
|
p_default, 100, |
|
p_accessor, &bmtex_accessor, |
|
end, |
|
kBmpDetailStopOpac, _T("detailMin"), TYPE_INT, 0, 0, |
|
p_ui, TYPE_SPINNER, EDITTYPE_INT, IDC_DETAIL_STOP_OPAC_EDIT, IDC_DETAIL_STOP_OPAC_SPIN, 0.4, |
|
p_range, 0, 100, |
|
p_default, 0, |
|
p_accessor, &bmtex_accessor, |
|
end, |
|
|
|
kBmpExportWidth, _T("exportWidth"), TYPE_INT, 0, 0, |
|
p_ui, TYPE_SPINNER, EDITTYPE_INT, IDC_EXPORTWIDTH, IDC_EXPORTWIDTH_SPINNER, SPIN_AUTOSCALE, |
|
p_range, 4, 2048, |
|
p_default, 512, |
|
end, |
|
kBmpExportHeight, _T("exportHeight"), TYPE_INT, 0, 0, |
|
p_ui, TYPE_SPINNER, EDITTYPE_INT, IDC_EXPORTHEIGHT, IDC_EXPORTHEIGHT_SPINNER, SPIN_AUTOSCALE, |
|
p_range, 4, 2048, |
|
p_default, 512, |
|
end, |
|
kBmpExportLastWidth, _T("lastExportWidth"), TYPE_INT, 0, 0, |
|
end, |
|
kBmpExportLastHeight, _T("lastExportHeight"), TYPE_INT, 0, 0, |
|
end, |
|
|
|
// Keep a sysmem copy at runtime (for image examination/manipulation). |
|
kBmpNoDiscard, _T("noDiscard"), TYPE_BOOL, 0, 0, |
|
p_ui, TYPE_SINGLECHEKBOX, IDC_NO_DISCARD, |
|
p_default, FALSE, |
|
end, |
|
|
|
end |
|
); |
|
ParamBlockDesc2 *GetBitmapBlk() { return &gBitmapParamBlk; } |
|
|
|
class BMCropper; |
|
|
|
class BMTexPBAccessor : public PBAccessor |
|
{ |
|
public: |
|
void Set(PB2Value& val, ReferenceMaker* owner, ParamID id, int tabIndex, TimeValue t) |
|
{ |
|
plLayerTex* layer = (plLayerTex*)owner; |
|
|
|
if(layer == NULL) return; |
|
|
|
IParamBlock2 *pb = layer->GetParamBlockByID(plLayerTex::kBlkBitmap); |
|
|
|
switch (id) |
|
{ |
|
case kBmpBitmap: |
|
if (pb->GetMap()) |
|
pb->GetMap()->Invalidate(kBmpBitmap); |
|
|
|
// Update the bitmap saved by the layer |
|
//layer->SetBitmap(&val.bm->bi, tabIndex); |
|
break; |
|
|
|
/* |
|
case kBmpFilename: |
|
bmt->SetMapName(val.s); |
|
break; |
|
|
|
case kBmpFiltering: |
|
bmt->filterType = val.i; |
|
if (bmt->thebm) |
|
bmt->thebm->SetFilter(bmFilterType(val.i)); |
|
break; |
|
*/ |
|
case kBmpClipU: |
|
{ |
|
float u = val.f; |
|
float w = pb->GetFloat(kBmpClipW, t); |
|
if (u + w > 1.0f) |
|
{ |
|
pb->SetValue(kBmpClipW, t, 1.0f-u); |
|
if (pb->GetMap()) |
|
pb->GetMap()->Invalidate(kBmpClipW); |
|
} |
|
break; |
|
} |
|
case kBmpClipW: |
|
{ |
|
float w = val.f; |
|
float u = pb->GetFloat(kBmpClipU, t); |
|
if (u + w > 1.0f) |
|
{ |
|
pb->SetValue(kBmpClipU, t, 1.0f-w); |
|
if (pb->GetMap()) |
|
pb->GetMap()->Invalidate(kBmpClipU); |
|
} |
|
break; |
|
} |
|
case kBmpClipV: |
|
{ |
|
float v = val.f; |
|
float h = pb->GetFloat(kBmpClipH, t); |
|
if (v + h > 1.0f) |
|
{ |
|
pb->SetValue(kBmpClipH, t, 1.0f-v); |
|
if (pb->GetMap()) |
|
pb->GetMap()->Invalidate(kBmpClipH); |
|
} |
|
break; |
|
} |
|
case kBmpClipH: |
|
{ |
|
float h = val.f; |
|
float v = pb->GetFloat(kBmpClipV, t); |
|
if (v + h > 1.0f) |
|
{ |
|
pb->SetValue(kBmpClipV, t, 1.0f-h); |
|
if (pb->GetMap()) |
|
pb->GetMap()->Invalidate(kBmpClipV); |
|
} |
|
break; |
|
} |
|
|
|
case kBmpDetailStartSize: |
|
case kBmpDetailStopSize: |
|
case kBmpDetailStartOpac: |
|
case kBmpDetailStopOpac: |
|
if( pb != NULL ) |
|
{ |
|
if( IIsProcSettingDetailValues( pb ) ) |
|
break; // Ignore, since we're the ones setting 'em |
|
|
|
HWND dlg = pb->GetMap()->GetHWnd(); |
|
plDetailCurveCtrl *ctrl = GET_DETAIL_CURVE_CTRL( dlg, IDC_DETAIL_CURVE_CTRL ); |
|
if( ctrl != NULL ) |
|
{ |
|
if( id == kBmpDetailStartSize || id == kBmpDetailStartOpac ) |
|
ctrl->SetStartPoint( (float)pb->GetInt( kBmpDetailStartSize, t ) / 100.f, |
|
(float)pb->GetInt( kBmpDetailStartOpac, t ) / 100.f ); |
|
else |
|
ctrl->SetEndPoint( (float)pb->GetInt( kBmpDetailStopSize, t ) / 100.f, |
|
(float)pb->GetInt( kBmpDetailStopOpac, t ) / 100.f ); |
|
} |
|
|
|
// Make sure start is less than end |
|
if( id == kBmpDetailStartSize ) |
|
{ |
|
int end = pb->GetInt( kBmpDetailStopSize, t ); |
|
if( val.i > end ) |
|
pb->SetValue( kBmpDetailStopSize, t, val.i ); |
|
} |
|
else if( id == kBmpDetailStopSize ) |
|
{ |
|
int start = pb->GetInt( kBmpDetailStartSize, t ); |
|
if( val.i < start ) |
|
pb->SetValue( kBmpDetailStartSize, t, val.i ); |
|
} |
|
|
|
} |
|
break; |
|
|
|
case kBmpUseDetail: |
|
if( pb != NULL ) |
|
{ |
|
HWND dlg = pb->GetMap()->GetHWnd(); |
|
EnableWindow( GetDlgItem( dlg, IDC_DETAIL_CURVE_CTRL ), (BOOL)val.i ); |
|
} |
|
break; |
|
} |
|
} |
|
void Get(PB2Value& v, ReferenceMaker* owner, ParamID id, int tabIndex, TimeValue t, Interval &valid) |
|
{ |
|
} |
|
|
|
// Gotta love hacks.... |
|
bool IIsProcSettingDetailValues( IParamBlock2 *pb ); |
|
|
|
}; |
|
static BMTexPBAccessor bmtex_accessor; |
|
|
|
|
|
//========================================================================================= |
|
// BMCropper |
|
//========================================================================================= |
|
class BMCropper : public CropCallback |
|
{ |
|
IParamBlock2 *fPBlock; |
|
|
|
public: |
|
BMCropper(IParamBlock2* pblock) : fPBlock(pblock) {} |
|
|
|
float GetInitU() { return fPBlock->GetFloat(kBmpClipU); } |
|
float GetInitV() { return fPBlock->GetFloat(kBmpClipV); } |
|
float GetInitW() { return fPBlock->GetFloat(kBmpClipW); } |
|
float GetInitH() { return fPBlock->GetFloat(kBmpClipH); } |
|
BOOL GetInitMode() { return fPBlock->GetInt(kBmpCropPlace); } |
|
void SetValues(float u, float v, float w, float h, BOOL md); |
|
void OnClose(); |
|
}; |
|
|
|
void BMCropper::SetValues(float u, float v, float w, float h, BOOL md) |
|
{ |
|
TimeValue t = GetCOREInterface()->GetTime(); |
|
|
|
if (u != fPBlock->GetFloat(kBmpClipU, t)) |
|
{ |
|
fPBlock->SetValue(kBmpClipU, t, u); |
|
fPBlock->GetMap()->Invalidate(kBmpClipU); |
|
} |
|
|
|
if (v != fPBlock->GetFloat(kBmpClipV, t)) |
|
{ |
|
fPBlock->SetValue(kBmpClipV, t, v); |
|
fPBlock->GetMap()->Invalidate(kBmpClipV); |
|
} |
|
|
|
if (w != fPBlock->GetFloat(kBmpClipW, t)) |
|
{ |
|
fPBlock->SetValue(kBmpClipW, t, w); |
|
fPBlock->GetMap()->Invalidate(kBmpClipW); |
|
} |
|
|
|
if (h != fPBlock->GetFloat(kBmpClipH, t)) |
|
{ |
|
fPBlock->SetValue(kBmpClipH, t, h); |
|
fPBlock->GetMap()->Invalidate(kBmpClipH); |
|
} |
|
|
|
if (md != fPBlock->GetInt(kBmpCropPlace)) |
|
{ |
|
fPBlock->SetValue(kBmpCropPlace, t, md); |
|
fPBlock->GetMap()->Invalidate(kBmpCropPlace); |
|
} |
|
} |
|
|
|
void BMCropper::OnClose() |
|
{ |
|
delete this; |
|
} |
|
|
|
class BitmapDlgProc : public ParamMap2UserDlgProc |
|
{ |
|
friend class BMTexPBAccessor; |
|
|
|
|
|
PBBitmap *fLastBMap; |
|
bool fSettingDetailValues; |
|
|
|
|
|
/// Called to update the controls of the dialog |
|
/// Note: we're bad that we use a static here, but |
|
virtual void Update( TimeValue t, Interval &valid, IParamMap2 *map ) |
|
{ |
|
ICustButton *bmSelectBtn; |
|
IParamBlock2 *pblock; |
|
int width, height; |
|
|
|
|
|
ParamMap2UserDlgProc::Update( t, valid, map ); |
|
|
|
if( fSettingDetailValues ) |
|
{ |
|
// We're getting an update just because we changed detail values, so we |
|
// know we don't have to do anything ourselves |
|
return; |
|
} |
|
|
|
pblock = map->GetParamBlock(); |
|
|
|
// Update texture map button |
|
bmSelectBtn = GetICustButton( GetDlgItem( map->GetHWnd(), IDC_LAYER_NAME ) ); |
|
PBBitmap *pbbm = pblock->GetBitmap( kBmpBitmap, t ); |
|
if( pbbm ) |
|
{ |
|
if( pbbm != fLastBMap ) |
|
{ |
|
bmSelectBtn->SetText( (TCHAR *)pbbm->bi.Filename() ); |
|
|
|
// Init values for clamping spinners to powers of 2 |
|
width = IFloorPow2( pbbm->bi.Width() ); |
|
map->SetRange( kBmpExportWidth, 4.f, (float)width ); |
|
|
|
height = IFloorPow2( pbbm->bi.Height() ); |
|
map->SetRange( kBmpExportHeight, 4.f, (float)height ); |
|
|
|
IClampTexSizeSpinner( t, map, true ); |
|
ISetDetailCurveNumLevels( map, t ); |
|
} |
|
} |
|
else if( pbbm != fLastBMap ) |
|
bmSelectBtn->SetText( _T( "None" ) ); |
|
|
|
fLastBMap = pbbm; |
|
|
|
ReleaseICustButton( bmSelectBtn ); |
|
|
|
// Update detail curve control |
|
HWND dlg = map->GetHWnd(); |
|
|
|
plDetailCurveCtrl *ctrl = GET_DETAIL_CURVE_CTRL( dlg, IDC_DETAIL_CURVE_CTRL ); |
|
if( ctrl == NULL ) |
|
{ |
|
// The control hasn't been created, so create it already! |
|
HWND basis; |
|
RECT r; |
|
|
|
// Create the detail map control |
|
basis = GetDlgItem( dlg, IDC_DETAIL_SAMPLE ); |
|
GetClientRect( basis, &r ); |
|
MapWindowPoints( basis, dlg, (POINT *)&r, 2 ); |
|
|
|
ctrl = TRACKED_NEW plDetailCurveCtrl( dlg, IDC_DETAIL_CURVE_CTRL, &r ); |
|
} |
|
|
|
EnableWindow( GetDlgItem( dlg, IDC_DETAIL_CURVE_CTRL ), (BOOL)pblock->GetInt( kBmpUseDetail, t ) ); |
|
|
|
if( ctrl != NULL ) |
|
{ |
|
ctrl->SetStartPoint( (float)pblock->GetInt( kBmpDetailStartSize, t ) / 100.f, |
|
(float)pblock->GetInt( kBmpDetailStartOpac, t ) / 100.f ); |
|
ctrl->SetEndPoint( (float)pblock->GetInt( kBmpDetailStopSize, t ) / 100.f, |
|
(float)pblock->GetInt( kBmpDetailStopOpac, t ) / 100.f ); |
|
} |
|
|
|
} |
|
|
|
BOOL DlgProc(TimeValue t, IParamMap2 *map, HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam) |
|
{ |
|
static ICustButton* bmSelectBtn; |
|
|
|
switch (msg) |
|
{ |
|
case WM_INITDIALOG: |
|
fLastBMap = NULL; |
|
fSettingDetailValues = false; |
|
break; |
|
|
|
/// Note: the following *could* be done in the accessor, except that you end up in an |
|
/// infinite loop updating the values. Not good. |
|
case CC_SPINNER_CHANGE: |
|
|
|
if( LOWORD( wParam ) == IDC_EXPORTWIDTH_SPINNER ) |
|
IClampTexSizeSpinner( t, map, true ); |
|
|
|
else if( LOWORD( wParam ) == IDC_EXPORTHEIGHT_SPINNER ) |
|
IClampTexSizeSpinner( t, map, false ); |
|
|
|
break; |
|
|
|
// Message from the detail curve that a point got dragged |
|
case PL_DC_POINT_DRAGGED: |
|
{ |
|
plDetailCurveCtrl *ctrl = (plDetailCurveCtrl *)lParam; |
|
IParamBlock2 *pblock = map->GetParamBlock(); |
|
float x, y; |
|
|
|
|
|
fSettingDetailValues = true; |
|
|
|
if( wParam == PL_DC_START_POINT ) |
|
{ |
|
ctrl->GetStartPoint( x, y ); |
|
pblock->SetValue( kBmpDetailStartSize, t, (int)( x * 100.f ) ); |
|
pblock->SetValue( kBmpDetailStartOpac, t, (int)( y * 100.f ) ); |
|
} |
|
else |
|
{ |
|
ctrl->GetEndPoint( x, y ); |
|
pblock->SetValue( kBmpDetailStopSize, t, (int)( x * 100.f ) ); |
|
pblock->SetValue( kBmpDetailStopOpac, t, (int)( y * 100.f ) ); |
|
} |
|
|
|
map->UpdateUI( t ); |
|
fSettingDetailValues = false; |
|
} |
|
return 0; |
|
|
|
case WM_COMMAND: |
|
if( HIWORD( wParam ) == EN_CHANGE && LOWORD( wParam ) == IDC_EXPORTWIDTH ) |
|
IClampTexSizeSpinner( t, map, true ); |
|
|
|
else if( HIWORD( wParam ) == EN_CHANGE && LOWORD( wParam ) == IDC_EXPORTHEIGHT ) |
|
IClampTexSizeSpinner( t, map, false ); |
|
|
|
else if (HIWORD(wParam) == BN_CLICKED && LOWORD(wParam) == IDC_BM_CROP_IMAGE) |
|
{ |
|
IParamBlock2 *pblock = map->GetParamBlock(); |
|
PBBitmap *pbbm = pblock->GetBitmap(kBmpBitmap, t); |
|
if (pbbm) |
|
{ |
|
if (!pbbm->bm) |
|
pbbm->bm = TheManager->Load(&pbbm->bi); |
|
|
|
BMCropper *cropper = TRACKED_NEW BMCropper(pblock); |
|
|
|
pbbm->bm->Display("Specify Cropping/Placement", BMM_CN, FALSE, TRUE, cropper); |
|
} |
|
// bm->DeleteThis(); |
|
return TRUE; |
|
} |
|
else if (HIWORD(wParam) == BN_CLICKED && LOWORD(wParam) == IDC_LAYER_RELOAD) |
|
{ |
|
// TEMP |
|
IParamBlock2 *pblock = map->GetParamBlock(); |
|
PBBitmap *pbbm = pblock->GetBitmap(kBmpBitmap, t); |
|
if (pbbm) |
|
{ |
|
plLayerTex *layer = (plLayerTex*)map->GetParamBlock()->GetOwner(); |
|
|
|
layer->RefreshBitmaps(); |
|
|
|
layer->fMtlParams->MtlChanged(); |
|
layer->IChanged(); |
|
} |
|
return TRUE; |
|
} |
|
else if (LOWORD(wParam) == IDC_LAYER_NAME) |
|
{ |
|
plPlasmaMAXLayer *layer = (plPlasmaMAXLayer *)map->GetParamBlock()->GetOwner(); |
|
if (layer == nil) |
|
return FALSE; |
|
BOOL selectedNewBitmap = layer->HandleBitmapSelection(); |
|
|
|
if(selectedNewBitmap) |
|
{ |
|
IParamBlock2 *pblock = map->GetParamBlock(); |
|
//plLayerTex *layer = (plLayerTex*)map->GetParamBlock()->GetOwner(); |
|
|
|
//layer->SetBitmap(&bi); |
|
//layer->IChanged(); |
|
//BitmapInfo *bi = &layer->GetPBBitmap()->bi; |
|
|
|
bmSelectBtn = GetICustButton(GetDlgItem(hWnd,IDC_LAYER_NAME)); |
|
PBBitmap *pbbm = layer->GetPBBitmap(); |
|
bmSelectBtn->SetText(pbbm != nil ? (TCHAR*)pbbm->bi.Filename() : ""); |
|
ReleaseICustButton(bmSelectBtn); |
|
|
|
if (pbbm != nil) |
|
{ |
|
// Init values for clamping spinners to powers of 2 |
|
int width = IFloorPow2( pbbm->bi.Width() ); |
|
map->SetRange( kBmpExportWidth, 4.f, (float)width ); |
|
|
|
int height = IFloorPow2( pbbm->bi.Height() ); |
|
map->SetRange( kBmpExportHeight, 4.f, (float)height ); |
|
|
|
if( width > 512 ) |
|
{ |
|
height = (int)( 512.f * (float)( (float)height / (float)width ) ); |
|
width = 512; |
|
} |
|
else if( height > 512 ) |
|
{ |
|
width = (int)( 512.f * (float)( (float)width / (float)height ) ); |
|
height = 512; |
|
} |
|
pblock->SetValue( kBmpExportWidth, t, width ); |
|
pblock->SetValue( kBmpExportLastWidth, t, width ); |
|
pblock->SetValue( kBmpExportHeight, t, height ); |
|
pblock->SetValue( kBmpExportLastHeight, t, height ); |
|
|
|
IClampTexSizeSpinner( t, map, true ); |
|
} |
|
return TRUE; |
|
} |
|
else |
|
{ |
|
return FALSE; |
|
} |
|
} |
|
break; |
|
} |
|
|
|
return FALSE; |
|
} |
|
void DeleteThis() {}; |
|
|
|
void ISetDetailCurveNumLevels( IParamMap2 *map, TimeValue t ) |
|
{ |
|
/// Set the level count on the detail control |
|
plDetailCurveCtrl *ctrl = GET_DETAIL_CURVE_CTRL( map->GetHWnd(), IDC_DETAIL_CURVE_CTRL ); |
|
if( ctrl != NULL ) |
|
{ |
|
IParamBlock2 *pblock = map->GetParamBlock(); |
|
int w = pblock->GetInt( kBmpExportWidth, t ); |
|
int h = pblock->GetInt( kBmpExportHeight, t ); |
|
int numLevels = 0; |
|
while( w > 1 && h > 1 ) |
|
{ |
|
w >>= 1; |
|
h >>= 1; |
|
numLevels++; |
|
} |
|
ctrl->SetNumLevels( numLevels ); |
|
} |
|
} |
|
|
|
/// Clamp texture sizes to a power of 2 |
|
void IClampTexSizeSpinner( TimeValue t, IParamMap2 *map, bool clampWidth ) |
|
{ |
|
IParamBlock2 *pblock = map->GetParamBlock(); |
|
ParamID clampNew, clampOld; |
|
ParamID otherNew, otherOld; |
|
|
|
if( clampWidth ) |
|
{ |
|
clampNew = kBmpExportWidth; clampOld = kBmpExportLastWidth; |
|
otherNew = kBmpExportHeight; otherOld = kBmpExportLastHeight; |
|
} |
|
else |
|
{ |
|
clampNew = kBmpExportHeight; clampOld = kBmpExportLastHeight; |
|
otherNew = kBmpExportWidth; otherOld = kBmpExportLastWidth; |
|
} |
|
|
|
int lastVal = pblock->GetInt( clampOld, t ); |
|
int tempVal, newVal = pblock->GetInt( clampNew, t ); |
|
|
|
if( newVal < lastVal ) |
|
{ |
|
lastVal = newVal; |
|
for( tempVal = 1; tempVal <= newVal; tempVal <<= 1 ); |
|
newVal = tempVal >> 1; |
|
} |
|
else |
|
{ |
|
lastVal = newVal; |
|
for( tempVal = 1; tempVal < newVal; tempVal <<= 1 ); |
|
newVal = tempVal; |
|
} |
|
|
|
pblock->SetValue( clampNew, t, newVal ); |
|
pblock->SetValue( clampOld, t, newVal ); |
|
|
|
// And clamp aspect ratio |
|
PBBitmap *pbbm = pblock->GetBitmap( kBmpBitmap, t ); |
|
|
|
if( pbbm != NULL ) |
|
{ |
|
int realWidth = pbbm->bi.Width(); |
|
int realHeight = pbbm->bi.Height(); |
|
|
|
float aspect; |
|
if( clampWidth ) |
|
aspect = (float)realHeight / (float)realWidth; |
|
else |
|
aspect = (float)realWidth / (float)realHeight; |
|
|
|
int value = newVal; |
|
value *= aspect; |
|
|
|
if( value < 4 ) |
|
{ |
|
// Can't be below 4! |
|
value = 4; |
|
pblock->SetValue( otherNew, t, value ); |
|
pblock->SetValue( otherOld, t, value ); |
|
value = value / aspect; |
|
pblock->SetValue( clampNew, t, value ); |
|
pblock->SetValue( clampOld, t, value ); |
|
} |
|
else |
|
{ |
|
pblock->SetValue( otherNew, t, value ); |
|
pblock->SetValue( otherOld, t, value ); |
|
} |
|
} |
|
|
|
ISetDetailCurveNumLevels( map, t ); |
|
} |
|
|
|
int IFloorPow2( int value ) |
|
{ |
|
int v; |
|
|
|
|
|
for( v = 1; v <= value; v <<= 1 ); |
|
return v >> 1; |
|
} |
|
|
|
}; |
|
|
|
static BitmapDlgProc gBitmapDlgProc; |
|
|
|
|
|
// Gotta love hacks.... |
|
bool BMTexPBAccessor::IIsProcSettingDetailValues( IParamBlock2 *pb ) |
|
{ |
|
BitmapDlgProc *proc = (BitmapDlgProc *)pb->GetMap()->GetUserDlgProc(); |
|
if( proc != NULL ) |
|
return proc->fSettingDetailValues; |
|
|
|
return false; |
|
} |
|
|
|
#endif |