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.

426 lines
9.9 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/>.
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 "HeadSpin.h"
#include "plAnimCompProc.h"
#include "../MaxMain/plMaxNode.h"
#include "plComponentBase.h"
#include "plPickNode.h"
#include "plAnimComponent.h"
#include "../../PubUtilLib/plInterp/plAnimEaseTypes.h"
plAnimCompProc::plAnimCompProc() :
fCompButtonID(0),
fCompParamID(0),
fNodeButtonID(0),
fNodeParamID(0)
{
}
BOOL plAnimCompProc::DlgProc(TimeValue t, IParamMap2* pm, HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
switch (msg)
{
case WM_INITDIALOG:
{
IParamBlock2* pb = pm->GetParamBlock();
IUpdateNodeButton(hWnd, pb);
IUpdateCompButton(hWnd, pb);
ILoadUser(hWnd, pb);
}
return TRUE;
case WM_COMMAND:
{
int cmd = HIWORD(wParam);
int resID = LOWORD(wParam);
if (cmd == BN_CLICKED && resID == fCompButtonID)
{
ICompButtonPress(hWnd, pm->GetParamBlock());
return TRUE;
}
else if (cmd == BN_CLICKED && resID == fNodeButtonID)
{
INodeButtonPress(hWnd, pm->GetParamBlock());
return TRUE;
}
else if (IUserCommand(hWnd, pm->GetParamBlock(), cmd, resID))
return TRUE;
}
break;
}
return FALSE;
}
void plAnimCompProc::ICompButtonPress(HWND hWnd, IParamBlock2* pb)
{
IPickComponent(pb);
IUpdateCompButton(hWnd, pb);
IUpdateNodeButton(hWnd, pb);
ILoadUser(hWnd, pb);
}
void plAnimCompProc::IPickNode(IParamBlock2* pb, plComponentBase* comp)
{
plPick::CompTargets(pb, fNodeParamID, comp);
}
void plAnimCompProc::INodeButtonPress(HWND hWnd, IParamBlock2* pb)
{
plComponentBase* comp = IGetComp(pb);
if (comp)
IPickNode(pb, comp);
IUpdateNodeButton(hWnd, pb);
ILoadUser(hWnd, pb);
}
void plAnimCompProc::IUpdateNodeButton(HWND hWnd, IParamBlock2* pb)
{
HWND hButton = GetDlgItem(hWnd, fNodeButtonID);
plComponentBase* comp = IGetComp(pb);
if (!comp)
{
SetWindowText(hButton, "(none)");
EnableWindow(hButton, FALSE);
return;
}
// If this is an anim grouped component you can't pick a target
if (comp->ClassID() == ANIM_GROUP_COMP_CID)
{
IClearNode(pb);
SetWindowText(hButton, "(none)");
EnableWindow(hButton, FALSE);
return;
}
EnableWindow(hButton, TRUE);
// Make sure the node is actually in the components target list
plMaxNode* node = IGetNode(pb);
if (comp->IsTarget((plMaxNodeBase*)node))
SetWindowText(hButton, node->GetName());
else
SetWindowText(hButton, "(none)");
}
void plAnimCompProc::IUpdateCompButton(HWND hWnd, IParamBlock2* pb)
{
HWND hAnim = GetDlgItem(hWnd, fCompButtonID);
plComponentBase* comp = IGetComp(pb);
if (comp)
SetWindowText(hAnim, comp->GetINode()->GetName());
else
SetWindowText(hAnim, "(none)");
}
plComponentBase* plAnimCompProc::IGetComp(IParamBlock2* pb)
{
plMaxNode* node = nil;
if (pb->GetParameterType(fCompParamID) == TYPE_REFTARG)
node = (plMaxNode*)pb->GetReferenceTarget(fCompParamID);
else
node = (plMaxNode*)pb->GetINode(fCompParamID);
if (node)
return node->ConvertToComponent();
return nil;
}
plMaxNode* plAnimCompProc::IGetNode(IParamBlock2* pb)
{
if (pb->GetParameterType(fNodeParamID) == TYPE_REFTARG)
return (plMaxNode*)pb->GetReferenceTarget(fNodeParamID);
else
return (plMaxNode*)pb->GetINode(fNodeParamID);
}
void plAnimCompProc::IClearNode(IParamBlock2* pb)
{
if (pb->GetParameterType(fNodeParamID) == TYPE_REFTARG)
pb->SetValue(fNodeParamID, 0, (ReferenceTarget*)nil);
else
pb->SetValue(fNodeParamID, 0, (INode*)nil);
}
bool plAnimCompProc::GetCompAndNode(IParamBlock2* pb, plComponentBase*& comp, plMaxNode*& node)
{
comp = IGetComp(pb);
if (comp)
{
node = IGetNode(pb);
// If it's an anim group component (don't need a node), or we have a node
// and the component is attached to it, we're ok.
if (comp->ClassID() == ANIM_GROUP_COMP_CID ||
(node && comp->IsTarget((plMaxNodeBase*)node)))
return true;
}
return false;
}
///////////////////////////////////////////////////////////////////////////////////////////
plMtlAnimProc::plMtlAnimProc() :
fMtlButtonID(0),
fMtlParamID(0),
fNodeButtonID(0),
fNodeParamID(0),
fAnimComboID(0),
fAnimParamID(0)
{
}
BOOL plMtlAnimProc::DlgProc(TimeValue t, IParamMap2* pm, HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
switch (msg)
{
case WM_INITDIALOG:
{
IParamBlock2* pb = pm->GetParamBlock();
IOnInitDlg(hWnd, pb);
IUpdateMtlButton(hWnd, pb);
}
return TRUE;
case WM_COMMAND:
{
int cmd = HIWORD(wParam);
int resID = LOWORD(wParam);
IParamBlock2* pb = pm->GetParamBlock();
if (cmd == BN_CLICKED && resID == fMtlButtonID)
{
IMtlButtonPress(hWnd, pb);
return TRUE;
}
else if (cmd == BN_CLICKED && resID == fNodeButtonID)
{
INodeButtonPress(hWnd, pb);
return TRUE;
}
else if (cmd == CBN_SELCHANGE && resID == fAnimComboID)
{
IAnimComboChanged(hWnd, pb);
return TRUE;
}
else if (IUserCommand(hWnd, pb, cmd, resID))
return TRUE;
}
break;
}
return FALSE;
}
void plMtlAnimProc::IUpdateMtlButton(HWND hWnd, IParamBlock2* pb)
{
HWND hMtl = GetDlgItem(hWnd, fMtlButtonID);
// Get the saved material
Mtl *savedMtl = IGetMtl(pb);
if (savedMtl)
SetWindowText(hMtl, savedMtl->GetName());
else
SetWindowText(hMtl, "(none)");
// Enable the node button if a material is selected
EnableWindow(GetDlgItem(hWnd, fNodeButtonID), (savedMtl != nil));
// Update the dependencies of this
IUpdateNodeButton(hWnd, pb);
}
void plMtlAnimProc::IUpdateNodeButton(HWND hWnd, IParamBlock2* pb)
{
ISetNodeButtonText(hWnd, pb);
// Update the dependencies of this
ILoadAnimCombo(hWnd, pb);
}
#include "plNotetrackAnim.h"
void plMtlAnimProc::ILoadAnimCombo(HWND hWnd, IParamBlock2* pb)
{
HWND hAnim = GetDlgItem(hWnd, fAnimComboID);
ComboBox_ResetContent(hAnim);
int sel = ComboBox_AddString(hAnim, ENTIRE_ANIMATION_NAME);
ComboBox_SetCurSel(hAnim, sel);
const char* savedName = pb->GetStr(fAnimParamID);
if (!savedName)
savedName = "";
Mtl* mtl = IGetMtl(pb);
if (mtl)
{
plNotetrackAnim anim(mtl, nil);
while (const char* animName = anim.GetNextAnimName())
{
int idx = ComboBox_AddString(hAnim, animName);
ComboBox_SetItemData(hAnim, idx, 1);
if (!strcmp(animName, savedName))
ComboBox_SetCurSel(hAnim, idx);
}
EnableWindow(hAnim, TRUE);
}
else
EnableWindow(hAnim, FALSE);
// Update the dependencies of this
ILoadUser(hWnd, pb);
}
#include "plPickMaterialMap.h"
#include "../MaxMain/plMtlCollector.h"
void plMtlAnimProc::IMtlButtonPress(HWND hWnd, IParamBlock2* pb)
{
// Let the user pick a new material
Mtl* pickedMtl = plPickMaterialMap::PickMaterial(plMtlCollector::kUsedOnly |
plMtlCollector::kPlasmaOnly);
// Save the mtl in the pb and update the interface
if (pickedMtl != nil)
{
if (pb->GetParameterType(fMtlParamID) == TYPE_REFTARG)
pb->SetValue(fMtlParamID, 0, (ReferenceTarget*)pickedMtl);
else
pb->SetValue(fMtlParamID, 0, pickedMtl);
}
// Make sure the current node has the selected material on it (clear it otherwise)
INode* node = pb->GetINode(fNodeParamID);
if (!pickedMtl || !node || node->GetMtl() != pickedMtl)
pb->SetValue(fNodeParamID, 0, (INode*)nil);
IUpdateMtlButton(hWnd, pb);
}
void plMtlAnimProc::INodeButtonPress(HWND hWnd, IParamBlock2* pb)
{
IPickNode(pb);
IUpdateNodeButton(hWnd, pb);
}
void plMtlAnimProc::IAnimComboChanged(HWND hWnd, IParamBlock2* pb)
{
HWND hCombo = GetDlgItem(hWnd, fAnimComboID);
int idx = ComboBox_GetCurSel(hCombo);
if (idx != CB_ERR)
{
if (ComboBox_GetItemData(hCombo, idx) == 0)
pb->SetValue(fAnimParamID, 0, "");
else
{
// Get the name of the animation and save it
char buf[256];
ComboBox_GetText(hCombo, buf, sizeof(buf));
pb->SetValue(fAnimParamID, 0, buf);
}
}
// Update the dependencies of this
ILoadUser(hWnd, pb);
}
Mtl* plMtlAnimProc::IGetMtl(IParamBlock2* pb)
{
if (pb->GetParameterType(fMtlParamID) == TYPE_REFTARG)
return (Mtl*)pb->GetReferenceTarget(fMtlParamID);
else
return pb->GetMtl(fMtlParamID);
}
#include "plPickNodeBase.h"
static const char* kUserTypeAll = "(All)";
class plPickAllMtlNode : public plPickMtlNode
{
protected:
void IAddUserType(HWND hList)
{
int idx = ListBox_AddString(hList, kUserTypeAll);
if (!fPB->GetINode(fNodeParamID))
ListBox_SetCurSel(hList, idx);
}
void ISetUserType(plMaxNode* node, const char* userType)
{
if (hsStrEQ(userType, kUserTypeAll))
ISetNodeValue(nil);
}
public:
plPickAllMtlNode(IParamBlock2* pb, int nodeParamID, Mtl* mtl) :
plPickMtlNode(pb, nodeParamID, mtl)
{
}
};
void plMtlAnimProc::IPickNode(IParamBlock2* pb)
{
plPickAllMtlNode pick(pb, fNodeParamID, IGetMtl(pb));
pick.DoPick();
}
void plMtlAnimProc::ISetNodeButtonText(HWND hWnd, IParamBlock2* pb)
{
HWND hNode = GetDlgItem(hWnd, fNodeButtonID);
INode* node = pb->GetINode(fNodeParamID);
if (node)
SetWindowText(hNode, node->GetName());
else
SetWindowText(hNode, kUserTypeAll);
}