/*==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 . 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 "plStaticEnvLayer.h" /////////////////////////////////////////////////////////////////////////////// //// Bitmap Accessor ////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////// class SELBMTexPBAccessor : public PBAccessor { public: void Set(PB2Value& val, ReferenceMaker* owner, ParamID id, int tabIndex, TimeValue t) { if (!owner) return; plStaticEnvLayer* layer = (plStaticEnvLayer*)owner; IParamBlock2 *pb = layer->GetParamBlockByID(plStaticEnvLayer::kBlkBitmap); switch (id) { case plStaticEnvLayer::kBmpFrontBitmap: case plStaticEnvLayer::kBmpBackBitmap: case plStaticEnvLayer::kBmpLeftBitmap: case plStaticEnvLayer::kBmpRightBitmap: case plStaticEnvLayer::kBmpTopBitmap: case plStaticEnvLayer::kBmpBottomBitmap: // Set up the enums so these would match... if (pb->GetMap()) pb->GetMap()->Invalidate( id ); // Update the bitmap saved by the layer //layer->SetBitmap( id, &val.bm->bi ); break; case plStaticEnvLayer::kBmpBaseFilename: if( pb->GetMap() ) { pb->GetMap()->Enable( plStaticEnvLayer::kBmpGenerateFaces, ( val.s == NULL || val.s[ 0 ] == 0 ) ? FALSE : TRUE ); ICustButton *bmSelectBtn = GetICustButton( GetDlgItem( pb->GetMap()->GetHWnd(), IDC_GENERATE_FACES ) ); bmSelectBtn->SetText( _T( "Generate From Node" ) ); ReleaseICustButton( bmSelectBtn ); } break; } } void Get(PB2Value& v, ReferenceMaker* owner, ParamID id, int tabIndex, TimeValue t, Interval &valid) { } }; static SELBMTexPBAccessor bmtex_accessor; /////////////////////////////////////////////////////////////////////////////// //// PickControlNode ////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////// class PickControlNode : public PickObjectProc { public: plStaticEnvLayer *fLayer; HWND fHWnd; PickControlNode() { fLayer = NULL; } BOOL Pick( INode *node ) { if( node && fLayer ) fLayer->RenderCubicMap( node ); return TRUE; } void EnterMode() { ICustButton *iBut = GetICustButton( GetDlgItem( fHWnd, IDC_GENERATE_FACES ) ); if( iBut ) { iBut->SetCheck( TRUE ); iBut->SetText( _T( "Generate From Node" ) ); } ReleaseICustButton( iBut ); } void ExitMode() { ICustButton *iBut = GetICustButton( GetDlgItem( fHWnd, IDC_GENERATE_FACES ) ); if( iBut ) { iBut->SetCheck( FALSE ); iBut->SetText( _T( "Generate From Node" ) ); } ReleaseICustButton( iBut ); } BOOL Filter( INode *node ) { return TRUE; } }; /////////////////////////////////////////////////////////////////////////////// //// ParamBlock Dialog Proc /////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////// class SELBitmapDlgProc : public ParamMap2UserDlgProc { PickControlNode fPickCallback; public: IMtlParams *fMtlParams; /// Called to update the controls of the dialog virtual void Update( TimeValue t, Interval &valid, IParamMap2 *map ) { ICustButton *bmSelectBtn; IParamBlock2 *pblock; int i; long buttons[ 6 ] = { IDC_FRONT_NAME, IDC_BACK_NAME, IDC_LEFT_NAME, IDC_RIGHT_NAME, IDC_TOP_NAME, IDC_BOTTOM_NAME }; BitmapInfo bi; ParamMap2UserDlgProc::Update( t, valid, map ); pblock = map->GetParamBlock(); for( i = plStaticEnvLayer::kBmpFrontBitmap; i <= plStaticEnvLayer::kBmpBottomBitmap; i++ ) { bmSelectBtn = GetICustButton( GetDlgItem( map->GetHWnd(), buttons[ i ] ) ); PBBitmap *pbbm = pblock->GetBitmap( i, t ); if( pbbm ) bmSelectBtn->SetText( (TCHAR *)pbbm->bi.Filename() ); else bmSelectBtn->SetText( _T( "None" ) ); ReleaseICustButton( bmSelectBtn ); } plStaticEnvLayer *layer = (plStaticEnvLayer *)map->GetParamBlock()->GetOwner(); bi.SetName( layer->GetBaseFilename( t ) ); SetDlgItemText( map->GetHWnd(), IDC_BASE_FILENAME, bi.Filename() ); map->Enable( plStaticEnvLayer::kBmpGenerateFaces, ( bi.Name() == NULL || bi.Name()[ 0 ] == 0 ) ? FALSE : TRUE ); bmSelectBtn = GetICustButton( GetDlgItem( map->GetHWnd(), IDC_GENERATE_FACES ) ); bmSelectBtn->SetText( _T( "Generate From Node" ) ); ReleaseICustButton( bmSelectBtn ); i = pblock->GetInt( plStaticEnvLayer::kBmpTextureSize, t ); pblock->SetValue( plStaticEnvLayer::kBmpLastTextureSize, t, i ); } /// Clamp texture sizes to a power of 2 void IClampTexSizeSpinner( TimeValue t, IParamMap2 *map ) { IParamBlock2 *pblock = map->GetParamBlock(); int lastVal = pblock->GetInt( plStaticEnvLayer::kBmpLastTextureSize, t ); int tempVal, newVal = pblock->GetInt( plStaticEnvLayer::kBmpTextureSize, 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( plStaticEnvLayer::kBmpTextureSize, t, newVal ); pblock->SetValue( plStaticEnvLayer::kBmpLastTextureSize, t, newVal ); } /// Main message proc BOOL DlgProc(TimeValue t, IParamMap2 *map, HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam) { static ICustButton* bmSelectBtn; long buttons[ 6 ] = { IDC_FRONT_NAME, IDC_BACK_NAME, IDC_LEFT_NAME, IDC_RIGHT_NAME, IDC_TOP_NAME, IDC_BOTTOM_NAME }; switch (msg) { case WM_INITDIALOG: break; case CC_SPINNER_CHANGE: if( LOWORD( wParam ) == IDC_TEXSIZE_SPIN ) IClampTexSizeSpinner( t, map ); break; case WM_COMMAND: if( HIWORD( wParam ) == EN_CHANGE && LOWORD( wParam ) == IDC_TEXSIZE_EDIT ) { IClampTexSizeSpinner( t, map ); } else if( HIWORD( wParam ) == BN_CLICKED && LOWORD( wParam ) == IDC_LAYER_RELOAD ) { plStaticEnvLayer *layer = (plStaticEnvLayer*)map->GetParamBlock()->GetOwner(); layer->RefreshBitmaps(); layer->IChanged(); return TRUE; } else if( LOWORD( wParam ) == IDC_FRONT_NAME ) return IDoLayerClicked( LOWORD( wParam ), plStaticEnvLayer::kFrontFace, map, t, hWnd ); else if( LOWORD( wParam ) == IDC_BACK_NAME ) return IDoLayerClicked( LOWORD( wParam ), plStaticEnvLayer::kBackFace, map, t, hWnd ); else if( LOWORD( wParam ) == IDC_LEFT_NAME ) return IDoLayerClicked( LOWORD( wParam ), plStaticEnvLayer::kLeftFace, map, t, hWnd ); else if( LOWORD( wParam ) == IDC_RIGHT_NAME ) return IDoLayerClicked( LOWORD( wParam ), plStaticEnvLayer::kRightFace, map, t, hWnd ); else if( LOWORD( wParam ) == IDC_TOP_NAME ) return IDoLayerClicked( LOWORD( wParam ), plStaticEnvLayer::kTopFace, map, t, hWnd ); else if( LOWORD( wParam ) == IDC_BOTTOM_NAME ) return IDoLayerClicked( LOWORD( wParam ), plStaticEnvLayer::kBottomFace, map, t, hWnd ); else if( LOWORD( wParam ) == IDC_LAYER_LOAD_GEN ) return IDoLoadGenerated( map, t, hWnd ); else if( LOWORD( wParam ) == IDC_GENERATE_FACES ) { plStaticEnvLayer *layer = (plStaticEnvLayer*)map->GetParamBlock()->GetOwner(); fMtlParams->EndPickMode(); fPickCallback.fHWnd = hWnd; fPickCallback.fLayer = layer; fMtlParams->SetPickMode( &fPickCallback ); break; } else if( LOWORD( wParam ) == IDC_BASE_FILENAME ) return IDoSelectBaseFilename( map, t, hWnd ); break; } return FALSE; } void DeleteThis() {}; BOOL IDoSelectBaseFilename( IParamMap2 *map, TimeValue t, HWND hWnd ) { BitmapInfo bi; plStaticEnvLayer *layer = (plStaticEnvLayer*)map->GetParamBlock()->GetOwner(); /// Select one file bi.SetName( layer->GetBaseFilename( t ) ); if( !TheManager->SelectFileOutput( &bi, GetCOREInterface()->GetMAXHWnd(), _T( "Choose the base filename for the rendered faces" ) ) ) return FALSE; /// Just store the name and set the button label as such, too SetDlgItemText( hWnd, IDC_BASE_FILENAME, bi.Filename() ); layer->SetBaseFilename( bi.Name(), t ); return TRUE; } BOOL IDoLoadGenerated( IParamMap2 *map, TimeValue t, HWND hWnd ) { BitmapInfo bi; int i; TCHAR filename[ MAX_PATH ]; TCHAR *modPoint, faces[ 6 ][ 4 ] = { "_FR", "_BK", "_LF", "_RT", "_UP", "_DN" }; /// Select one file PBBitmap *pbbm = map->GetParamBlock()->GetBitmap( plStaticEnvLayer::kBmpFrontBitmap, t ); if( pbbm != NULL ) bi.SetName( pbbm->bi.Name() ); if( !TheManager->SelectFileInput( &bi, GetCOREInterface()->GetMAXHWnd(), _T( "Select one of the generated face bitmaps" ) ) ) return FALSE; /// Copy the name over and get our mod point strcpy( filename, bi.Filename() ); modPoint = strstr( filename, "_UP" ); if( modPoint == NULL ) modPoint = strstr( filename, "_DN" ); if( modPoint == NULL ) modPoint = strstr( filename, "_LF" ); if( modPoint == NULL ) modPoint = strstr( filename, "_RT" ); if( modPoint == NULL ) modPoint = strstr( filename, "_FR" ); if( modPoint == NULL ) modPoint = strstr( filename, "_BK" ); /// Load each face for( i = 0; i < 6; i++ ) { memcpy( modPoint, faces[ i ], sizeof( TCHAR ) * 3 ); if( !ILoadFace( i, filename, map, t, hWnd ) ) return FALSE; } return TRUE; } BOOL ILoadFace( int whichFace, const TCHAR *fileName, IParamMap2 *map, TimeValue t, HWND hWnd ) { long buttons[ 6 ] = { IDC_FRONT_NAME, IDC_BACK_NAME, IDC_LEFT_NAME, IDC_RIGHT_NAME, IDC_TOP_NAME, IDC_BOTTOM_NAME }; IParamBlock2 *pblock = map->GetParamBlock(); plStaticEnvLayer *layer = (plStaticEnvLayer*)map->GetParamBlock()->GetOwner(); ICustButton *bmSelectBtn; BitmapInfo bi; if( TheManager->GetImageInfo( &bi, fileName ) != BMMRES_SUCCESS ) return FALSE; layer->SetBitmap( &bi, whichFace - plStaticEnvLayer::kFrontFace ); PBBitmap *pbbm = layer->GetPBBitmap( whichFace - plStaticEnvLayer::kFrontFace ); bmSelectBtn = GetICustButton( GetDlgItem( hWnd, buttons[ whichFace ] ) ); bmSelectBtn->SetText((TCHAR*)pbbm->bi.Filename()); ReleaseICustButton( bmSelectBtn ); return TRUE; } BOOL IDoLayerClicked( int whichBtn, int whichFace, IParamMap2 *map, TimeValue t, HWND hWnd ) { plPlasmaMAXLayer *layer = (plPlasmaMAXLayer *)map->GetParamBlock()->GetOwner(); if (layer == nil) return FALSE; BOOL selectedNewBitmap = layer->HandleBitmapSelection( whichFace - plStaticEnvLayer::kFrontFace ); if(selectedNewBitmap) { ICustButton* bmSelectBtn; PBBitmap *pbbm = layer->GetPBBitmap( whichFace - plStaticEnvLayer::kFrontFace ); bmSelectBtn = GetICustButton( GetDlgItem( hWnd, whichBtn ) ); bmSelectBtn->SetText(pbbm != nil ? (TCHAR*)pbbm->bi.Filename() : nil); ReleaseICustButton(bmSelectBtn); return TRUE; } else { return FALSE; } } }; static SELBitmapDlgProc gSELBitmapDlgProc; /////////////////////////////////////////////////////////////////////////////// //// ParamBlock Definition //////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////// static ParamBlockDesc2 gBitmapParamBlk ( plStaticEnvLayer::kBlkBitmap, _T("bitmap"), 0, GetStaticEnvLayerDesc(),//NULL, P_AUTO_CONSTRUCT + P_AUTO_UI, plStaticEnvLayer::kRefBitmap, IDD_STATIC_ENVMAP_LAYER, IDS_STATIC_ENVMAP_LAYER_TEX, 0, 0, &gSELBitmapDlgProc, // Bitmaps plStaticEnvLayer::kBmpFrontBitmap, _T("frontBitmap"), TYPE_BITMAP, P_SHORT_LABELS, 0, p_accessor, &bmtex_accessor, end, plStaticEnvLayer::kBmpBackBitmap, _T("backBitmap"), TYPE_BITMAP, P_SHORT_LABELS, 0, p_accessor, &bmtex_accessor, end, plStaticEnvLayer::kBmpLeftBitmap, _T("leftBitmap"), TYPE_BITMAP, P_SHORT_LABELS, 0, p_accessor, &bmtex_accessor, end, plStaticEnvLayer::kBmpRightBitmap, _T("rightBitmap"), TYPE_BITMAP, P_SHORT_LABELS, 0, p_accessor, &bmtex_accessor, end, plStaticEnvLayer::kBmpTopBitmap, _T("topBitmap"), TYPE_BITMAP, P_SHORT_LABELS, 0, p_accessor, &bmtex_accessor, end, plStaticEnvLayer::kBmpBottomBitmap, _T("bottomBitmap"), TYPE_BITMAP, P_SHORT_LABELS, 0, p_accessor, &bmtex_accessor, end, // Texture Color/Alpha plStaticEnvLayer::kBmpDiscardColor, _T("discardColor"), TYPE_BOOL, 0, 0, p_ui, TYPE_SINGLECHEKBOX, IDC_BLEND_NO_COLOR, end, plStaticEnvLayer::kBmpInvertColor, _T("invertColor"), TYPE_BOOL, 0, 0, p_ui, TYPE_SINGLECHEKBOX, IDC_BLEND_INV_COLOR, end, plStaticEnvLayer::kBmpDiscardAlpha, _T("discardAlpha"), TYPE_BOOL, 0, 0, p_ui, TYPE_SINGLECHEKBOX, IDC_DISCARD_ALPHA, end, plStaticEnvLayer::kBmpInvertAlpha, _T("invertAlpha"), TYPE_BOOL, 0, 0, p_ui, TYPE_SINGLECHEKBOX, IDC_BLEND_INV_ALPHA, end, // Texture Quality plStaticEnvLayer::kBmpNonCompressed, _T("nonCompressed"),TYPE_BOOL, 0, 0, p_ui, TYPE_SINGLECHEKBOX, IDC_FORCE_NONCOMPRESSED, end, plStaticEnvLayer::kBmpScaling, _T("scaling"), TYPE_INT, 0, 0, p_ui, TYPE_RADIO, 3, IDC_SCALE_ALL, IDC_SCALE_HALF, IDC_SCALE_NONE, end, // Max Only plStaticEnvLayer::kBmpMonoOutput, _T("monoOutput"), TYPE_INT, 0, 0, p_ui, TYPE_RADIO, 2, IDC_HSMAX_LAYER_RGBOUT, IDC_HSMAX_LAYER_ALPHAOUT, end, plStaticEnvLayer::kBmpRGBOutput, _T("rgbOutput"), TYPE_INT, 0, 0, p_ui, TYPE_RADIO, 2, IDC_HSMAX_LAYER_RGBOUT2, IDC_HSMAX_LAYER_ALPHAOUT2, end, // Detail plStaticEnvLayer::kBmpUseDetail, _T("useDetail"), TYPE_BOOL, 0, 0, p_ui, TYPE_SINGLECHEKBOX, IDC_USE_DETAIL, p_default, FALSE, p_enable_ctrls, 4, plStaticEnvLayer::kBmpDetailStartSize, plStaticEnvLayer::kBmpDetailStopSize, plStaticEnvLayer::kBmpDetailStartOpac, plStaticEnvLayer::kBmpDetailStopOpac, end, plStaticEnvLayer::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, end, plStaticEnvLayer::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, end, plStaticEnvLayer::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, 8, end, plStaticEnvLayer::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, end, // Face generation plStaticEnvLayer::kBmpTextureSize, _T("textureSize"), TYPE_INT, 0, 0, p_ui, TYPE_SPINNER, EDITTYPE_INT, IDC_TEXSIZE_EDIT, IDC_TEXSIZE_SPIN, SPIN_AUTOSCALE, p_range, 4, 512, p_default, 64, end, plStaticEnvLayer::kBmpBaseFilename, _T("baseFilename"), TYPE_FILENAME, 0, 0, p_default, _T( "" ), p_accessor, &bmtex_accessor, end, plStaticEnvLayer::kBmpGenerateFaces, _T("genFaces"), TYPE_INODE, 0, 0, p_ui, TYPE_PICKNODEBUTTON, IDC_GENERATE_FACES, p_prompt, IDS_SELECT_NODE, end, plStaticEnvLayer::kBmpUseMAXAtmosphere, _T("useMAXAtmos"), TYPE_BOOL, 0, 0, p_ui, TYPE_SINGLECHEKBOX, IDC_USEMAXFOG, p_default, FALSE, p_enable_ctrls, 1, plStaticEnvLayer::kBmpFarDistance, end, plStaticEnvLayer::kBmpFarDistance, _T("farDistance"), TYPE_FLOAT, 0, 0, p_ui, TYPE_SPINNER, EDITTYPE_FLOAT, IDC_FARDIST_EDIT, IDC_FARDIST_SPIN, SPIN_AUTOSCALE, p_range, 0.f, 9999999.f, p_default, 500.f, end, plStaticEnvLayer::kBmpLastTextureSize, _T("lastTextureSize"), TYPE_INT, 0, 0, end, plStaticEnvLayer::kBmpRefract, _T("refract"),TYPE_BOOL, 0, 0, p_ui, TYPE_SINGLECHEKBOX, IDC_REFRACT, end, end );