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.
318 lines
11 KiB
318 lines
11 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 <windowsx.h> |
|
|
|
#include "HeadSpin.h" |
|
#include "max.h" |
|
#include "resource.h" |
|
#include "hsTemplates.h" |
|
#include "hsResMgr.h" |
|
#include "plQuality.h" |
|
#include "pnMessage/plRefMsg.h" |
|
#include "plSurface/hsGMaterial.h" |
|
#include "MaxMain/plMaxNode.h" |
|
#include "MaxConvert/hsMaterialConverter.h" |
|
|
|
#include "plComponent.h" |
|
#include "plComponentReg.h" |
|
#include "plGrassComponent.h" |
|
#include "plSurface/plGrassShaderMod.h" |
|
|
|
#include "pnKeyedObject/plUoid.h" |
|
#include "pnMessage/plObjRefMsg.h" |
|
#include "MaxMain/plPluginResManager.h" |
|
|
|
void DummyCodeIncludeFuncGrassShader() |
|
{ |
|
} |
|
|
|
class GrassCompDlgProc : public ParamMap2UserDlgProc |
|
{ |
|
public: |
|
GrassCompDlgProc() {} |
|
~GrassCompDlgProc() {} |
|
|
|
protected: |
|
void ISetToWave(int wave, HWND hWnd, IParamBlock2 *pb, IParamMap2 *map) |
|
{ |
|
HWND cbox = GetDlgItem(hWnd, IDC_GRASS_WAVE); |
|
SendMessage(cbox, CB_SETCURSEL, wave, 0); |
|
pb->SetValue(ParamID(plGrassComponent::kWave), 0, wave); |
|
pb->SetValue(ParamID(plGrassComponent::kDistX), 0, pb->GetFloat(ParamID(plGrassComponent::kDistXTab), 0, wave)); |
|
pb->SetValue(ParamID(plGrassComponent::kDistY), 0, pb->GetFloat(ParamID(plGrassComponent::kDistYTab), 0, wave)); |
|
pb->SetValue(ParamID(plGrassComponent::kDistZ), 0, pb->GetFloat(ParamID(plGrassComponent::kDistZTab), 0, wave)); |
|
pb->SetValue(ParamID(plGrassComponent::kDirX), 0, pb->GetFloat(ParamID(plGrassComponent::kDirXTab), 0, wave)); |
|
pb->SetValue(ParamID(plGrassComponent::kDirY), 0, pb->GetFloat(ParamID(plGrassComponent::kDirYTab), 0, wave)); |
|
pb->SetValue(ParamID(plGrassComponent::kSpeed), 0, pb->GetFloat(ParamID(plGrassComponent::kSpeedTab), 0, wave)); |
|
map->Invalidate(); |
|
} |
|
|
|
public: |
|
BOOL DlgProc(TimeValue t, IParamMap2 *map, HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam) |
|
{ |
|
int id = LOWORD(wParam); |
|
int code = HIWORD(wParam); |
|
|
|
IParamBlock2 *pb = map->GetParamBlock(); |
|
HWND cbox = NULL; |
|
|
|
int selection; |
|
switch (msg) |
|
{ |
|
case WM_INITDIALOG: |
|
cbox = GetDlgItem(hWnd, IDC_GRASS_WAVE); |
|
SendMessage(cbox, CB_ADDSTRING, 0, (LPARAM)"1"); |
|
SendMessage(cbox, CB_ADDSTRING, 1, (LPARAM)"2"); |
|
SendMessage(cbox, CB_ADDSTRING, 2, (LPARAM)"3"); |
|
SendMessage(cbox, CB_ADDSTRING, 3, (LPARAM)"4"); |
|
|
|
selection = pb->GetInt(plGrassComponent::kWave); |
|
ISetToWave(selection, hWnd, pb, map); |
|
return TRUE; |
|
|
|
case WM_COMMAND: |
|
case CC_SPINNER_CHANGE: |
|
int wave = SendMessage(GetDlgItem(hWnd, IDC_GRASS_WAVE), CB_GETCURSEL, 0, 0); |
|
if (id == IDC_GRASS_WAVE) |
|
{ |
|
if (wave != pb->GetInt(ParamID(plGrassComponent::kWave))) |
|
ISetToWave(wave, hWnd, pb, map); |
|
} |
|
else if (id == IDC_GRASS_DIST_X || id == IDC_GRASS_DIST_X_SPIN) |
|
pb->SetValue(plGrassComponent::kDistXTab, 0, pb->GetFloat(ParamID(plGrassComponent::kDistX)), wave); |
|
else if (id == IDC_GRASS_DIST_Y || id == IDC_GRASS_DIST_Y_SPIN) |
|
pb->SetValue(plGrassComponent::kDistYTab, 0, pb->GetFloat(ParamID(plGrassComponent::kDistY)), wave); |
|
else if (id == IDC_GRASS_DIST_Z || id == IDC_GRASS_DIST_Z_SPIN) |
|
pb->SetValue(plGrassComponent::kDistZTab, 0, pb->GetFloat(ParamID(plGrassComponent::kDistZ)), wave); |
|
else if (id == IDC_GRASS_DIR_X || id == IDC_GRASS_DIR_X_SPIN) |
|
pb->SetValue(plGrassComponent::kDirXTab, 0, pb->GetFloat(ParamID(plGrassComponent::kDirX)), wave); |
|
else if (id == IDC_GRASS_DIR_Y || id == IDC_GRASS_DIR_Y_SPIN) |
|
pb->SetValue(plGrassComponent::kDirYTab, 0, pb->GetFloat(ParamID(plGrassComponent::kDirY)), wave); |
|
else if (id == IDC_GRASS_SPEED || id == IDC_GRASS_SPEED_SPIN) |
|
pb->SetValue(plGrassComponent::kSpeedTab, 0, pb->GetFloat(ParamID(plGrassComponent::kSpeed)), wave); |
|
|
|
return TRUE; |
|
} |
|
return FALSE; |
|
} |
|
void DeleteThis() {} |
|
}; |
|
static GrassCompDlgProc gGrassCompDlgProc; |
|
|
|
CLASS_DESC(plGrassComponent, gGrassDesc, "Grass", "Grass", COMP_TYPE_SHADERS, GRASS_COMPONENT_CLASS_ID) |
|
|
|
ParamBlockDesc2 gGrassBk |
|
( |
|
|
|
plComponent::kBlkComp, _T("Grass"), 0, &gGrassDesc, P_AUTO_CONSTRUCT + P_AUTO_UI, plComponent::kRefComp, |
|
|
|
//Roll out |
|
IDD_COMP_GRASS, IDS_COMP_GRASS_ROLL, 0, 0, &gGrassCompDlgProc, |
|
|
|
|
|
plGrassComponent::kWave, _T("Wave"), TYPE_INT, 0, 0, |
|
p_default, 0, |
|
end, |
|
|
|
plGrassComponent::kDistX, _T("DistX"), TYPE_FLOAT, 0, 0, |
|
p_default, 0.0, |
|
p_range, -10.0, 10.0, |
|
p_ui, TYPE_SPINNER, EDITTYPE_FLOAT, |
|
IDC_GRASS_DIST_X, IDC_GRASS_DIST_X_SPIN, 0.1, |
|
end, |
|
|
|
plGrassComponent::kDistY, _T("DistY"), TYPE_FLOAT, 0, 0, |
|
p_default, 0.0, |
|
p_range, -10.0, 10.0, |
|
p_ui, TYPE_SPINNER, EDITTYPE_FLOAT, |
|
IDC_GRASS_DIST_Y, IDC_GRASS_DIST_Y_SPIN, 0.1, |
|
end, |
|
|
|
plGrassComponent::kDistZ, _T("DistZ"), TYPE_FLOAT, 0, 0, |
|
p_default, 0.0, |
|
p_range, -10.0, 10.0, |
|
p_ui, TYPE_SPINNER, EDITTYPE_FLOAT, |
|
IDC_GRASS_DIST_Z, IDC_GRASS_DIST_Z_SPIN, 0.1, |
|
end, |
|
|
|
plGrassComponent::kDirX, _T("DirX"), TYPE_FLOAT, 0, 0, |
|
p_default, 0.0, |
|
p_range, -10.0, 10.0, |
|
p_ui, TYPE_SPINNER, EDITTYPE_FLOAT, |
|
IDC_GRASS_DIR_X, IDC_GRASS_DIR_X_SPIN, 0.1, |
|
end, |
|
|
|
plGrassComponent::kDirY, _T("DirY"), TYPE_FLOAT, 0, 0, |
|
p_default, 0.0, |
|
p_range, -10.0, 10.0, |
|
p_ui, TYPE_SPINNER, EDITTYPE_FLOAT, |
|
IDC_GRASS_DIR_Y, IDC_GRASS_DIR_Y_SPIN, 0.1, |
|
end, |
|
|
|
plGrassComponent::kSpeed, _T("Speed"), TYPE_FLOAT, 0, 0, |
|
p_default, 0.0, |
|
p_range, -10.0, 10.0, |
|
p_ui, TYPE_SPINNER, EDITTYPE_FLOAT, |
|
IDC_GRASS_SPEED, IDC_GRASS_SPEED_SPIN, 0.1, |
|
end, |
|
|
|
plGrassComponent::kDistXTab, _T("DistXTab"), TYPE_FLOAT_TAB, plGrassShaderMod::kNumWaves, 0, 0, |
|
p_default, 0.0, |
|
p_range, -10.0, 10.0, |
|
end, |
|
|
|
plGrassComponent::kDistYTab, _T("DistYTab"), TYPE_FLOAT_TAB, plGrassShaderMod::kNumWaves, 0, 0, |
|
p_default, 0.0, |
|
p_range, -10.0, 10.0, |
|
end, |
|
|
|
plGrassComponent::kDistZTab, _T("DistZTab"), TYPE_FLOAT_TAB, plGrassShaderMod::kNumWaves, 0, 0, |
|
p_default, 0.0, |
|
p_range, -10.0, 10.0, |
|
end, |
|
|
|
plGrassComponent::kDirXTab, _T("DirXTab"), TYPE_FLOAT_TAB, plGrassShaderMod::kNumWaves, 0, 0, |
|
p_default, 0.0, |
|
p_range, -10.0, 10.0, |
|
end, |
|
|
|
plGrassComponent::kDirYTab, _T("DirYTab"), TYPE_FLOAT_TAB, plGrassShaderMod::kNumWaves, 0, 0, |
|
p_default, 0.0, |
|
p_range, -10.0, 10.0, |
|
end, |
|
|
|
plGrassComponent::kSpeedTab, _T("SpeedTab"), TYPE_FLOAT_TAB, plGrassShaderMod::kNumWaves, 0, 0, |
|
p_default, 0.0, |
|
p_range, -10.0, 10.0, |
|
end, |
|
|
|
end |
|
); |
|
|
|
plGrassComponent::plGrassComponent() : fShader(nil) |
|
{ |
|
fClassDesc = &gGrassDesc; |
|
fClassDesc->MakeAutoParamBlocks(this); |
|
} |
|
|
|
hsBool plGrassComponent::PreConvert(plMaxNode *node, plErrorMsg *pErrMsg) |
|
{ |
|
fShader = TRACKED_NEW plGrassShaderMod(); |
|
|
|
plLoadMask loadMask; |
|
int qual = 1; |
|
int cap = plQuality::kPS_1_1; |
|
plLoadMask::ComputeRepMasks(1, &qual, &cap, &loadMask); |
|
plKey modKey = hsgResMgr::ResMgr()->NewKey(IGetUniqueName(node), fShader, node->GetLocation(), loadMask); |
|
|
|
int i; |
|
for (i = 0; i < plGrassShaderMod::kNumWaves; i++) |
|
{ |
|
fShader->fWaves[i].fDistX = fCompPB->GetFloat(ParamID(kDistXTab), 0, i); |
|
fShader->fWaves[i].fDistY = fCompPB->GetFloat(ParamID(kDistYTab), 0, i); |
|
fShader->fWaves[i].fDistZ = fCompPB->GetFloat(ParamID(kDistZTab), 0, i); |
|
fShader->fWaves[i].fDirX = fCompPB->GetFloat(ParamID(kDirXTab), 0, i); |
|
fShader->fWaves[i].fDirY = fCompPB->GetFloat(ParamID(kDirYTab), 0, i); |
|
fShader->fWaves[i].fSpeed = fCompPB->GetFloat(ParamID(kSpeedTab), 0, i); |
|
} |
|
|
|
// Add a ref to the shader. |
|
fShader->GetKey()->RefObject(); |
|
|
|
return true; |
|
} |
|
|
|
hsBool plGrassComponent::Convert(plMaxNode *node, plErrorMsg *pErrMsg) |
|
{ |
|
plObjRefMsg* refMsg = TRACKED_NEW plObjRefMsg(node->GetKey(), plRefMsg::kOnRequest, -1, plObjRefMsg::kModifier); |
|
hsgResMgr::ResMgr()->AddViaNotify(fShader->GetKey(), refMsg, plRefFlags::kActiveRef); |
|
|
|
hsTArray<hsGMaterial*> mats; |
|
hsMaterialConverter::Instance().CollectConvertedMaterials(hsMaterialConverter::Instance().GetBaseMtl(node), mats); |
|
hsgResMgr::ResMgr()->SendRef(mats[0]->GetKey(), TRACKED_NEW plGenRefMsg(fShader->GetKey(), plRefMsg::kOnRequest, 0, plGrassShaderMod::kRefMaterial), plRefFlags::kActiveRef); |
|
|
|
return TRUE; |
|
} |
|
|
|
hsBool plGrassComponent::DeInit(plMaxNode* node, plErrorMsg* pErrMsg) |
|
{ |
|
if( fShader ) |
|
fShader->GetKey()->UnRefObject(); |
|
fShader = nil; |
|
|
|
return true; |
|
} |
|
|
|
plGrassShaderMod* plGrassComponent::GetShader(INode* node) |
|
{ |
|
if( !node ) |
|
return nil; |
|
|
|
plComponentBase *comp = ((plMaxNodeBase*)node)->ConvertToComponent(); |
|
if( !comp ) |
|
return nil; |
|
|
|
if( comp->ClassID() != GRASS_COMPONENT_CLASS_ID ) |
|
return nil; |
|
|
|
plGrassComponent *shader = (plGrassComponent*)comp; |
|
return shader->fShader; |
|
} |
|
|
|
plGrassShaderMod* plGrassComponent::GetShaderNode(plMaxNode* node) |
|
{ |
|
if( !node ) |
|
return nil; |
|
|
|
int n = node->NumAttachedComponents(); |
|
int i; |
|
for( i = 0; i < n; i++ ) |
|
{ |
|
plComponentBase* comp = node->GetAttachedComponent(i); |
|
if( comp && (comp->ClassID() == GRASS_COMPONENT_CLASS_ID) ) |
|
{ |
|
plGrassComponent* shader = (plGrassComponent*)comp; |
|
return shader->fShader; |
|
} |
|
} |
|
return nil; |
|
}
|
|
|