2
3
mirror of https://foundry.openuru.org/gitblit/r/CWE-ou-minkata.git synced 2025-07-14 02:27:40 -04:00

CWE Directory Reorganization

Rearrange directory structure of CWE to be loosely equivalent to
the H'uru Plasma repository.

Part 1: Movement of directories and files.
This commit is contained in:
rarified
2021-05-15 12:49:46 -06:00
parent c3f4a640a3
commit 96903e8dca
4002 changed files with 159 additions and 644 deletions

View File

@ -0,0 +1,298 @@
/*==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 "HeadSpin.h"
#include "GlobalUtility.h"
#include "hsResMgr.h"
#include "plMaxNode.h"
#include "../MaxSceneViewer/SceneSync.h"
#include "../MaxComponent/ComponentDummies.h"
#include "plActionTableMgr.h"
#include "plMaxMenu.h"
#include "../MaxComponent/plComponentBase.h"
#include "../MaxSceneViewer/plMaxFileData.h"
#include "../pfPython/cyPythonInterface.h"
#include "../MaxPlasmaMtls/Layers/plPlasmaMAXLayer.h"
#include "plMaxCFGFile.h"
#include "../pfLocalizationMgr/pfLocalizationMgr.h"
extern plActionTableMgr theActionTableMgr;
extern HINSTANCE hInstance;
/*===========================================================================*\
| Class Descriptor
\*===========================================================================*/
static PlasmaMax gPlasmaMax;
class PlasmaMaxClassDesc : public ClassDesc
{
public:
int IsPublic() { return TRUE; }
void* Create(BOOL loading) { return &gPlasmaMax; }
const TCHAR* ClassName() { return _T("PlasmaMax"); }
SClass_ID SuperClassID() { return GUP_CLASS_ID; }
Class_ID ClassID() { return PLASMA_MAX_CLASSID; }
const TCHAR* Category() { return _T(""); }
// ************************* action table
// The following 2 lines are added for action tables and menu work
int NumActionTables() { return theActionTableMgr.NumActionTables(); }
ActionTable* GetActionTable(int i) { return theActionTableMgr.GetActionTable(i); }
};
static PlasmaMaxClassDesc PlasmaMaxCD;
ClassDesc* GetGUPDesc() { return &PlasmaMaxCD; }
//////////////////////////////////////////
// This function is from the console. This dummy version is here so that plNetLinkingMgr will build.
plKey FindSceneObjectByName(const char* name, const char* ageName, char* statusStr, bool subString)
{
return nil;
}
/*===========================================================================*\
| Global Utility interface (start/stop/control)
\*===========================================================================*/
PlasmaMax::PlasmaMax()
{
}
void DoAllRecur(PMaxNodeFunc p, plMaxNode *node)
{
(node->*p)(nil, nil);
for (int i = 0; i < node->NumberOfChildren(); i++)
{
plMaxNode *child = (plMaxNode*)node->GetChildNode(i);
DoAllRecur(p, child);
}
}
//#include "../MaxComponent/plComponentBase.h"
#include "../MaxExport/plExportErrorMsg.h"
#include "../MaxExport/plExportDlg.h"
static void NotifyProc(void *param, NotifyInfo *info)
{
if (info->intcode == NOTIFY_FILE_POST_OPEN)
{
plMaxNode *pNode = (plMaxNode*)GetCOREInterface()->GetRootNode();
DoAllRecur(plMaxNode::ClearData, pNode);
}
else if (info->intcode == NOTIFY_SYSTEM_STARTUP)
{
int type;
float scale;
GetMasterUnitInfo(&type, &scale);
if (type != UNITS_FEET || scale != 1.f)
{
hsMessageBoxWithOwner(GetCOREInterface()->GetMAXHWnd(),
"Please set your system units to 1 unit = 1 foot.\n\n"
"Customize -> Units Setup... -> System Unit Setup",
"Plasma Units Error", hsMessageBoxNormal);
}
plExportDlg::Instance().StartAutoExport();
}
}
// Activate and Stay Resident
// The GUPRESULT_KEEP tells MAX that we want to remain loaded in the system
// Check the SDK Help File for other returns, to change the behavior
DWORD PlasmaMax::Start()
{
// Make sure component code isn't thrown away by the linker
DummyCodeIncludeFunc(); //Anim Comps
DummyCodeIncludeFuncActive(); //Activators
DummyCodeIncludeFuncResponder(); //Responders
DummyCodeIncludeFuncAudio(); //Audio Files
DummyCodeIncludeAvatarFunc(); //Avatar Comp
DummyCodeIncludeFuncTypes(); //Type (Portal, StartPoint, etc..)
DummyCodeIncludeFuncMisc(); //Misc (Room, PageInfo, Interesting, etc..)
DummyCodeIncludeFuncPhys(); //Phys Comps
DummyCodeIncludeFuncParticles(); //Particle Comps
DummyCodeIncludeFuncSmooth(); //Smooth Comp
DummyCodeIncludeFuncSeekPoint(); //Avatar SeekPoint Comp
DummyCodeIncludeFuncClickable(); //Clickable Comp
DummyCodeIncludeFuncSingleSht(); //OneShot Comp
DummyCodeIncludeFuncAGComp();
DummyCodeIncludeFuncClickDrag(); //Click-Draggable comp
DummyCodeIncludeFuncInventStuff(); //Inventory Object comp
DummyCodeIncludeFuncVolumeGadget(); // inside/enter/exit phys volume activator
// DummyCodeIncludeFuncActivatorGadget(); // activator activator
DummyCodeIncludeFuncImpactGadget(); // collision activator
DummyCodeIncludeFuncSoftVolume(); // Soft Volumes
DummyCodeIncludeFuncPhysConst(); // Phys Constraints
DummyCodeIncludeFuncCameras(); // new camera code
DummyCodeIncludePythonFileFunc();
DummyCodeIncludeFuncDistrib(); // Geometry distribution functions
DummyCodeIncludeFuncExcludeRegion();
DummyCodeIncludeFuncCluster(); // Geometry clustering functions
DummyCodeIncludeFuncGUI(); // User Interface components
DummyCodeIncludeFuncIgnore(); // Things to ignore completely or partially
DummyCodeIncludeFuncBlow(); // Procedural wind modifier
DummyCodeIncludeFuncWater(); // All things wet.
DummyCodeIncludeFuncLightMap(); // LightMap
DummyCodeIncludeFuncXImposter(); // Like a billboard, but exier.
DummyCodeIncludeFuncRepComp(); // Different representations
DummyCodeIncludeFuncLineFollow(); // Things that follow a line
DummyCodeIncludeFuncMorph(); // Like putty in my hands
DummyCodeIncludeFuncLODFade(); // Alpha blending lod transition
DummyCodeIncludeFuncBehaviors(); // Av Behaviors, like Sitting
DummyCodeIncludeFuncNavigablesRegion();
DummyCodeIncludeFuncTemplate();
DummyCodeIncludeFuncClothing();
DummyCodeIncludeFuncMultistageBeh();
DummyCodeIncludeFuncAnimDetector();
DummyCodeIncludeFuncShadow(); // Components controlling shadow generation.
DummyCodeIncludeFuncFootstepSound();
DummyCodeIncludeFuncFootPrint(); // dynamic decals
DummyCodeIncludFuncNPCSpawn();
DummyCodeIncludeFuncClimbTrigger();
DummyCodeIncludeFuncObjectFlocker();
DummyCodeIncludeFuncGrassShader();
// Register the SceneViewer with Max
SceneSync::Instance();
plComponentShow::Init();
plCreateMenu();
RegisterNotification(NotifyProc, 0, NOTIFY_FILE_POST_OPEN);
RegisterNotification(NotifyProc, 0, NOTIFY_SYSTEM_STARTUP);
InitMaxFileData();
// Setup the localization mgr
std::string clientPath = plMaxConfig::GetClientPath(false, true);
clientPath += "dat";
pfLocalizationMgr::Initialize(clientPath);
return GUPRESULT_KEEP;
}
void PlasmaMax::Stop()
{
UnRegisterNotification(NotifyProc, 0, NOTIFY_FILE_POST_OPEN);
pfLocalizationMgr::Shutdown();
PythonInterface::WeAreInShutdown();
PythonInterface::finiPython();
hsgResMgr::Shutdown();
}
#include "plMtlCollector.h"
#include "../../AssetMan/PublicInterface/AssManBaseTypes.h"
void TextureSet(Texmap* texmap, int iBmp, UInt64 assetId)
{
plPlasmaMAXLayer* layer = plPlasmaMAXLayer::GetPlasmaMAXLayer(texmap);
if (layer)
{
int numBitmaps = layer->GetNumBitmaps();
if (iBmp < numBitmaps)
layer->SetBitmapAssetId(jvUniqueId(assetId), iBmp);
}
}
DWORD PlasmaMax::Control(DWORD parameter)
{
if (parameter == kGetTextures)
{
TexSet texmaps;
plMtlCollector::GetMtls(nil, &texmaps);
std::vector<TexInfo> texInfo;
TexSet::iterator texIt = texmaps.begin();
for (; texIt != texmaps.end(); texIt++)
{
Texmap* texmap = (*texIt);
plPlasmaMAXLayer* layer = plPlasmaMAXLayer::GetPlasmaMAXLayer(texmap);
if (layer)
{
int numBitmaps = layer->GetNumBitmaps();
for (int iBmp = 0; iBmp < numBitmaps; iBmp++)
{
// UPDATE: If someone merges in a material from another AssetMan
// controled scene the texture ID will already be set, when it
// shouldn't be. Because of that, we redo all the texture ID's
// every time.
// - Colin
// if (assetId.IsEmpty())
{
char fileName[MAX_PATH];
if (layer->GetBitmapFileName(fileName, sizeof(fileName), iBmp))
{
int texIdx = texInfo.size();
texInfo.resize(texIdx+1);
texInfo[texIdx].texmap = texmap;
texInfo[texIdx].iBmp = iBmp;
texInfo[texIdx].texName = fileName;
}
}
}
}
}
jvArray<TexInfo>* textures = TRACKED_NEW jvArray<TexInfo>(texInfo.size());
for (int i = 0; i < texInfo.size(); i++)
(*textures)[i] = texInfo[i];
return DWORD(textures);
}
else if (parameter == kGetTextureSetFunc)
{
return DWORD(&TextureSet);
}
return 0;
}

View File

@ -0,0 +1,86 @@
/*==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==*/
#ifndef PLASMA_MAX_H
#define PLASMA_MAX_H
class BitmapManager;
class Texmap;
#include "max.h"
#include "guplib.h"
#include "hsTypes.h"
#include <string>
#define PLASMA_MAX_CLASSID Class_ID(0x3d494269, 0x103c5c5f)
extern ClassDesc* GetGUPDesc();
typedef void (*TextureSetFunc)(Texmap* texmap, int iBmp, UInt64 assetId);
struct TexInfo
{
Texmap* texmap;
int iBmp;
std::string texName;
};
class PlasmaMax : public GUP
{
public:
PlasmaMax();
~PlasmaMax() {}
// GUP Methods
DWORD Start();
void Stop();
enum ControlVals
{
// Pass this to Control and get back a jvArray<TexInfo>* of all the textures in the scene
kGetTextures,
// Pass this to Control and get back a pointer to the TextureSetFunc
kGetTextureSetFunc,
};
DWORD Control(DWORD parameter);
};
#endif

View File

@ -0,0 +1,114 @@
/*==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 "max.h"
#include "MaxAllocDll.h"
typedef void* (*MAXMALLOC) (size_t size);
typedef void (*MAXFREE) (void *memblock);
static MAXMALLOC maxMalloc = NULL;
static MAXFREE maxFree = NULL;
static HINSTANCE maxAllocDll = NULL;
void LoadAllocDll()
{
if (!maxAllocDll)
{
// Search through all the Max plugin paths for MaxAlloc.dll
Interface *ip = GetCOREInterface();
for (int i = 0; i < ip->GetPlugInEntryCount(); i++)
{
const char *dir = ip->GetPlugInDir(i);
char path[MAX_PATH];
sprintf(path, "%sMaxAlloc.dll", dir);
maxAllocDll = LoadLibrary(path);
if (maxAllocDll)
return;
}
maxAllocDll = LoadLibrary("MaxAlloc.dll");
if (!maxAllocDll)
{
::MessageBox(NULL, "Couldn't load MaxAlloc.dll", "Error", MB_OK);
exit(0);
}
}
}
void *plMaxMalloc(size_t size)
{
if (!maxMalloc)
{
LoadAllocDll();
maxMalloc = (MAXMALLOC)GetProcAddress(maxAllocDll, "MaxMalloc");
if (!maxMalloc)
{
::MessageBox(NULL, "Couldn't find MaxMalloc in MaxAlloc.dll", "Error", MB_OK);
exit(0);
}
}
return maxMalloc(size);
}
void plMaxFree(void *memblock)
{
if (!maxFree)
{
LoadAllocDll();
maxFree = (MAXFREE)GetProcAddress(maxAllocDll, "MaxFree");
if (!maxFree)
{
::MessageBox(NULL, "Couldn't find MaxFree in MaxAlloc.dll", "Error", MB_OK);
exit(0);
}
}
maxFree(memblock);
}

View File

@ -0,0 +1,49 @@
/*==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==*/
//
// The functions allocate and free memory using functions contained in another
// Dll. This gives us the advantage of compiling against whatever runtime
// library we want and still being able to allocate memory and give it to Max
// to free.
//
void *plMaxMalloc(size_t size);
void plMaxFree(void *memblock);

View File

@ -0,0 +1,538 @@
// Microsoft Visual C++ generated resource script.
//
#include "resource.h"
#define APSTUDIO_READONLY_SYMBOLS
/////////////////////////////////////////////////////////////////////////////
//
// Generated from the TEXTINCLUDE 2 resource.
//
#include "afxres.h"
/////////////////////////////////////////////////////////////////////////////
#undef APSTUDIO_READONLY_SYMBOLS
/////////////////////////////////////////////////////////////////////////////
// English (U.S.) resources
#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU)
#ifdef _WIN32
LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
#pragma code_page(1252)
#endif //_WIN32
#ifdef APSTUDIO_INVOKED
/////////////////////////////////////////////////////////////////////////////
//
// TEXTINCLUDE
//
1 TEXTINCLUDE
BEGIN
"resource.h\0"
END
2 TEXTINCLUDE
BEGIN
"#include ""afxres.h""\r\n"
"\0"
END
3 TEXTINCLUDE
BEGIN
"#include ""../MaxComponent/plComponent.rc""\r\n"
"#include ""../MaxPlasmaMtls/MaxPlasmaMtls.rc""\r\n"
"\0"
END
#endif // APSTUDIO_INVOKED
/////////////////////////////////////////////////////////////////////////////
//
// Dialog
//
IDD_COMP_PANEL DIALOGEX 0, 0, 108, 100
STYLE DS_SETFONT | WS_CHILD | WS_VISIBLE
FONT 8, "MS Sans Serif", 0, 0, 0x1
BEGIN
CONTROL "List1",IDC_COMPLIST,"SysListView32",LVS_REPORT |
LVS_SINGLESEL | LVS_SHOWSELALWAYS | LVS_SORTASCENDING |
LVS_EDITLABELS | LVS_NOCOLUMNHEADER | WS_BORDER |
WS_TABSTOP,4,4,100,81,WS_EX_CLIENTEDGE
CTEXT "",IDC_NUM_TARGS,4,88,19,9,SS_SUNKEN
PUSHBUTTON "<",IDC_BACK,25,87,12,11,BS_LEFT | BS_BOTTOM |
WS_DISABLED
PUSHBUTTON ">",IDC_FORWARD,39,87,12,11,BS_CENTER | BS_BOTTOM |
WS_DISABLED
PUSHBUTTON "Ref'd By...",IDC_REF_BY_BUTTON,58,87,45,11
END
IDD_SCENEVIEWER DIALOG 0, 0, 222, 146
STYLE DS_SETFONT | DS_MODALFRAME | DS_CENTER | WS_MINIMIZEBOX | WS_POPUP |
WS_VISIBLE | WS_CAPTION | WS_SYSMENU
CAPTION "SceneViewer Options"
FONT 8, "MS Sans Serif"
BEGIN
CONTROL "Update every",IDC_UPDATE,"Button",BS_AUTOCHECKBOX |
WS_TABSTOP,7,103,55,10
CONTROL "",IDC_EDIT,"CustEdit",WS_TABSTOP,65,103,18,10
CONTROL "",IDC_SPINNER,"SpinnerControl",WS_TABSTOP,83,103,7,10
PUSHBUTTON "Reshade",IDC_RESHADE,7,117,46,13,WS_DISABLED
PUSHBUTTON "Browse...",IDC_DIR,173,23,42,12
LTEXT "seconds",IDC_STATIC,92,103,28,11
LTEXT "Client Path:",IDC_STATIC,7,13,37,8
CONTROL "Custom1",IDC_CLIENT_PATH,"CustEdit",WS_TABSTOP,7,23,163,
12
CONTROL "Reuse data from previous run",IDC_REUSE_DATA,"Button",
BS_AUTOCHECKBOX | WS_TABSTOP,7,55,109,10
GROUPBOX "Update",IDC_STATIC,1,91,218,51
GROUPBOX "Setup",IDC_STATIC,1,2,218,84
COMBOBOX IDC_EXE,66,39,50,54,CBS_DROPDOWNLIST | WS_VSCROLL |
WS_TABSTOP
PUSHBUTTON "Start",IDC_START,87,68,46,13
LTEXT "Client Executable:",IDC_STATIC,7,41,58,8
END
IDD_GET_LOCATION DIALOG 0, 0, 112, 125
STYLE DS_SETFONT | DS_MODALFRAME | DS_CENTER | WS_POPUP | WS_CAPTION |
WS_SYSMENU
CAPTION "Set A Location"
FONT 8, "MS Sans Serif"
BEGIN
DEFPUSHBUTTON "OK",IDOK,4,107,50,14
PUSHBUTTON "Cancel",IDCANCEL,57,107,50,14
LISTBOX IDC_LIST_LOC,4,48,103,43,LBS_SORT | WS_VSCROLL |
WS_TABSTOP
LTEXT "a\na\na\na\na",IDC_PROMPT,4,5,103,41
CONTROL "Use selection for any other objects without a location",
IDC_CHECK_DEFAULT,"Button",BS_AUTOCHECKBOX |
BS_MULTILINE | WS_TABSTOP,7,85,97,20
END
IDD_COMP_MAIN DIALOGEX 0, 0, 111, 95
STYLE DS_SETFONT | DS_CENTER | WS_MINIMIZEBOX | WS_POPUP | WS_CLIPCHILDREN |
WS_CAPTION | WS_SYSMENU | WS_THICKFRAME
CAPTION "Component Manager"
MENU IDR_COMP_MENU
FONT 8, "MS Sans Serif", 0, 0, 0x1
BEGIN
CONTROL "Tree1",IDC_TREE,"SysTreeView32",TVS_HASBUTTONS |
TVS_HASLINES | TVS_LINESATROOT | TVS_EDITLABELS |
TVS_SHOWSELALWAYS | WS_BORDER | WS_TABSTOP,4,3,102,32,
WS_EX_CLIENTEDGE
PUSHBUTTON "Attach to Selected Object(s)",IDC_ATTACH,4,37,102,14,
WS_DISABLED
LTEXT "Component Comments:",IDC_COMMENT_TEXT,4,53,74,8
EDITTEXT IDC_COMMENTS,4,63,102,28,ES_MULTILINE | ES_AUTOVSCROLL |
ES_READONLY | ES_WANTRETURN | WS_VSCROLL
END
IDD_AGE_DESC DIALOGEX 0, 0, 316, 283
STYLE DS_SETFONT | DS_MODALFRAME | DS_CENTER | WS_POPUP | WS_CAPTION |
WS_SYSMENU
CAPTION "Age Description Manager"
FONT 8, "MS Sans Serif", 0, 0, 0x1
BEGIN
PUSHBUTTON "Create New...",IDC_AGE_NEW,12,238,51,13
PUSHBUTTON "New...",IDC_PAGE_NEW,269,38,32,13
CONTROL "DateTimePicker1",IDC_DATE,"SysDateTimePick32",
DTS_RIGHTALIGN | DTS_UPDOWN | WS_TABSTOP,170,161,53,12
CONTROL "DateTimePicker2",IDC_TIME,"SysDateTimePick32",
DTS_RIGHTALIGN | DTS_UPDOWN | WS_TABSTOP | 0x8,226,161,
56,12
CONTROL "",IDC_DAYLEN_EDIT,"CustEdit",WS_TABSTOP,226,179,18,10
CONTROL "",IDC_DAYLEN_SPINNER,"SpinnerControl",WS_TABSTOP,244,
179,7,10
DEFPUSHBUTTON "Close",IDOK,120,262,50,14
LTEXT "Start Date and Time (in Current Timezone):",IDC_STATIC,
158,152,137,8
LTEXT "Day Length:",IDC_STATIC,184,179,40,8
LTEXT "hours",IDC_STATIC,254,179,18,8
LTEXT "Pages:",IDC_STATIC,153,38,23,8
GROUPBOX "Age Description",IDC_STATIC,150,140,153,67
LTEXT "Max Capacity:",IDC_STATIC,178,193,46,8
CONTROL "",IDC_CAP_EDIT,"CustEdit",WS_TABSTOP,226,192,18,10
CONTROL "",IDC_CAP_SPINNER,"SpinnerControl",WS_TABSTOP,244,192,7,
10
LTEXT "players",IDC_STATIC,254,193,23,8
PUSHBUTTON "Delete",IDC_PAGE_DEL,269,53,32,13
LISTBOX IDC_PAGE_LIST,179,38,88,68,LBS_SORT | WS_VSCROLL |
WS_TABSTOP
CONTROL "",IDC_SEQPREFIX_EDIT,"CustEdit",WS_DISABLED |
WS_TABSTOP,214,221,18,10
CONTROL "",IDC_SEQPREFIX_SPIN,"SpinnerControl",WS_DISABLED |
WS_TABSTOP,232,221,7,10
LTEXT "Sequence Prefix:",IDC_STATIC,156,222,55,8
GROUPBOX "Ages",IDC_AGELIST_STATIC,7,36,132,221
GROUPBOX "Description for Cleft",IDC_AGEDESC,145,7,164,250
GROUPBOX "Registry Settings",IDC_STATIC,150,210,153,41
CONTROL "Reserved/Global",IDC_RSVDCHECK,"Button",BS_AUTOCHECKBOX |
WS_DISABLED | WS_TABSTOP,157,235,70,10
PUSHBUTTON "Edit...",IDC_EDITREG,246,226,50,14
CONTROL "Tree1",IDC_AGE_LIST,"SysTreeView32",TVS_HASBUTTONS |
TVS_HASLINES | TVS_LINESATROOT | TVS_DISABLEDRAGDROP |
TVS_SHOWSELALWAYS | TVS_NOTOOLTIPS | TVS_FULLROWSELECT |
WS_TABSTOP,11,48,124,185,WS_EX_CLIENTEDGE
PUSHBUTTON "Check Out",IDC_AGE_CHECKOUT,150,18,50,14,WS_DISABLED
PUSHBUTTON "Check In",IDC_AGE_CHECKIN,202,18,50,14,WS_DISABLED
PUSHBUTTON "Undo Chk Out",IDC_AGE_UNDOCHECKOUT,254,18,50,14,
WS_DISABLED
CONTROL "Don't load with age",IDC_ADM_DONTLOAD,"Button",
BS_AUTOCHECKBOX | WS_TABSTOP,181,100,77,10
CONTROL "Load if matching age SDL var",IDC_ADM_LOADSDL,"Button",
BS_AUTOCHECKBOX | WS_TABSTOP,181,111,110,10
GROUPBOX "Branch",IDC_STATIC,7,7,132,29
COMBOBOX IDC_BRANCHCOMBO,12,17,122,110,CBS_DROPDOWNLIST |
WS_VSCROLL | WS_TABSTOP
CONTROL "Local only",IDC_ADM_LOCAL_ONLY,"Button",BS_AUTOCHECKBOX |
WS_TABSTOP,181,120,48,10
CONTROL "Volatile",IDC_ADM_VOLATILE,"Button",BS_AUTOCHECKBOX |
WS_TABSTOP,181,129,39,10
END
IDD_AGE_NAME DIALOG 0, 0, 112, 39
STYLE DS_SETFONT | DS_MODALFRAME | DS_CENTER | WS_POPUP | WS_CAPTION |
WS_SYSMENU
FONT 8, "MS Sans Serif"
BEGIN
EDITTEXT IDC_AGE_NAME,4,6,103,13,ES_AUTOHSCROLL
DEFPUSHBUTTON "Create",IDOK,4,22,50,14
PUSHBUTTON "Cancel",IDCANCEL,57,22,50,14
END
IDD_UTILS_RES DIALOG 0, 0, 189, 197
STYLE DS_SETFONT | DS_MODALFRAME | DS_CENTER | WS_POPUP | WS_VISIBLE |
WS_CAPTION | WS_SYSMENU
CAPTION "Resource Browser"
FONT 8, "MS Sans Serif"
BEGIN
DEFPUSHBUTTON "OK",IDOK,42,180,50,14
CONTROL "Tree1",IDC_REG_TREE,"SysTreeView32",TVS_HASBUTTONS |
TVS_HASLINES | TVS_LINESATROOT | WS_BORDER | WS_TABSTOP,
5,4,179,172
PUSHBUTTON "Refresh",IDC_REFRESH,97,180,50,14
END
IDD_UTILS DIALOG 0, 0, 108, 27
STYLE DS_SETFONT | WS_CHILD | WS_VISIBLE
FONT 8, "MS Sans Serif"
BEGIN
PUSHBUTTON "Resource Browser...",IDC_RES,16,6,76,14
END
IDD_FIND_TEXTURE DIALOG 0, 0, 249, 215
STYLE DS_SETFONT | DS_MODALFRAME | DS_CENTER | WS_POPUP | WS_CAPTION |
WS_SYSMENU
CAPTION "Texture Find and Replace"
FONT 8, "MS Sans Serif"
BEGIN
PUSHBUTTON "Close",IDCANCEL,100,199,50,14
EDITTEXT IDC_FIND_EDIT,61,3,87,12,ES_AUTOHSCROLL
DEFPUSHBUTTON "Update Results",IDC_UPDATE_BUTTON,152,3,58,12
LTEXT "Texture Name:",IDC_STATIC,7,5,48,8
CONTROL "List2",IDC_TEXTURE_LIST,"SysListView32",LVS_REPORT |
LVS_SORTASCENDING | WS_BORDER | WS_TABSTOP,7,18,235,139
PUSHBUTTON "Replace All...",IDC_REPLACE_ALL_BUTTON,152,162,58,12,
WS_DISABLED
LTEXT "Replace With:",IDC_STATIC,7,164,46,8
PUSHBUTTON "(none)",IDC_REPLACE_BUTTON,61,162,87,12,WS_DISABLED
LTEXT "Set Export Size:",IDC_STATIC,7,179,51,8
PUSHBUTTON "Set All...",IDC_SET_ALL_BUTTON,152,178,58,12,
WS_DISABLED
COMBOBOX IDC_SIZE_COMBO,61,177,87,173,CBS_DROPDOWNLIST |
WS_DISABLED | WS_VSCROLL | WS_TABSTOP
END
IDD_EXPORT DIALOG 0, 0, 222, 185
STYLE DS_SETFONT | DS_MODALFRAME | WS_POPUP | WS_VISIBLE | WS_CAPTION |
WS_SYSMENU
CAPTION "Plasma Export"
FONT 8, "MS Sans Serif"
BEGIN
EDITTEXT IDC_CLIENT_PATH,8,22,159,12,ES_AUTOHSCROLL | ES_READONLY
PUSHBUTTON "Browse...",IDC_DIR,170,22,42,12
CONTROL "Preshade Geometry",IDC_PRESHADE_CHECK,"Button",
BS_AUTOCHECKBOX | WS_TABSTOP,8,40,78,10
CONTROL "Physicals Only",IDC_PHYSICAL_CHECK,"Button",
BS_AUTOCHECKBOX | WS_TABSTOP,102,40,61,10
CONTROL "Current File",IDC_RADIO_FILE,"Button",
BS_AUTORADIOBUTTON | WS_GROUP,7,85,51,10
CONTROL "Directory",IDC_RADIO_DIR,"Button",BS_AUTORADIOBUTTON,7,
114,44,10
COMBOBOX IDC_PAGE_COMBO,43,97,78,83,CBS_DROPDOWNLIST | WS_VSCROLL |
WS_GROUP | WS_TABSTOP
EDITTEXT IDC_EXPORT_PATH,20,127,147,12,ES_AUTOHSCROLL |
ES_READONLY
PUSHBUTTON "Browse...",IDC_BROWSE_EXPORT,170,127,42,12
LTEXT "Last Export Took:",IDC_LAST_EXPORT,6,151,209,11,
SS_SUNKEN
DEFPUSHBUTTON "Export",IDC_EXPORT,59,167,50,14
PUSHBUTTON "Cancel",IDCANCEL,113,167,50,14
LTEXT "Client Path:",IDC_STATIC,8,12,37,8
GROUPBOX "Options",IDC_STATIC,2,2,217,66
LTEXT "Page:",IDC_STATIC,21,99,20,8
GROUPBOX "Export",IDC_STATIC,2,71,217,75
CONTROL "Regenerate Lightmaps",IDC_LIGHTMAP_CHECK,"Button",
BS_AUTOCHECKBOX | WS_TABSTOP,8,52,87,10
END
IDD_REF_BY DIALOG 0, 0, 174, 162
STYLE DS_SETFONT | DS_MODALFRAME | DS_CENTER | WS_POPUP | WS_VISIBLE |
WS_CAPTION
CAPTION "Referenced By"
FONT 8, "MS Sans Serif"
BEGIN
DEFPUSHBUTTON "Close",IDC_CLOSE,61,144,50,14
LISTBOX IDC_REF_LIST,4,21,165,118,LBS_SORT |
LBS_NOINTEGRALHEIGHT | WS_VSCROLL | WS_TABSTOP
LTEXT "Double-click on a component name to select the nodes it is attached to.",
IDC_STATIC,4,2,155,16
END
IDD_AGE_SEQNUM DIALOG 0, 0, 314, 226
STYLE DS_SETFONT | DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU
CAPTION "Assigning a New Sequence Number"
FONT 8, "MS Sans Serif"
BEGIN
CTEXT "Age title goes here",IDC_AGEMSG,7,7,296,13
LTEXT "ADM Manager Message Goes here",IDC_ADMMSG,7,84,289,34
DEFPUSHBUTTON "Yes, choose a new sequence number for a NORMAL age",
IDYES,43,129,221,16
PUSHBUTTON "Yes, choose a new sequence number for a GLOBAL age",
IDNO,43,151,221,16
PUSHBUTTON "No, do not choose a sequence number; I'll take my chances",
IDCANCEL,43,175,221,16
LTEXT "Info Message Goes Here",IDC_INFOMSG,7,22,296,44
END
IDD_AGE_CHECKIN DIALOG 0, 0, 186, 95
STYLE DS_SETFONT | DS_MODALFRAME | DS_CENTER | WS_POPUP | WS_CAPTION |
WS_SYSMENU
CAPTION "Age is checked out..."
FONT 8, "MS Sans Serif"
BEGIN
PUSHBUTTON "Save changes and check in",IDYES,24,33,138,14
PUSHBUTTON "Undo check out and discard changes",IDNO,24,53,138,14
LTEXT "The current age file you are switching away from is checked out. What do you wish to do?",
IDC_STATIC,7,9,172,18
DEFPUSHBUTTON "Cancel",IDCANCEL,24,71,138,14
END
IDD_AGE_SAVEYESNO DIALOG 0, 0, 186, 61
STYLE DS_SETFONT | DS_MODALFRAME | DS_CENTER | WS_POPUP | WS_CAPTION |
WS_SYSMENU
CAPTION "Local age has changed..."
FONT 8, "MS Sans Serif"
BEGIN
PUSHBUTTON "Save",IDYES,16,36,46,14
PUSHBUTTON "Discard",IDNO,70,36,46,14
LTEXT "The current age file you are switching away from has been altered. Do you wish to keep your changes?",
IDC_STATIC,7,9,172,18
DEFPUSHBUTTON "Cancel",IDCANCEL,123,36,46,14
END
/////////////////////////////////////////////////////////////////////////////
//
// DESIGNINFO
//
#ifdef APSTUDIO_INVOKED
GUIDELINES DESIGNINFO
BEGIN
IDD_COMP_PANEL, DIALOG
BEGIN
LEFTMARGIN, 7
RIGHTMARGIN, 101
TOPMARGIN, 7
BOTTOMMARGIN, 93
END
IDD_SCENEVIEWER, DIALOG
BEGIN
LEFTMARGIN, 7
RIGHTMARGIN, 215
TOPMARGIN, 7
BOTTOMMARGIN, 139
END
IDD_GET_LOCATION, DIALOG
BEGIN
LEFTMARGIN, 7
RIGHTMARGIN, 105
TOPMARGIN, 7
BOTTOMMARGIN, 118
END
IDD_COMP_MAIN, DIALOG
BEGIN
LEFTMARGIN, 7
RIGHTMARGIN, 104
TOPMARGIN, 7
BOTTOMMARGIN, 88
END
IDD_AGE_DESC, DIALOG
BEGIN
LEFTMARGIN, 7
RIGHTMARGIN, 309
TOPMARGIN, 7
BOTTOMMARGIN, 276
END
IDD_AGE_NAME, DIALOG
BEGIN
LEFTMARGIN, 7
RIGHTMARGIN, 105
TOPMARGIN, 7
BOTTOMMARGIN, 32
END
IDD_UTILS_RES, DIALOG
BEGIN
LEFTMARGIN, 7
RIGHTMARGIN, 182
TOPMARGIN, 7
BOTTOMMARGIN, 190
END
IDD_UTILS, DIALOG
BEGIN
LEFTMARGIN, 7
RIGHTMARGIN, 101
TOPMARGIN, 7
BOTTOMMARGIN, 20
END
IDD_FIND_TEXTURE, DIALOG
BEGIN
LEFTMARGIN, 7
RIGHTMARGIN, 242
TOPMARGIN, 7
BOTTOMMARGIN, 208
END
IDD_EXPORT, DIALOG
BEGIN
LEFTMARGIN, 7
RIGHTMARGIN, 215
TOPMARGIN, 7
BOTTOMMARGIN, 178
END
IDD_REF_BY, DIALOG
BEGIN
LEFTMARGIN, 7
RIGHTMARGIN, 167
TOPMARGIN, 7
BOTTOMMARGIN, 155
END
IDD_AGE_SEQNUM, DIALOG
BEGIN
LEFTMARGIN, 7
RIGHTMARGIN, 307
TOPMARGIN, 7
BOTTOMMARGIN, 219
END
IDD_AGE_CHECKIN, DIALOG
BEGIN
LEFTMARGIN, 7
RIGHTMARGIN, 179
TOPMARGIN, 7
BOTTOMMARGIN, 88
END
IDD_AGE_SAVEYESNO, DIALOG
BEGIN
LEFTMARGIN, 7
RIGHTMARGIN, 179
TOPMARGIN, 7
BOTTOMMARGIN, 54
END
END
#endif // APSTUDIO_INVOKED
/////////////////////////////////////////////////////////////////////////////
//
// Bitmap
//
IDB_CURSOR_UP BITMAP "../../Plasma/Apps/plClient/res/cursor_up.bmp"
IDB_CURSOR_DOWN BITMAP "../../Plasma/Apps/plClient/res/cursor_down.bmp"
IDB_CURSOR_RIGHT BITMAP "../../Plasma/Apps/plClient/res/cursor_right.bmp"
IDB_CURSOR_LEFT BITMAP "../../Plasma/Apps/plClient/res/cursor_left.bmp"
IDB_CURSOR_OPEN BITMAP "../../Plasma/Apps/plClient/res/cursor_open.bmp"
IDB_CURSOR_GRAB BITMAP "../../Plasma/Apps/plClient/res/cursor_grab.bmp"
IDB_CURSOR_CLICKED BITMAP "../../Plasma/Apps/plClient/res/cursor_clicked.bmp"
IDB_CURSOR_POISED BITMAP "../../Plasma/Apps/plClient/res/cursor_poised.bmp"
/////////////////////////////////////////////////////////////////////////////
//
// Menu
//
IDR_COMP_MENU MENU
BEGIN
POPUP "Tools"
BEGIN
MENUITEM "Remove Unused Components", ID_REMOVE_UNUSED
MENUITEM SEPARATOR
MENUITEM "Refresh View", ID_REFRESH
END
END
/////////////////////////////////////////////////////////////////////////////
//
// String Table
//
STRINGTABLE
BEGIN
IDS_ACT1_DESC "Save Selected (with components)"
IDS_ACT1_NAME "Save Selected..."
IDS_ACT2_DESC "Merge File (with components)"
IDS_ACT2_NAME "Merge..."
IDS_ACT3_NAME "Component Manager..."
IDS_ACT4_NAME "Resource Collector..."
IDS_ACT5_NAME "Age Description Manager..."
IDS_ACT6_NAME "Copy Components..."
IDS_ACT7_NAME "SceneViewer..."
IDS_ACT8_DESC "Lock Selected"
IDS_ACT8_NAME "Lock"
IDS_ACT9_DESC "Unlock Selected"
IDS_ACT9_NAME "Unlock"
IDS_ACT10_NAME "Texture Find and Replace..."
IDS_PLASMA_EXPORT "Plasma Export..."
END
STRINGTABLE
BEGIN
IDS_ACT11_NAME "ResetXform"
IDS_ACT11_DESC "Reset Transform"
IDS_ACT12_NAME "Select NonRend"
IDS_ACT12_DESC "Select NonRenderables"
IDS_ACT_CAT "Plasma"
END
#endif // English (U.S.) resources
/////////////////////////////////////////////////////////////////////////////
#ifndef APSTUDIO_INVOKED
/////////////////////////////////////////////////////////////////////////////
//
// Generated from the TEXTINCLUDE 3 resource.
//
#include "../MaxComponent/plComponent.rc"
#include "../MaxPlasmaMtls/MaxPlasmaMtls.rc"
/////////////////////////////////////////////////////////////////////////////
#endif // not APSTUDIO_INVOKED

View File

@ -0,0 +1,62 @@
/*==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==*/
// These take a long time to compile so I'm putting them here so they won't be
// rebuilt unless completely necessary -Colin
#include "HeadSpin.h"
#include "pnNucleusCreatables.h"
#include "plAllCreatables.h"
//#include "pfAllCreatables.h"
#include "../pfCharacter/pfCharacterCreatable.h"
#include "../pfCamera/pfCameraCreatable.h"
#include "../pfAnimation/pfAnimationCreatable.h"
#include "../pfConditional/plConditionalObjectCreatable.h"
//#include "../pfConsole/pfConsoleCreatable.h"
#include "../pfSurface/pfSurfaceCreatable.h"
#include "../pfMessage/pfMessageCreatable.h"
#include "../pfAudio/pfAudioCreatable.h"
#include "../pfPython/pfPythonCreatable.h"
#include "../pfGameGUIMgr/pfGameGUIMgrCreatable.h"
#include "../pfCCR/plCCRCreatable.h"
#include "../pfJournalBook/pfJournalBookCreatable.h"
#include "../pfGameMgr/pfGameMgrCreatables.h"

View File

@ -0,0 +1,292 @@
/*==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 "HeadSpin.h"
#include "Max.h"
#include "istdplug.h"
#include "custcont.h"
#include "HeadSpin.h"
#include "../MaxExport/SimpleExport.h"
#include "../MaxComponent/plComponentMgr.h"
#include "../MaxPlasmaMtls/plMtlImport.h"
extern ClassDesc* GetGUPDesc();
extern ClassDesc* GetComponentUtilDesc();
extern ClassDesc* GetComponentMgrDesc();
extern ClassDesc *GetMaxFileDataDesc();
extern ClassDesc* GetMaxUtilsDesc();
static HSClassDesc2 HSDesc;
static int controlsInit = FALSE;
HINSTANCE hInstance = NULL;
/*inline*/ TCHAR *GetString(int id)
{
static TCHAR buf[256];
if (hInstance)
return LoadString(hInstance, id, buf, sizeof(buf)) ? buf : NULL;
return NULL;
}
//
// return a string to be displayed if the DLL is not found
//
__declspec(dllexport) const TCHAR *LibDescription()
{
return "Plasma 2.0";
}
//
// the number of plugin classes in the dll
//
__declspec(dllexport) int LibNumberClasses()
{
return 7 + plComponentMgr::Inst().Count() + plPlasmaMtlImport::GetNumMtlDescs();
}
//
// return the i'th class descriptor defined by the plugin
//
// TEMP //
class plGeneralAttribClassDesc;
extern plGeneralAttribClassDesc theGeneralAttribClassDesc;
// TEMP //
__declspec(dllexport) ClassDesc *LibClassDesc(int i)
{
switch(i)
{
case 0:
return &HSDesc;
case 1:
return GetGUPDesc();
case 2:
return (ClassDesc*)&theGeneralAttribClassDesc;
case 3:
return GetComponentUtilDesc();
case 4:
return GetComponentMgrDesc();
case 5:
return GetMaxFileDataDesc();
case 6:
return GetMaxUtilsDesc();
default:
{
int numMtls = plPlasmaMtlImport::GetNumMtlDescs();
if( i - 7 < numMtls )
return plPlasmaMtlImport::GetMtlDesc( i - 7 );
return plComponentMgr::Inst().Get( i - 7 - numMtls );
}
}
}
//
// Return version so can detect obsolete DLLs
//
__declspec(dllexport) ULONG LibVersion()
{
return VERSION_3DSMAX;
}
#include "plPythonMgr.h"
#include "plPluginResManager.h"
#include "../plSDL/plSDL.h"
#include "plMaxCFGFile.h"
#include <direct.h>
#include "../plFile/hsFiles.h"
//
// DLLMAIN
//
BOOL WINAPI DllMain(HINSTANCE hinstDLL,ULONG fdwReason,LPVOID lpvReserved)
{
hInstance = hinstDLL;
if (!controlsInit)
{
controlsInit = TRUE;
// jaguar controls
InitCustomControls(hInstance);
// initialize Chicago controls
InitCommonControls();
plPythonMgr::Instance().LoadPythonFiles();
const char *clientPath = plMaxConfig::GetClientPath(false, true);
if (clientPath)
{
char oldCwd[kFolderIterator_MaxPath];
_getcwd(oldCwd, sizeof(oldCwd));
_chdir(clientPath);
plSDLMgr::GetInstance()->Init();
_chdir(oldCwd);
}
// Initialize the ResManager
plResManager* pRmgr = TRACKED_NEW plPluginResManager;
hsgResMgr::Init(pRmgr);
}
switch (fdwReason)
{
case DLL_PROCESS_ATTACH:
break;
case DLL_THREAD_ATTACH:
break;
case DLL_THREAD_DETACH:
break;
case DLL_PROCESS_DETACH:
break;
}
return(TRUE);
}
//////////////////////////////////////////////////////////////////////////////////
// TEMP
//////////////////////////////////////////////////////////////////////////////////
#include "CustAttrib.h"
#include "ICustAttribContainer.h"
#include "iparamb2.h"
#define PL_GEN_ATTRIB_CLASS_ID Class_ID(0x24c36e6e, 0x53ec2ce4)
class plGeneralAttrib : public CustAttrib
{
public:
ClassDesc2 *fClassDesc;
IParamBlock2 *fPBlock;
plGeneralAttrib();
virtual RefResult NotifyRefChanged(Interval changeInt, RefTargetHandle hTarget,
PartID& partID, RefMessage message){return REF_SUCCEED;}
int NumParamBlocks() { return 1; } // return number of ParamBlocks in this instance
IParamBlock2* GetParamBlock(int i) { return fPBlock; } // return i'th ParamBlock
IParamBlock2* GetParamBlockByID(BlockID id) { return (fPBlock->ID() == id) ? fPBlock : NULL; } // return id'd ParamBlock
int NumRefs() { return 1;}
virtual RefTargetHandle GetReference(int i) { if(i == 0) return fPBlock; else return NULL; }
virtual void SetReference(int i, RefTargetHandle rtarg) { if(i == 0) fPBlock = (IParamBlock2 *)rtarg; }
virtual int NumSubs() { return 1; }
virtual Animatable* SubAnim(int i) { return fPBlock; }
virtual TSTR SubAnimName(int i){ return fClassDesc->ClassName();}
void BeginEditParams(IObjParam *ip,ULONG flags,Animatable *prev);
void EndEditParams(IObjParam *ip, ULONG flags, Animatable *next);
SClass_ID SuperClassID() {return CUST_ATTRIB_CLASS_ID;}
Class_ID ClassID() {return fClassDesc->ClassID();}
ReferenceTarget *Clone(RemapDir &remap = NoRemap());
virtual bool CheckCopyAttribTo(ICustAttribContainer *to) { return true; }
TCHAR* GetName() { return (TCHAR*)fClassDesc->ClassName(); }
void DeleteThis() { delete this; }
};
class plGeneralAttribClassDesc : public ClassDesc2
{
public:
int IsPublic() { return 1; }
void* Create(BOOL loading) { return TRACKED_NEW plGeneralAttrib; }
const TCHAR* ClassName() { return _T("Plasma Attrib"); }
SClass_ID SuperClassID() { return CUST_ATTRIB_CLASS_ID; }
Class_ID ClassID() { return PL_GEN_ATTRIB_CLASS_ID; }
const TCHAR* Category() { return _T(""); }
const TCHAR* InternalName() { return _T("PlasmaAttrib"); }
HINSTANCE HInstance() { return hInstance; }
};
static plGeneralAttribClassDesc theGeneralAttribClassDesc;
//
// Parameter Block Description
//
enum
{
kRoomName = 0
};
ParamBlockDesc2 generalAttribBlock
(
1, _T("GeneralAttribs"), 0, &theGeneralAttribClassDesc, P_AUTO_CONSTRUCT, 0,
// params
kRoomName, _T("roomName"), TYPE_STRING, 0, 0,
p_default, "",
end,
end
);
plGeneralAttrib::plGeneralAttrib() : fClassDesc(&theGeneralAttribClassDesc), fPBlock(NULL)
{
fClassDesc->MakeAutoParamBlocks(this);
}
void plGeneralAttrib::BeginEditParams(IObjParam *ip,ULONG flags,Animatable *prev)
{
fClassDesc->BeginEditParams(ip,this,flags,prev);
}
void plGeneralAttrib::EndEditParams(IObjParam *ip, ULONG flags, Animatable *next)
{
fClassDesc->EndEditParams(ip,this,flags,next);
}
ReferenceTarget *plGeneralAttrib::Clone(RemapDir &remap)
{
plGeneralAttrib *pnew = (plGeneralAttrib*) fClassDesc->Create(false);
pnew->MakeRefByID(FOREVER,0,remap.CloneRef(fPBlock));
BaseClone(this, pnew, remap);
return pnew;
}
//////////////////////////////////////////////////////////////////////////////////
// TEMP
//////////////////////////////////////////////////////////////////////////////////

View File

@ -0,0 +1,8 @@
LIBRARY
EXPORTS
LibDescription @1
LibNumberClasses @2
LibClassDesc @3
LibVersion @4
SECTIONS
.data READ WRITE

View File

@ -0,0 +1,157 @@
/*==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==*/
/******************************************************************************
plActionTableMgr.cpp
Eric Ellis
******************************************************************************/
#include "HeadSpin.h"
#include "plActionTableMgr.h"
plActionTableMgr::plActionTableMgr(ActionTableInfo& actionTable, ActionCallbackFunc cbFunc)
{
AddActionTable(actionTable, cbFunc);
RegisterNotification(SysStartup, this, NOTIFY_SYSTEM_STARTUP);
RegisterNotification(SysShutdown, this, NOTIFY_SYSTEM_SHUTDOWN);
}
plActionTableMgr::~plActionTableMgr()
{
UnRegisterNotification(SysStartup, this, NOTIFY_SYSTEM_STARTUP);
UnRegisterNotification(SysShutdown, this, NOTIFY_SYSTEM_SHUTDOWN);
}
void plActionTableMgr::AddActionTable(ActionTableInfo& actionTable, ActionCallbackFunc cbFunc)
{
actionTable.ActionCB = new ActionTableMgrCB(cbFunc);
fActionTables.push_back(&actionTable);
}
CoreExport void *__cdecl MAX_new(size_t size);
CoreExport void __cdecl MAX_delete(void* mem);
class plActionTable : public ActionTable
{
public:
plActionTable(ActionTableId id, ActionContextId contextId, TSTR& name, HACCEL hDefaults, int numIds, ActionDescription* pOps, HINSTANCE hInst)
: ActionTable(id, contextId, name, hDefaults, numIds, pOps, hInst) {}
plActionTable(ActionTableId id, ActionContextId contextId, TSTR& name)
: ActionTable(id, contextId, name) {}
void *operator new (size_t)
{
return MAX_new(sizeof(plActionTable));
}
void operator delete (void * mem)
{
MAX_delete(mem);
}
};
ActionTable* plActionTableMgr::GetActionTable(int i)
{
if(i > this->NumActionTables())
{
return NULL;
}
ActionTableInfo* pTableInfo = fActionTables[i];
if(pTableInfo->Created)
{
return GetCOREInterface()->GetActionManager()->FindTable(pTableInfo->TableId);
}
ActionTable *pTab = new plActionTable(
pTableInfo->TableId,
pTableInfo->ContextId,
pTableInfo->Name, NULL,
pTableInfo->Actions.size(),
&pTableInfo->Actions[0],
hInstance
);
// register the action table with the system before we hand it off
GetCOREInterface()->GetActionManager()->RegisterActionContext(pTableInfo->ContextId, pTableInfo->Name);
pTableInfo->Created = true;
return pTab;
}
void plActionTableMgr::SysStartup(void *param, NotifyInfo *info)
{
plActionTableMgr* pActionTableMgr = (plActionTableMgr*)param;
// ((MenuTestUtil*)param)->CreateMenu(); //setup menus
IActionManager* pActionMgr = GetCOREInterface()->GetActionManager();
for(int i = 0; i < pActionTableMgr->NumActionTables(); i++)
{
ActionTableInfo* pTableInfo = pActionTableMgr->fActionTables[i];
pActionMgr->ActivateActionTable(pTableInfo->ActionCB, pTableInfo->TableId);
}
}
void plActionTableMgr::SysShutdown(void *param, NotifyInfo *info)
{
plActionTableMgr* pActionTableMgr = (plActionTableMgr*)param;
IActionManager* pActionMgr = GetCOREInterface()->GetActionManager();
for(int i = 0; i < pActionTableMgr->NumActionTables(); i++)
{
ActionTableInfo* pTableInfo = pActionTableMgr->fActionTables[i];
pActionMgr->DeactivateActionTable(pTableInfo->ActionCB, pTableInfo->TableId);
}
}

View File

@ -0,0 +1,142 @@
/*==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==*/
/******************************************************************************
plActionTableMgr.h
Eric Ellis
******************************************************************************/
#ifndef __PLACTIONTABLEMGR_H
#define __PLACTIONTABLEMGR_H
#include "Max.h"
#include "notify.h"
#include <vector>
#include "hsTypes.h"
typedef bool(*ActionCallbackFunc)(int);
/******************************************************************************
Helper classes for plActionTableMgr
******************************************************************************/
class ActionTableMgrCB : public ActionCallback
{
ActionCallbackFunc fCallbackFunc;
public:
ActionTableMgrCB(ActionCallbackFunc cbFunc) {fCallbackFunc = cbFunc;}
BOOL ExecuteAction(int id) { return fCallbackFunc(id) ? TRUE : FALSE; }
};
class ActionTableInfo
{
friend class plActionTableMgr;
private:
ActionTableMgrCB* ActionCB;
bool Created;
public:
ActionTableId TableId;
ActionContextId ContextId;
TSTR Name;
std::vector<ActionDescription> Actions;
ActionTableInfo(ActionTableId actionId, TCHAR* name, ActionDescription actions[], int numActions)
{
TableId = actionId;
ContextId = actionId;
Name = name;
Created = false;
ActionCB = NULL;
for(int i = 0; i < numActions; i++)
{
Actions.push_back(actions[i]);
}
}
ActionTableInfo()
{
TableId = 0;
ContextId = 0;
Created = false;
ActionCB = NULL;
}
virtual ~ActionTableInfo()
{
delete ActionCB;
}
};
/******************************************************************************
plActionTableMgr class defintion
******************************************************************************/
class plActionTableMgr
{
std::vector<ActionTableInfo*> fActionTables;
public:
plActionTableMgr(ActionTableInfo& actionTable, ActionCallbackFunc cbFunc);
virtual ~plActionTableMgr();
void AddActionTable(ActionTableInfo& actionTable, ActionCallbackFunc cbFunc);
int NumActionTables() { return fActionTables.size(); }
ActionTable* GetActionTable(int i);
private:
static void SysStartup(void *param, NotifyInfo *info);
static void SysShutdown(void *param, NotifyInfo *info);
};
#endif __PLACTIONTABLEMGR_H

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,137 @@
/*==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 "hsWindows.h"
#include "hsTypes.h"
#include "hsTemplates.h"
#include <comutil.h>
#include <vector>
using std::vector;
class ISpinnerControl;
class plAgeDescription;
class plAgeFile;
typedef struct _TREEITEM *HTREEITEM;
class MaxAssBranchAccess;
class plAgeDescInterface
{
protected:
HWND fhDlg;
bool fDirty;
int fCurAge;
ISpinnerControl *fSpin;
ISpinnerControl *fCapSpin;
ISpinnerControl *fSeqPrefixSpin;
HTREEITEM fCurrAgeItem;
bool fCurrAgeCheckedOut;
char fCheckedOutPath[ MAX_PATH ];
bool fForceSeqNumLocal;
HTREEITEM fAssetManBranch, fLocalBranch;
HFONT fBoldFont;
HBRUSH fHiliteBrush;
vector<plAgeFile*> fAgeFiles;
// vector<_variant_t> fAssetIds;
MaxAssBranchAccess *fAssetManIface;
plAgeDescInterface();
public:
~plAgeDescInterface();
static plAgeDescInterface& Instance();
// Open the dialog
void Open();
static BOOL CALLBACK ForwardDlgProc(HWND hDlg, UINT msg, WPARAM wParam, LPARAM lParam);
BOOL DlgProc(HWND hDlg, UINT msg, WPARAM wParam, LPARAM lParam);
static void BuildAgeFileList( hsTArray<char *> &ageList );
protected:
static int IFindAge(const char* ageName, vector<plAgeFile*>& ageFiles);
static void IGetAgeFiles(vector<plAgeFile*>& ageFiles);
static void IClearAgeFiles(vector<plAgeFile*>& ageFiles);
void IResetParams();
void IInitControls();
void ISetControlDefaults();
void IEnableControls(bool enable);
void IEnablePageControls(bool enable);
void ICheckedPageFlag(int ctrlID);
// Save the settings for the last age and load the settings for the currently one
void IUpdateCurAge();
void ISaveCurAge( const char *path, hsBool checkSeqNum = false );
void ILoadAge( const char *path, hsBool checkSeqNum = false );
static bool IGetLocalAgePath(char *path);
// Fill out the age tree view
void IFillAgeTree( void );
// Create a new age file and select it in the browser
void INewAge();
void INewPage();
UInt32 IGetNextFreeSequencePrefix( hsBool getReservedPrefix );
UInt32 IGetFreePageSeqSuffix( HWND pageCombo );
void ICheckOutCurrentAge( void );
void ICheckInCurrentAge( void );
void IUndoCheckOutCurrentAge( void );
hsBool IMakeSureCheckedIn( void );
plAgeFile* IGetCurrentAge( void );
void IInvalidateCheckOutIndicator( void );
void ICheckSequenceNumber( plAgeDescription &aged );
};

View File

@ -0,0 +1,240 @@
/*==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==*/
//////////////////////////////////////////////////////////////////////////////
// //
// plCommonObjLib - Base class for a library of objects that are stored //
// in common pages (for now, that means Textures or //
// BuiltIn pages). //
// //
//////////////////////////////////////////////////////////////////////////////
#include "HeadSpin.h"
#include "hsTypes.h"
#include "plCommonObjLib.h"
#include "../pnKeyedObject/hsKeyedObject.h"
#include "../pnKeyedObject/plUoid.h"
#include "plPluginResManager.h"
//////////////////////////////////////////////////////////////////////////////
//// Static Array And Functions //////////////////////////////////////////////
// Used only by the export resManager, to create and maintain a list of the
// commonObjLibs to be used.
//////////////////////////////////////////////////////////////////////////////
class plCommonObjLibList
{
public:
UInt32 fRefCount;
hsTArray<plCommonObjLib *> fLibs;
plCommonObjLibList() { fRefCount = 0; }
void Add( plCommonObjLib *lib )
{
fLibs.Append( lib );
fRefCount++;
}
hsBool Remove( plCommonObjLib *lib )
{
int idx = fLibs.Find( lib );
if( idx != fLibs.kMissingIndex )
fLibs.Remove( idx );
else
{
hsAssert( false, "Common Object Lib not found in list upon deletion. Are you misusing this class? Tsk tsk!" );
}
fRefCount--;
return ( fRefCount == 0 ) ? true : false;
}
};
plCommonObjLibList *plCommonObjLib::fLibList = nil;
UInt32 plCommonObjLib::GetNumLibs( void )
{
return ( fLibList != nil ) ? fLibList->fLibs.GetCount() : 0;
}
plCommonObjLib *plCommonObjLib::GetLib( UInt32 idx )
{
if( fLibList == nil )
return nil;
if( idx < fLibList->fLibs.GetCount() )
return fLibList->fLibs[ idx ];
return nil;
}
//////////////////////////////////////////////////////////////////////////////
//// Constructor/Destructor //////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////
plCommonObjLib::plCommonObjLib()
{
// Make sure we have a list to add ourselves to
if( fLibList == nil )
fLibList = TRACKED_NEW plCommonObjLibList();
// Add ourselves to the list of libs
fLibList->Add( this );
}
plCommonObjLib::~plCommonObjLib()
{
ClearObjectList();
// Remove ourselves from the list of libs
if( fLibList->Remove( this ) )
{
// List is no longer needed
delete fLibList;
fLibList = nil;
}
}
//////////////////////////////////////////////////////////////////////////////
//// Base Utility Functions //////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////
//// ClearObjectList /////////////////////////////////////////////////////////
void plCommonObjLib::ClearObjectList( void )
{
int i;
// Unref our object list, so they'll go away properly
for( i = 0; i < fObjects.GetCount(); i++ )
fObjects[ i ]->GetKey()->UnRefObject();
fObjects.Reset();
}
//// AddObject ///////////////////////////////////////////////////////////////
// Adds the given object to our lib. The object must have a key already.
void plCommonObjLib::AddObject( hsKeyedObject *object )
{
if( object == nil || object->GetKey() == nil )
{
hsAssert( false, "Trying to add an object to a commonLib that doesn't have a key" );
return;
}
// Ref it so it won't go away on us
object->GetKey()->RefObject();
fObjects.Append( object );
}
//// RemoveObjectAndKey //////////////////////////////////////////////////////
// Given the key to an object, completely nukes the object and the key. After
// this function call, the key should no longer exist in the registry and be
// free to use elsewhere.
hsBool plCommonObjLib::RemoveObjectAndKey( plKey &key )
{
if (!key)
{
hsAssert( false, "Received RemoveObjectAndKey() call for a key that is invalid. Nillifying key anyway." );
key = nil;
return true;
}
hsKeyedObject *object = hsKeyedObject::ConvertNoRef( key->ObjectIsLoaded() );
if( object == nil )
{
hsAssert( false, "Received RemoveObjectAndKey() call for a key that isn't loaded. Nillifying key anyway." );
key = nil;
return true;
}
int idx = fObjects.Find( object );
if( idx == fObjects.kMissingIndex )
{
hsAssert( false, "Trying to RemoveObjectAndKey() for a common object not in the lib." );
key = nil;
return true;
}
// Unref and remove from our list
fObjects[ idx ]->GetKey()->UnRefObject();
fObjects.Remove( idx );
// Nuke out the key and its object
if( !plPluginResManager::ResMgr()->NukeKeyAndObject( key ) )
{
hsAssert( false, "Trouble nuking out the key for this texture. Problems abound...." );
return false;
}
// All done!
return true;
}
//// FindObject //////////////////////////////////////////////////////////////
// Given a name and an optional class type, tries to find that object in
// our lib. Returns nil if not found. Use to find out if you already have a
// object of a given name that was previously exported.
hsKeyedObject *plCommonObjLib::FindObject( const char *name, UInt16 classType /* = -1 */ )
{
int i;
for( i = 0; i < fObjects.GetCount(); i++ )
{
const plUoid &uoid = fObjects[ i ]->GetKey()->GetUoid();
if( stricmp( uoid.GetObjectName(), name ) == 0 &&
( classType == (UInt16)-1 || classType == uoid.GetClassType() ) )
{
return fObjects[ i ];
}
}
return nil;
}

View File

@ -0,0 +1,108 @@
/*==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==*/
//////////////////////////////////////////////////////////////////////////////
// //
// plCommonObjLib - Base class for a library of objects that are stored //
// in common pages (for now, that means Textures or //
// BuiltIn pages). //
// //
//// How To Use //////////////////////////////////////////////////////////////
// //
// Derive from this class and override the IsInteresting function to //
// filter out which objects you're interested in. Then, create an object //
// of this type (static is fine) before the export process begins. //
// //
// Then, when you are going to create an object in a common page, call //
// this lib to see if the object is already created. If so, it'll already //
// be loaded and ready to go, and you shouldn't create another one. Of //
// course, you always have the option of deleting it and creating another. //
// //
// The single biggest limitation is that objects in common pages can NOT //
// have ANY refs to ANY other objects in ANY other page. Otherwise, their //
// refs will get completely screwed up at export time. So don't do it!!! //
// //
//////////////////////////////////////////////////////////////////////////////
#ifndef _plCommonObjLib_h
#define _plCommonObjLib_h
#include "hsTemplates.h"
//// Class Definition /////////////////////////////////////////////////////////
class plCommonObjLibList;
class hsKeyedObject;
class plKey;
class plCommonObjLib
{
protected:
hsTArray<hsKeyedObject *> fObjects;
public:
plCommonObjLib();
virtual ~plCommonObjLib();
/// Base utility functions
void AddObject( hsKeyedObject *object );
hsBool RemoveObjectAndKey( plKey &key );
hsKeyedObject *FindObject( const char *name, UInt16 classType = (UInt16)-1 );
void ClearObjectList( void );
/// THIS IS YOUR VIRTUAL HERE. Override this to define which objects you collect
virtual hsBool IsInteresting( const plKey &objectKey ) { return false; }
/// Static functions for use only by the export resManager
static UInt32 GetNumLibs( void );
static plCommonObjLib *GetLib( UInt32 idx );
private:
static plCommonObjLibList *fLibList;
};
#endif //_plCommonObjLib_h

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,122 @@
/*==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 "max.h"
#include "notify.h"
#include <vector>
class plMaxNode;
class plComponentDlg
{
protected:
friend class plComponentUtil;
HWND fhDlg;
HMENU fCompMenu;
HMENU fTypeMenu;
Interface *fInterface;
POINT fSmallestSize;
RECT fLastRect;
// The node we're currently editing the comment for
plMaxNode *fCommentNode;
std::vector<Class_ID> fHiddenComps;
public:
~plComponentDlg();
static plComponentDlg &Instance();
void Open();
void SelectComponentTargs(INodeTab& nodes);
protected:
plComponentDlg();
static BOOL CALLBACK ForwardDlgProc(HWND hDlg, UINT msg, WPARAM wParam, LPARAM lParam);
BOOL DlgProc(HWND hDlg, UINT msg, WPARAM wParam, LPARAM lParam);
void IPositionControls(RECT *newRect, int edge);
enum { kResizeX = 1, kResizeY = 2, kMoveX = 4, kMoveY = 8 };
void IPositionControl(HWND hControl, int hDiff, int wDiff=0, int flags=kMoveY);
HTREEITEM IAddLeaf(HWND hTree, HTREEITEM hParent, const char *text, LPARAM lParam);
// Search for an item in the tree by name, but only in the children of hParent
HTREEITEM IFindTreeItem(HWND hTree, const char *name, HTREEITEM hParent);
HTREEITEM IAddComponent(HWND hTree, plMaxNode *node);
void IAddComponentsRecur(HWND hTree, plMaxNode *node);
void ICreateMenu();
bool IIsComponent(LPARAM lParam);
bool IIsType(LPARAM lParam);
void IAttachTreeSelection();
void ISelectTreeSelection();
plMaxNode *IGetTreeSelection();
plMaxNode *ITreeItemToNode(HWND hTree, HTREEITEM hItem);
void IDeleteComponent(plMaxNode *component);
void IGetComponentsRecur(HWND hTree, HTREEITEM hItem, INodeTab& nodes);
void ICreateRightClickMenu();
void IOpenRightClickMenu();
HTREEITEM ISearchTree(HWND hTree, LPARAM lParam, HTREEITEM hCur=TVGN_ROOT);
void IRefreshTree();
void IRemoveUnusedComps();
static void INotify(void *param, NotifyInfo *info);
// To syncronize with plComponentUtil when a name is changed
void IUpdateNodeName(plMaxNode *node);
void IGetComment();
bool IIsHidden(Class_ID& cid);
};
// Brings up the copy components dialog. Stuck here for no particular reason.
void CopyComponents();

View File

@ -0,0 +1,526 @@
/*==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 "HeadSpin.h"
#include "plComponentPanel.h"
#include "resource.h"
#include "plMaxNode.h"
#include "../MaxComponent/plComponent.h"
#include "../MaxComponent/plComponentMgr.h"
#include "plComponentDlg.h"
#include "plMaxAccelerators.h"
extern TCHAR *GetString(int id);
class ComponentUtilClassDesc : public ClassDesc
{
public:
int IsPublic() { return TRUE; }
void* Create(BOOL loading) { return &plComponentUtil::Instance(); }
const TCHAR* ClassName() { return _T("Component Util"); }
SClass_ID SuperClassID() { return UTILITY_CLASS_ID; }
Class_ID ClassID() { return Class_ID(0xb220659, 0x31015552); }
const TCHAR* Category() { return _T(""); }
};
static ComponentUtilClassDesc theComponentUtilCD;
ClassDesc* GetComponentUtilDesc() { return &theComponentUtilCD; }
plComponentUtil::plComponentUtil() : fInterface(nil), fhPanel(nil), fCurComponent(nil), fLastComponent(nil)
{
}
plComponentUtil& plComponentUtil::Instance()
{
static plComponentUtil theInstance;
return theInstance;
}
////////////////////////////////////////////////////////////////////////////////
// Proc for the currently selected object dialog
//
BOOL CALLBACK plComponentUtil::ForwardDlgProc(HWND hDlg, UINT msg, WPARAM wParam, LPARAM lParam)
{
return Instance().DlgProc(hDlg, msg, wParam, lParam);
}
BOOL plComponentUtil::DlgProc(HWND hDlg, UINT msg, WPARAM wParam, LPARAM lParam)
{
switch (msg)
{
case WM_COMMAND:
// Switch to next or previous target
if (HIWORD(wParam) == BN_CLICKED && (LOWORD(wParam) == IDC_BACK || LOWORD(wParam) == IDC_FORWARD))
{
INextTarget(LOWORD(wParam) == IDC_FORWARD);
return TRUE;
}
else if (HIWORD(wParam) == BN_CLICKED && LOWORD(wParam) == IDC_REF_BY_BUTTON)
{
IShowRefdBy();
return TRUE;
}
break;
case WM_NOTIFY:
{
NMHDR *nmhdr = (NMHDR*)lParam;
if (nmhdr->idFrom == IDC_COMPLIST)
{
switch (nmhdr->code)
{
// Stop Max from reading keypresses while the list has focus
case NM_SETFOCUS:
plMaxAccelerators::Disable();
return TRUE;
case NM_KILLFOCUS:
plMaxAccelerators::Enable();
return TRUE;
case LVN_KEYDOWN:
{
NMLVKEYDOWN *kd = (NMLVKEYDOWN*)lParam;
if (kd->wVKey == VK_DELETE)
IDeleteListSelection();
}
return TRUE;
// The edit box this creates kills the focus on the listbox,
// so add an extra disable to ignore it
case LVN_BEGINLABELEDIT:
plMaxAccelerators::Disable();
return TRUE;
// Finishing changing the name of a component
case LVN_ENDLABELEDIT:
{
NMLVDISPINFO *di = (NMLVDISPINFO*)lParam;
const char *name = di->item.pszText;
// If the name was changed...
if (name && *name != '\0')
{
// Update the name of the node
plComponentBase* comp = IGetListSelection();
comp->GetINode()->SetName(di->item.pszText);
// Make sure the column is wide enough
int width = ListView_GetStringWidth(nmhdr->hwndFrom, di->item.pszText)+10;
if (width > ListView_GetColumnWidth(nmhdr->hwndFrom, 0))
{
ListView_SetColumnWidth(nmhdr->hwndFrom, 0, width);
InvalidateRect(nmhdr->hwndFrom, NULL, FALSE);
}
// Update the name in the tree too
plComponentDlg::Instance().IUpdateNodeName((plMaxNode*)comp->GetINode());
// Return true to keep the changes
SetWindowLong(hDlg, DWL_MSGRESULT, TRUE);
}
plMaxAccelerators::Enable();
}
return TRUE;
// Selected component has changed. This notification can come
// more than necessary, so IAddRollups doesn't change the rollups
// if the "new" one is the same as the old.
case LVN_ITEMCHANGED:
{
plComponentBase* comp = IGetListSelection();
IAddRollups(comp);
}
return TRUE;
}
}
}
break;
}
return FALSE;
}
void plComponentUtil::IDeleteListSelection()
{
plComponentBase* comp = IGetListSelection();
if (comp)
{
// Delete each of the selected nodes from this components target list
int count = fInterface->GetSelNodeCount();
for (int i = 0; i < count; i++)
{
plMaxNode *curNode = (plMaxNode*)fInterface->GetSelNode(i);
comp->DeleteTarget(curNode);
}
IUpdateRollups();
}
}
plComponentBase* plComponentUtil::IGetListSelection()
{
HWND hList = GetDlgItem(fhPanel, IDC_COMPLIST);
int index = ListView_GetNextItem(hList, -1, LVNI_SELECTED);
if (index != -1)
{
LVITEM item;
item.mask = LVIF_PARAM;
item.iItem = index;
item.iSubItem = 0;
if (ListView_GetItem(hList, &item))
return (plComponentBase*)item.lParam;
}
return nil;
}
void plComponentUtil::BeginEditParams(Interface *ip, IUtil *iu)
{
fInterface = ip;
fhPanel = fInterface->AddRollupPage(hInstance, MAKEINTRESOURCE(IDD_COMP_PANEL), ForwardDlgProc, "Components (Selected Obj)");
// Add a column. We don't use it (graphically), but it has to be there.
HWND hList = GetDlgItem(fhPanel, IDC_COMPLIST);
LVCOLUMN lvc;
lvc.mask = LVCF_TEXT;
lvc.pszText = "Description";
ListView_InsertColumn(hList, 0, &lvc);
IUpdateRollups();
}
void plComponentUtil::EndEditParams(Interface *ip, IUtil *iu)
{
IDestroyRollups();
GetCOREInterface()->DeleteRollupPage(fhPanel);
fhPanel = nil;
fCurComponent = nil;
fInterface = nil;
}
void plComponentUtil::SelectionSetChanged(Interface *ip, IUtil *iu)
{
IUpdateRollups();
}
void plComponentUtil::IUpdateRollups()
{
if (!fhPanel)
return;
// Destroy any current rollups
IDestroyRollups();
HWND hList = GetDlgItem(fhPanel, IDC_COMPLIST);
ListView_DeleteAllItems(hList);
// Check that something is selected.
int nodeCount = fInterface->GetSelNodeCount();
if (nodeCount == 0)
{
IAddRollups(nil);
return;
}
// Get the components shared among the selected nodes
int i;
INodeTab selNodes;
selNodes.SetCount(nodeCount);
for (i = 0; i < nodeCount; i++)
selNodes[i] = fInterface->GetSelNode(i);
INodeTab sharedComps;
plSharedComponents(selNodes, sharedComps);
// Add the shared components to the list
for (i = 0; i < sharedComps.Count(); i++)
{
plComponentBase *comp = ((plMaxNode*)sharedComps[i])->ConvertToComponent();
if (plComponentDlg::Instance().IIsHidden(comp->ClassID()))
continue;
IParamBlock2 *pb = comp->GetParamBlockByID(plComponent::kBlkComp);
LVITEM item = {0};
item.mask = LVIF_TEXT | LVIF_PARAM;
item.pszText = sharedComps[i]->GetName();
item.iItem = ListView_GetItemCount(hList);
item.lParam = (LPARAM)comp;
ListView_InsertItem(hList, &item);
}
// Make sure the column is wide enough
ListView_SetColumnWidth(hList, 0, LVSCW_AUTOSIZE);
// If there are rollups to show
if (ListView_GetItemCount(hList) > 0)
{
// Try and find the last used rollup
int idx = IFindListItem(fLastComponent);
// If last one wasn't found, just use the first
if (idx == -1)
idx = 0;
ListView_SetItemState(hList, idx, LVIS_SELECTED, LVIS_SELECTED);
ListView_EnsureVisible(hList, idx, FALSE);
}
else
IAddRollups(nil);
}
int plComponentUtil::IFindListItem(plComponentBase* comp)
{
LVFINDINFO fi;
fi.flags = LVFI_PARAM;
fi.lParam = (LPARAM)comp;
return ListView_FindItem(GetDlgItem(fhPanel, IDC_COMPLIST), -1, &fi);
}
#include "../MaxComponent/plAutoUIComp.h"
void plComponentUtil::IAddRollups(plComponentBase* comp)
{
if (fCurComponent == comp)
return;
IDestroyRollups();
fCurComponent = comp;
if (comp)
fLastComponent = comp;
//
// Update the targets dialog
//
UInt32 numTargs = 0;
if (fCurComponent)
{
// Only count non-nil targets
for (UInt32 i = 0; i < fCurComponent->NumTargets(); i++)
if (fCurComponent->GetTarget(i))
numTargs++;
}
// Put the number of targets in the text box
char buf[12];
itoa(numTargs, buf, 10);
SetWindowText(GetDlgItem(fhPanel, IDC_NUM_TARGS), buf);
// Enable the forward/back buttons if there are multiple targets
BOOL useButtons = (numTargs > 1);
EnableWindow(GetDlgItem(fhPanel, IDC_BACK), useButtons);
EnableWindow(GetDlgItem(fhPanel, IDC_FORWARD), useButtons);
//
// Add the component rollups
//
if (fCurComponent)
fCurComponent->CreateRollups();
}
void plComponentUtil::IDestroyRollups()
{
if (fCurComponent)
fCurComponent->DestroyRollups();
}
void plComponentUtil::INextTarget(bool forward)
{
// fCurComponent = IGetListSelection();
// plComponentBase *comp = fCurComponent->ConvertToComponent();
// Loop through the selected component's targets until we find the currently selected node.
// This gives us a starting point to find the next or previous target in this component's list.
plMaxNode *curNode = (plMaxNode*)GetCOREInterface()->GetSelNode(0);
UInt32 count = fCurComponent->NumTargets();
for (UInt32 i = 0; i < count; i++)
{
if (fCurComponent->GetTarget(i) == curNode)
{
// Got to loop until the target is non-nil here, so we skip over
// any deleted nodes.
UInt32 targIdx = i;
do
{
// Figure out which target to change to
if (forward)
{
if (targIdx == count-1)
targIdx = 0;
else
targIdx = targIdx + 1;
}
else
{
if (targIdx == 0)
targIdx = count-1;
else
targIdx = targIdx - 1;
}
} while (!fCurComponent->GetTarget(targIdx));
// Select the new target
theHold.Begin();
fInterface->RedrawViews(fInterface->GetTime(), REDRAW_BEGIN);
fInterface->SelectNode(fCurComponent->GetTarget(targIdx));
fInterface->RedrawViews(fInterface->GetTime(), REDRAW_END);
theHold.Accept("Select");
return;
}
}
}
void plComponentUtil::IUpdateNodeName(plMaxNode *node)
{
if (!fhPanel)
return;
// Update the name in the list
int idx = IFindListItem(node->ConvertToComponent());
if (idx != -1)
{
HWND hList = GetDlgItem(fhPanel, IDC_COMPLIST);
ListView_SetItemText(hList, idx, 0, node->GetName());
// Make sure the column is wide enough
ListView_SetColumnWidth(hList, 0, LVSCW_AUTOSIZE);
}
}
void plComponentUtil::IComponentPreDelete(plComponentBase* comp)
{
if (fCurComponent == comp)
{
IDestroyRollups();
fCurComponent = nil;
}
}
////////////////////////////////////////////////////////////////////////////////
#include <vector>
void IGetReferencesRecur(plMaxNode* node, INode* target, std::vector<plMaxNode*>& nodes)
{
plComponentBase* comp = node->ConvertToComponent();
if (comp && comp->DoReferenceNode(target))
{
const char* name = node->GetName();
nodes.push_back(node);
}
for (int i = 0; i < node->NumberOfChildren(); i++)
{
IGetReferencesRecur((plMaxNode*)node->GetChildNode(i), target, nodes);
}
}
BOOL CALLBACK RefDlgProc(HWND hDlg, UINT msg, WPARAM wParam, LPARAM lParam)
{
switch (msg)
{
case WM_INITDIALOG:
{
if (GetCOREInterface()->GetSelNodeCount() > 0)
{
INode* node = GetCOREInterface()->GetSelNode(0);
char buf[256];
sprintf(buf, "%s is Ref'd By", node->GetName());
SetWindowText(hDlg, buf);
std::vector<plMaxNode*> nodes;
IGetReferencesRecur((plMaxNode*)GetCOREInterface()->GetRootNode(), node, nodes);
HWND hList = GetDlgItem(hDlg, IDC_REF_LIST);
for (int i = 0; i < nodes.size(); i++)
{
plMaxNode* node = nodes[i];
int idx = ListBox_AddString(hList, node->GetName());
ListBox_SetItemData(hList, idx, node);
}
}
}
return TRUE;
case WM_COMMAND:
if (HIWORD(wParam) == BN_CLICKED && LOWORD(wParam) == IDC_CLOSE)
{
EndDialog(hDlg, 0);
return TRUE;
}
else if (HIWORD(wParam) == LBN_DBLCLK && LOWORD(wParam) == IDC_REF_LIST)
{
// If the user double clicked on a component, return it so we can
// select the nodes it's attached to
HWND hList = HWND(lParam);
int sel = ListBox_GetCurSel(hList);
LRESULT node = ListBox_GetItemData(hList, sel);
EndDialog(hDlg, node);
return TRUE;
}
break;
}
return FALSE;
}
void plComponentUtil::IShowRefdBy()
{
INode* node = (INode*)DialogBox(hInstance,
MAKEINTRESOURCE(IDD_REF_BY),
GetCOREInterface()->GetMAXHWnd(),
RefDlgProc);
if (node)
{
INodeTab nodes;
nodes.Append(1, &node);
plComponentDlg::Instance().SelectComponentTargs(nodes);
}
}

View File

@ -0,0 +1,92 @@
/*==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 "max.h"
#include "utilapi.h"
#include "notify.h"
class plMaxNode;
class plComponentBase;
class plComponentUtil : public UtilityObj
{
protected:
friend class plComponentDlg;
Interface *fInterface;
HWND fhPanel;
plComponentBase* fCurComponent;
// Used to try and load the last displayed component on reload, just for pointer compares
plComponentBase* fLastComponent;
plComponentUtil();
public:
static plComponentUtil& Instance();
void BeginEditParams(Interface *ip, IUtil *iu);
void EndEditParams(Interface *ip, IUtil *iu);
void SelectionSetChanged(Interface *ip, IUtil *iu);
void DeleteThis() {};
static BOOL CALLBACK ForwardDlgProc(HWND hDlg, UINT msg, WPARAM wParam, LPARAM lParam);
BOOL DlgProc(HWND hDlg, UINT msg, WPARAM wParam, LPARAM lParam);
bool IsOpen() { return (fhPanel != NULL); }
protected:
void IUpdateRollups();
void IAddRollups(plComponentBase* comp);
void IDestroyRollups();
void INextTarget(bool forward);
plComponentBase *IGetListSelection();
void IDeleteListSelection();
int IFindListItem(plComponentBase* comp);
void IShowRefdBy();
// plComponentDlg is about to delete this comp, get rid of it's interface
void IComponentPreDelete(plComponentBase* comp);
// To syncronize with plComponentDlg when a name is changed
void IUpdateNodeName(plMaxNode *node);
};

View File

@ -0,0 +1,195 @@
/*==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 "HeadSpin.h"
#include "plGetLocationDlg.h"
#include "plMaxNode.h"
#include "../MaxComponent/plMiscComponents.h"
#include "resource.h"
#include "../MaxExport/plErrorMsg.h"
#include "../MaxComponent/plComponent.h"
#include "hsUtils.h"
plGetLocationDlg::plGetLocationDlg() : fNode(nil), fErrMsg(nil), fDefaultLocation(nil)
{
}
plGetLocationDlg& plGetLocationDlg::Instance()
{
static plGetLocationDlg theInstance;
return theInstance;
}
bool plGetLocationDlg::GetLocation(plMaxNode *node, plErrorMsg *errMsg)
{
fNode = node;
fErrMsg = errMsg;
// If an XRef doesn't have a location, tell the user and stop the export
if (node->IsXRef())
{
char buf[256];
sprintf(buf, "XRef object \"%s\" does not have a location", node->GetName());
fErrMsg->Set(true, "Convert Error", buf).Show();
return false;
}
// If we have a default location, use it and exit
if (fDefaultLocation)
{
ISetLocation(fDefaultLocation);
return true;
}
// If we're not showing prompts, just fail if there isn't a location
if (hsMessageBox_SuppressPrompts)
{
fErrMsg->Set(true, "Convert Error", "Object %s doesn't have a location component", node->GetName());
fErrMsg->Show();
return false;
}
int ret = DialogBox(hInstance,
MAKEINTRESOURCE(IDD_GET_LOCATION),
GetCOREInterface()->GetMAXHWnd(),
ForwardDlgProc);
return (ret != 0);
}
void plGetLocationDlg::ResetDefaultLocation()
{
fDefaultLocation = nil;
}
void plGetLocationDlg::IListRooms(plMaxNode *node, HWND hList)
{
// If node is a room component, add it's name to the list
plComponentBase *comp = node->ConvertToComponent();
if(comp && (comp->ClassID() == ROOM_CID || comp->ClassID() == PAGEINFO_CID))
{
int idx = SendMessage(hList, LB_ADDSTRING, 0, (LPARAM)node->GetName());
SendMessage(hList, LB_SETITEMDATA, idx, (LPARAM)node);
}
// Recursively add all the nodes children
for (int i = 0; i < node->NumberOfChildren(); i++)
IListRooms((plMaxNode*)node->GetChildNode(i), hList);
}
void plGetLocationDlg::IAddSelection(HWND hList, bool setDefault)
{
int sel = SendMessage(hList, LB_GETCURSEL, 0, 0);
if (sel != LB_ERR)
{
// Get the node and component for the selected room component
plMaxNode *node = (plMaxNode*)SendMessage(hList, LB_GETITEMDATA, sel, 0);
ISetLocation(node);
if (setDefault)
fDefaultLocation = node;
}
}
void plGetLocationDlg::ISetLocation(plMaxNode *locNode)
{
plComponent *comp = (plComponent*)locNode->ConvertToComponent();
// Add the roomless node to the target list and run the convert pass that gives it a room
comp->AddTarget(fNode); // Might want to fix this...
comp->SetupProperties(fNode, nil);
}
INT_PTR plGetLocationDlg::ForwardDlgProc(HWND hDlg, UINT msg, WPARAM wParam, LPARAM lParam)
{
return Instance().DlgProc(hDlg, msg, wParam, lParam);
}
INT_PTR plGetLocationDlg::DlgProc(HWND hDlg, UINT msg, WPARAM wParam, LPARAM lParam)
{
switch (msg)
{
case WM_INITDIALOG:
{
HWND hList = GetDlgItem(hDlg, IDC_LIST_LOC);
SendMessage(hList, LB_RESETCONTENT, 0, 0);
IListRooms((plMaxNode*)GetCOREInterface()->GetRootNode(), hList);
// Set the prompt text
char buf[256];
sprintf(buf, "The object \"%s\" does not have a location. Either pick a location and press OK, or press Cancel to stop the convert.", fNode->GetName());
SetDlgItemText(hDlg, IDC_PROMPT, buf);
// No room components found. Tell user to create one and cancel convert.
if (SendMessage(hList, LB_GETCOUNT, 0, 0) == 0)
{
fErrMsg->Set(true, "Convert Error", "No location component found. Create one and convert again.");
fErrMsg->Show();
EndDialog(hDlg, 0);
}
// Else set the first room as the current selection
else
SendMessage(hList, LB_SETCURSEL, 0, 0);
}
return TRUE;
case WM_COMMAND:
switch (LOWORD(wParam))
{
case IDOK:
{
bool setDefault = (IsDlgButtonChecked(hDlg, IDC_CHECK_DEFAULT) == BST_CHECKED);
IAddSelection(GetDlgItem(hDlg, IDC_LIST_LOC), setDefault);
EndDialog(hDlg, 1);
}
return TRUE;
case IDCANCEL:
// Stop the convert. No message since they know they canceled.
fErrMsg->Set(true);
EndDialog(hDlg, 0);
return TRUE;
}
break;
}
return FALSE;
}

View File

@ -0,0 +1,70 @@
/*==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 "hsWindows.h"
class plErrorMsg;
class plMaxNode;
class plGetLocationDlg
{
protected:
plMaxNode *fNode;
plErrorMsg *fErrMsg;
plMaxNode *fDefaultLocation;
public:
static plGetLocationDlg& Instance();
bool GetLocation(plMaxNode *node, plErrorMsg *errMsg);
// This should be called at the start of each convert to prevent any
// problems with bad pointers
void ResetDefaultLocation();
protected:
plGetLocationDlg();
void IListRooms(plMaxNode *node, HWND hList);
void IAddSelection(HWND hList, bool setDefault);
void ISetLocation(plMaxNode *locNode);
static INT_PTR CALLBACK ForwardDlgProc(HWND hDlg, UINT msg, WPARAM wParam, LPARAM lParam);
INT_PTR DlgProc(HWND hDlg, UINT msg, WPARAM wParam, LPARAM lParam);
};

View File

@ -0,0 +1,62 @@
/*==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 "HeadSpin.h"
#include "max.h"
#include "plMaxAccelerators.h"
int plMaxAccelerators::fNumDisables = 0;
void plMaxAccelerators::Enable()
{
fNumDisables--;
if (fNumDisables <= 0)
EnableAccelerators();
}
void plMaxAccelerators::Disable()
{
fNumDisables++;
if (fNumDisables > 0)
DisableAccelerators();
}

View File

@ -0,0 +1,50 @@
/*==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==*/
class plMaxAccelerators
{
protected:
static int fNumDisables;
public:
static void Enable();
static void Disable();
};

View File

@ -0,0 +1,119 @@
/*==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 "HeadSpin.h"
#include "plMaxCFGFile.h"
#include "max.h"
#include "hsTypes.h"
#include "../plFile/plBrowseFolder.h"
const char *plMaxConfig::GetPluginIni()
{
// Get the plugin CFG dir
static char plugDir[MAX_PATH];
strcpy(plugDir, GetCOREInterface()->GetDir(APP_PLUGCFG_DIR));
strcat(plugDir, "\\PlasmaMAX2.ini");
return plugDir;
}
const char *plMaxConfig::GetClientPath(bool getNew, bool quiet)
{
static char plasmaPath[MAX_PATH];
plasmaPath[0] = '\0';
// Get the plugin CFG dir
const char *plugDir = GetPluginIni();
// Get the saved path
UInt32 len = GetPrivateProfileString("SceneViewer", "Directory", "", plasmaPath, MAX_PATH, plugDir);
// If we didn't find a path, or we want a new one, ask the user for one
if ((len == 0 || getNew) && !quiet)
{
// If the user selects one, save it
if (plBrowseFolder::GetFolder(plasmaPath, plasmaPath, "Specify your client folder"))
WritePrivateProfileString("SceneViewer", "Directory", plasmaPath, plugDir);
}
// Return the path if we got one
if (plasmaPath[0] != '\0')
{
// Make sure the path ends with a slash
char lastChar = plasmaPath[strlen(plasmaPath)-1];
if (lastChar != '/' && lastChar != '\\')
strcat(plasmaPath, "\\");
return plasmaPath;
}
return nil;
}
void plMaxConfig::SetClientPath(const char *path)
{
const char *plugDir = GetPluginIni();
WritePrivateProfileString("SceneViewer", "Directory", path, plugDir);
}
bool plMaxConfig::AssetManInterfaceDisabled()
{
static bool inited = false;
static bool disabled = false;
if (!inited)
{
char configstr[MAX_PATH];
configstr[0] = '\0';
const char *plugDir = GetPluginIni();
UInt32 len = GetPrivateProfileString("AssetMan", "Disable", "", configstr, MAX_PATH, plugDir);
if (strcmp(configstr, "1") == 0 || stricmp(configstr, "true") == 0)
disabled = true;
else
disabled = false;
inited = true;
}
return disabled;
}

View File

@ -0,0 +1,57 @@
/*==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==*/
namespace plMaxConfig
{
// Get the full path to the ini file to write settings to
const char *GetPluginIni();
// Gets the path to the Plasma working directory
// If the user hasn't set one before, it prompts them to
// Set getNew to true to force the user to set a new path
// If a path is returned, it will end with a slash
const char *GetClientPath(bool getNew=false, bool quiet=false);
// For the rare case where you need to set the client path manually
void SetClientPath(const char *path);
// option to disable the plugin's assetman interface
bool AssetManInterfaceDisabled();
}

View File

@ -0,0 +1,447 @@
/*==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 "HeadSpin.h"
#include "max.h"
#include "iMenuMan.h"
#include "plMaxMenu.h"
#include "plActionTableMgr.h"
#include "resource.h"
#include "plSaveSelected.h"
#include "plComponentDlg.h"
#include "plMaxCFGFile.h"
#include "plResCollector.h"
#include "plAgeDescInterface.h"
#include "../MaxSceneViewer/SceneViewer.h"
#include "plNodeLock.h"
#include "plResetXform.h"
#include "plTextureSearch.h"
#include "../MaxExport/plExportDlg.h"
// ************************* action table
//
// random id to identify an action table and context
const ActionTableId kActionId = 0x54162b7c;
enum
{
kActionSaveSel,
kActionMerge,
kActionComponent,
kActionResCollect,
kActionAgeDesc,
kActionCompCopy,
kActionSceneViewer,
kActionLock,
kActionUnlock,
kActionTexSearch,
kActionReset,
kActionSelectNonRenderables,
kActionExport,
};
static ActionDescription spActions[] =
{
{
kActionSaveSel, // ActionId identifies action for callback execution (within table)
IDS_ACT1_DESC, // Action description for display in ui customization
IDS_ACT1_NAME, // Action name for display on menu
IDS_ACT_CAT // Action category for ui customization
},
{
kActionMerge,
IDS_ACT2_DESC,
IDS_ACT2_NAME,
IDS_ACT_CAT
},
{
kActionComponent,
IDS_ACT3_NAME,
IDS_ACT3_NAME,
IDS_ACT_CAT
},
{
kActionResCollect,
IDS_ACT4_NAME,
IDS_ACT4_NAME,
IDS_ACT_CAT
},
{
kActionAgeDesc,
IDS_ACT5_NAME,
IDS_ACT5_NAME,
IDS_ACT_CAT
},
{
kActionCompCopy,
IDS_ACT6_NAME,
IDS_ACT6_NAME,
IDS_ACT_CAT
},
{
kActionSceneViewer,
IDS_ACT7_NAME,
IDS_ACT7_NAME,
IDS_ACT_CAT
},
{
kActionLock,
IDS_ACT8_DESC,
IDS_ACT8_NAME,
IDS_ACT_CAT
},
{
kActionUnlock,
IDS_ACT9_DESC,
IDS_ACT9_NAME,
IDS_ACT_CAT
},
{
kActionTexSearch,
IDS_ACT10_NAME,
IDS_ACT10_NAME,
IDS_ACT_CAT
},
{
kActionReset,
IDS_ACT11_DESC,
IDS_ACT11_NAME,
IDS_ACT_CAT
},
{
kActionSelectNonRenderables,
IDS_ACT12_DESC,
IDS_ACT12_NAME,
IDS_ACT_CAT
},
{
kActionExport,
IDS_PLASMA_EXPORT,
IDS_PLASMA_EXPORT,
IDS_ACT_CAT
}
};
// callback for action exection
bool DoAction(int id)
{
switch(id)
{
case kActionSaveSel:
plSaveSelected();
return true;
case kActionMerge:
plMerge();
return true;
case kActionComponent:
plComponentDlg::Instance().Open();
return true;
case kActionResCollect:
plResCollector::Collect();
return true;
case kActionAgeDesc:
plAgeDescInterface::Instance().Open();
return true;
case kActionCompCopy:
CopyComponents();
return true;
case kActionSceneViewer:
SceneViewer::Instance().Show();
return true;
case kActionLock:
plNodeLock().Lock();
return true;
case kActionUnlock:
plNodeLock().Unlock();
return true;
case kActionTexSearch:
plTextureSearch::Instance().Toggle();
return true;
case kActionReset:
plResetXform().ResetSelected();
return true;
case kActionSelectNonRenderables:
plSelectNonRenderables().SelectNonRenderables();
return true;
case kActionExport:
plExportDlg::Instance().Show();
return true;
}
return false;
}
static ActionTableInfo actionInfo(kActionId, "Plasma", spActions, sizeof(spActions) / sizeof(ActionDescription));
// static or global declaration of action table manager
plActionTableMgr theActionTableMgr(actionInfo, DoAction);
//
// ************************* end action table
//////////////////////////////////////////////////////////////////////////////
// Menu Creation Junk
MenuContextId kMyMenuContextId=0xcff95f6c; //<random number>
static char *kMenuName = "Plasma";
static int kMenuVersion = 10; // Increment this number if you add an entry to the menu
extern TCHAR *GetString(int id);
void AddPlasmaExportMenu()
{
IMenuManager* pMenuMan = GetCOREInterface()->GetMenuManager();
IMenu* fileMenu = pMenuMan->FindMenu("&File");
int i;
bool plasmaExportFound = false;
// Make sure our action isn't already in the menu
TSTR ourName = GetString(IDS_PLASMA_EXPORT);
for (i = 0; i < fileMenu->NumItems(); i++)
{
IMenuItem* fileMenuItem = fileMenu->GetItem(i);
const TSTR& title = fileMenuItem->GetTitle();
if (title == ourName)
plasmaExportFound = true;
// KLUDGE - MaxAss didn't define the file submenu with an accelerator.
// This fixes it.
if (title == "MAX File Operations")
{
fileMenuItem->SetUseCustomTitle(true);
bool custom = fileMenuItem->GetUseCustomTitle();
fileMenuItem->SetTitle("MAX File Opera&tions");
pMenuMan->UpdateMenuBar();
}
}
if (!plasmaExportFound)
{
// Menu item isn't there, add it
for (i = 0; i < fileMenu->NumItems(); i++)
{
IMenuItem* fileMenuItem = fileMenu->GetItem(i);
const TSTR& title = fileMenuItem->GetTitle();
// We want to add it after the "Export Selected" menu item
if (title == "Export Selected...")
{
ActionTable* pActionTable = GetCOREInterface()->GetActionManager()->FindTable(kActionId);
if (!pActionTable)
{
hsAssert(0, "Action table not found");
return;
}
IMenuItem* menuItem = GetIMenuItem();
menuItem->SetActionItem(pActionTable->GetAction(kActionExport));
fileMenu->AddItem(menuItem, i+1);
pMenuMan->UpdateMenuBar();
return;
}
}
}
}
void plCreateMenu()
{
AddPlasmaExportMenu();
IMenuManager* pMenuMan = GetCOREInterface()->GetMenuManager();
bool newlyRegistered = pMenuMan->RegisterMenuBarContext(kMyMenuContextId, kMenuName);
// Is the Max menu version the most recent?
bool wrongVersion = GetPrivateProfileInt("Menu", "Version", 0, plMaxConfig::GetPluginIni()) < kMenuVersion;
if (wrongVersion)
{
// Delete the old version of the menu
IMenu *oldMenu = pMenuMan->FindMenu(kMenuName);
if (oldMenu)
pMenuMan->UnRegisterMenu(oldMenu);
// Update the menu version
char buf[30];
WritePrivateProfileString("Menu", "Version", itoa(kMenuVersion, buf, 10), plMaxConfig::GetPluginIni());
}
if (wrongVersion || newlyRegistered)
{
IMenu *pMainMenu = pMenuMan->GetMainMenuBar();
if (!pMainMenu)
{
hsAssert(0, "Main menu not found");
return;
}
// Get our action table
ActionTable* pActionTable = GetCOREInterface()->GetActionManager()->FindTable(kActionId);
if (!pActionTable)
{
hsAssert(0, "Action table not found");
return;
}
// Create the Plasma menu
IMenu* pPlasmaMenu = GetIMenu();
pPlasmaMenu->SetTitle(kMenuName);
// Register the new menu with the system
pMenuMan->RegisterMenu(pPlasmaMenu, 0);
/////////////////////////////////////////////////
// Add the menu items
//
// Add the save selected action to the menu
IMenuItem* pMenuItem = GetIMenuItem();
pMenuItem->SetActionItem(pActionTable->GetAction(kActionSaveSel));
pPlasmaMenu->AddItem(pMenuItem);
// Add the merge action to the menu
pMenuItem = GetIMenuItem();
pMenuItem->SetActionItem(pActionTable->GetAction(kActionMerge));
pPlasmaMenu->AddItem(pMenuItem);
// Add the component copy action to the menu
pMenuItem = GetIMenuItem();
pMenuItem->SetActionItem(pActionTable->GetAction(kActionCompCopy));
pPlasmaMenu->AddItem(pMenuItem);
// Add a separator
pMenuItem = GetIMenuItem();
pMenuItem->ActAsSeparator();
pPlasmaMenu->AddItem(pMenuItem);
// Add the component manager to the menu
pMenuItem = GetIMenuItem();
pMenuItem->SetActionItem(pActionTable->GetAction(kActionComponent));
pPlasmaMenu->AddItem(pMenuItem);
// Add the resource collector to the menu
pMenuItem = GetIMenuItem();
pMenuItem->SetActionItem(pActionTable->GetAction(kActionResCollect));
pPlasmaMenu->AddItem(pMenuItem);
// Add the texture search to the menu
pMenuItem = GetIMenuItem();
pMenuItem->SetActionItem(pActionTable->GetAction(kActionTexSearch));
pPlasmaMenu->AddItem(pMenuItem);
// Add the age description to the menu
pMenuItem = GetIMenuItem();
pMenuItem->SetActionItem(pActionTable->GetAction(kActionAgeDesc));
pPlasmaMenu->AddItem(pMenuItem);
// Add a separator
pMenuItem = GetIMenuItem();
pMenuItem->ActAsSeparator();
pPlasmaMenu->AddItem(pMenuItem);
// Add the SceneViewer to the menu
pMenuItem = GetIMenuItem();
pMenuItem->SetActionItem(pActionTable->GetAction(kActionSceneViewer));
pPlasmaMenu->AddItem(pMenuItem);
// Add a separator
pMenuItem = GetIMenuItem();
pMenuItem->ActAsSeparator();
pPlasmaMenu->AddItem(pMenuItem);
// Add the Lock Selected to the menu
pMenuItem = GetIMenuItem();
pMenuItem->SetActionItem(pActionTable->GetAction(kActionLock));
pPlasmaMenu->AddItem(pMenuItem);
// Add the Unlock Selected to the menu
pMenuItem = GetIMenuItem();
pMenuItem->SetActionItem(pActionTable->GetAction(kActionUnlock));
pPlasmaMenu->AddItem(pMenuItem);
// Add the Reset Selected to the menu
pMenuItem = GetIMenuItem();
pMenuItem->SetActionItem(pActionTable->GetAction(kActionReset));
pPlasmaMenu->AddItem(pMenuItem);
// Add the SelectNonRenderables to the menu
pMenuItem = GetIMenuItem();
pMenuItem->SetActionItem(pActionTable->GetAction(kActionSelectNonRenderables));
pPlasmaMenu->AddItem(pMenuItem);
// Create a new menu item to hold the sub-menu
IMenuItem* pSubMenuItem1 = GetIMenuItem(); //menu in menu bar...
pSubMenuItem1->SetSubMenu(pPlasmaMenu);
pMainMenu->AddItem(pSubMenuItem1);
pMenuMan->UpdateMenuBar();
// Save the dang menu, in case Max crashes
const char *uiDir = GetCOREInterface()->GetDir(APP_UI_DIR);
char path[MAX_PATH];
sprintf(path, "%s\\%s", uiDir, "MaxMenus.mnu");
pMenuMan->SaveMenuFile(path);
}
}
// End Menu Creation Junk
//////////////////////////////////////////////////////////////////////////////

View File

@ -0,0 +1,47 @@
/*==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==*/
#ifndef __MENUTESTUTIL__H
#define __MENUTESTUTIL__H
void plCreateMenu();
#endif // __MENUTESTUTIL__H

View File

@ -0,0 +1,238 @@
/*==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 "plMaxMeshExtractor.h"
#include "Max.h"
#include "plMaxNode.h"
#include "dummy.h"
static Mesh* ExtractMesh(INode* pNode, TriObject** ppDeleteMe)
{
Object *obj = pNode->EvalWorldState(0).obj;
Mesh *pRetMesh = nil;
if( obj ) {
if( obj->CanConvertToType(triObjectClassID) ) {
// Convert to triangle object
TriObject *tri = (TriObject*)obj->ConvertToType(0, triObjectClassID);
if (tri != obj) *ppDeleteMe = tri; // if Convert allocated, pass back so caller can delete.
if( tri ) {
Mesh *pTMesh = &tri->mesh;
if( pTMesh->getNumFaces() ) {
pRetMesh = pTMesh;
}
}
}
}
return pRetMesh;
}
// Return the two points defining the bounding box for the given vertices.
static void MeshMinMax(hsPoint3& min, hsPoint3& max, int numVerts, hsPoint3* pVerts)
{
for (int i = 0; i < numVerts; i++)
{
hsPoint3* vert = &pVerts[i];
min.fX = hsMinimum(vert->fX, min.fX);
min.fY = hsMinimum(vert->fY, min.fY);
min.fZ = hsMinimum(vert->fZ, min.fZ);
max.fX = hsMaximum(vert->fX, max.fX);
max.fY = hsMaximum(vert->fY, max.fY);
max.fZ = hsMaximum(vert->fZ, max.fZ);
}
}
static bool MakeNormalMesh(plMaxNode *node, plMaxMeshExtractor::NeutralMesh& mesh, Matrix3* w2l)
{
TriObject *pDeleteMe = nil;
Mesh *pMesh = ExtractMesh(node, &pDeleteMe); // allocates *sometimes*; check pDeleteMe
if (!pMesh)
return false;
Matrix3 fullTM = node->GetObjectTM(0);
int parity = fullTM.Parity();
mesh.fNumVerts = pMesh->numVerts;
mesh.fVerts = TRACKED_NEW hsPoint3[mesh.fNumVerts];
for (int i = 0; i < mesh.fNumVerts; i++)
{
// convert the vertex to global coordinates
Point3 newVert = fullTM * pMesh->verts[i];
// convert the vertex to the new (requested) coordinate system
if (w2l)
newVert = (*w2l) * newVert;
mesh.fVerts[i].Set(newVert.x, newVert.y, newVert.z);
}
mesh.fNumFaces = pMesh->numFaces;
mesh.fFaces = TRACKED_NEW UInt16[mesh.fNumFaces*3];
for (int i = 0; i < mesh.fNumFaces; i++)
{
Face* pFace = &pMesh->faces[i];
UInt16* pNFace = &mesh.fFaces[i * 3];
pNFace[0] = pFace->v[ parity ? 2 : 0 ]; // reverse winding if parity backwards
pNFace[1] = pFace->v[1];
pNFace[2] = pFace->v[ parity ? 0 : 2 ]; // ''
}
if (pDeleteMe)
delete pDeleteMe;
return true;
}
// BUILDBOXMESH
// Build the minimum bounding box (triangles and all) enclosing the given vertices
// DELETES the given vertex and face array
// ALLOCATES a new vertex and face array
// MODIFIES *all* the input parameters.
static void MakeBoxMesh(plMaxNode* node, plMaxMeshExtractor::NeutralMesh& mesh, hsPoint3& minV, hsPoint3& maxV)
{
hsPoint3* newVerts = TRACKED_NEW hsPoint3[8];
UInt16* newFaces = TRACKED_NEW UInt16[12 * 3];
newVerts[0].Set(minV.fX, minV.fY, minV.fZ);
newVerts[1].Set(maxV.fX, minV.fY, minV.fZ);
newVerts[2].Set(minV.fX, maxV.fY, minV.fZ);
newVerts[3].Set(maxV.fX, maxV.fY, minV.fZ);
newVerts[4].Set(minV.fX, minV.fY, maxV.fZ);
newVerts[5].Set(maxV.fX, minV.fY, maxV.fZ);
newVerts[6].Set(minV.fX, maxV.fY, maxV.fZ);
newVerts[7].Set(maxV.fX, maxV.fY, maxV.fZ);
UInt16 standardFaces[] = { 0, 2, 1,
1, 2, 3,
0, 1, 4,
1, 5, 4,
0, 4, 2,
2, 4, 6,
1, 3, 7,
7, 5, 1,
3, 2, 7,
2, 6, 7,
4, 7, 6,
4, 5, 7 };
memcpy(newFaces, standardFaces, sizeof(standardFaces));
delete [] mesh.fVerts;
mesh.fVerts = newVerts;
delete [] mesh.fFaces;
mesh.fFaces = newFaces;
mesh.fNumVerts = 8;
mesh.fNumFaces = 12;
}
static void MakeDummyMesh(plMaxNode* node, plMaxMeshExtractor::NeutralMesh& mesh)
{
hsPoint3 minV, maxV;
Object* thisObj = node->GetObjectRef();
DummyObject* thisDummy = (DummyObject*)thisObj;
Box3 thisBoundSurface = thisDummy->GetBox();
minV.fX = thisBoundSurface.Min().x;
minV.fY = thisBoundSurface.Min().y;
minV.fZ = thisBoundSurface.Min().z;
maxV.fX = thisBoundSurface.Max().x;
maxV.fY = thisBoundSurface.Max().y;
maxV.fZ = thisBoundSurface.Max().z;
MakeBoxMesh(node, mesh, minV, maxV);
}
// CREATEPLHKPHYSICALFROMMESHEASY
// Convenience function for getting from a max node to a plHKPhysical and the requisite
// Havok objects.
// The node and the scene object don't have to correspond to the same Max object.
// If the sAltNode is supplied, the node will be moved into the coordinate system of the
bool plMaxMeshExtractor::Extract(plMaxMeshExtractor::NeutralMesh& mesh, plMaxNode* node, bool makeAABB, plMaxNode* sOwningNode)
{
mesh.fNumVerts = mesh.fNumFaces = 0;
mesh.fVerts = nil;
mesh.fFaces = nil;
// if an alternate node was supplied, get its scene object. otherwise don't...
plMaxNode* masterNode = sOwningNode ? sOwningNode : node;
mesh.fL2W = masterNode->GetLocalToWorld44();
//
// Create the arrays of verts and faces
//
hsBool isDummy = (node->EvalWorldState(0).obj->ClassID() == Class_ID(DUMMY_CLASS_ID,0));
if (isDummy)
{
hsMatrix44 w2l = masterNode->GetWorldToLocal44();
MakeDummyMesh(node, mesh);
// Localize the verts
//for (int i = 0; i < mesh.fNumVerts; i++)
// mesh.fVerts[i] = w2l * mesh.fVerts[i];
}
else
{
// only get the max world-to-local transform if the node is moveable or instanced. otherwise verts stay global.
Matrix3 w2l = masterNode->GetWorldToLocal();
// Matrix3 *localizer = nil;
// if (masterNode->IsMovable() || masterNode->GetForceLocal() || masterNode->GetInstanced())
// localizer = &w2l;
if (!MakeNormalMesh(node, mesh, &w2l))
return false;
if (makeAABB)
{
hsPoint3 minV(FLT_MAX, FLT_MAX, FLT_MAX), maxV(-FLT_MAX, -FLT_MAX, -FLT_MAX);
MeshMinMax(minV, maxV, mesh.fNumVerts, mesh.fVerts);
MakeBoxMesh(node, mesh, minV, maxV);
}
}
return true;
}

View File

@ -0,0 +1,68 @@
/*==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==*/
#ifndef plMaxMeshExtractor_h_inc
#define plMaxMeshExtractor_h_inc
#include "hsTypes.h"
#include "hsMatrix44.h"
class plMaxNode;
class plMaxMeshExtractor
{
public:
struct NeutralMesh
{
int fNumVerts;
hsPoint3* fVerts;
int fNumFaces;
UInt16* fFaces;
hsMatrix44 fL2W;
};
// Converts a max node into a position, rotation, and arrays of verts and faces
// relative to those.
static bool Extract(NeutralMesh& mesh, plMaxNode* pNode, bool makeAABB = false, plMaxNode* sOwningNode = nil);
};
#endif // plMaxMeshExtractor_h_inc

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,261 @@
/*==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==*/
#ifndef plMaxNode_inc
#define plMaxNode_inc
#include "plMaxNodeBase.h"
#include "hsTemplates.h"
#include "hsMatrix44.h"
#include "iparamb2.h"
#include "../pnKeyedObject/plKey.h"
#include <map>
class plMaxNode;
class plErrorMsg;
class plConvertSettings;
class plExportProgressBar;
class plSceneNode;
class plDrawable;
class plDrawInterface;
class plDrawableSpans;
class plLightInfo;
class plSpotLightInfo;
class plOmniLightInfo;
class plGeometrySpan;
class ISkin;
class plSpotModifier;
class plOmniModifier;
class plLtdDirModifier;
class plLightModifier;
class plController;
class plAGModifier;
class plAGMasterMod;
class plAGAnim;
class plRenderLevel;
class plDrawableCriteria;
class plXImposterComp;
class plPhysicalProps;
class plLightMapComponent;
class plPageInfoComponent;
class plMaxBoneMap;
class plSynchedObject;
typedef hsBool (plMaxNode:: *PMaxNodeFunc) (plErrorMsg *, plConvertSettings *); // Function pointer to a plMaxNode member funtion
class plMaxNodeTab : public Tab<plMaxNode*>
{
};
//-------------------------------------------
// plMaxNode
//-------------------------------------------
// CAREFUL! This class is different, it is derived from Max's INode (as you can see)
// But we can only add (NON Virtual) functions to plMaxNode directly
// If you want some new Data members, you can add them by adding to the class
// plMaxNodeData This data is stored in each INode through some mechanisms supplied
// It would be nice of you to add GetFunctions for each new data member you add (see below)
//--------------------------------------------
// NOTE: an INode can be cast to a plMaxNode, but currently it is the MakeSceneObject Pass which
// Adds the plMaxNodeData to the Node
class plMaxNode : public plMaxNodeBase
{
public:
hsBool DoRecur(PMaxNodeFunc p,plErrorMsg *, plConvertSettings *, plExportProgressBar*);
hsBool DoAllRecur(PMaxNodeFunc p,plErrorMsg *, plConvertSettings *, plExportProgressBar*);
// DoRecur takes one of the following functions
hsBool ConvertValidate (plErrorMsg *, plConvertSettings *);
hsBool SetupPropertiesPass (plErrorMsg *, plConvertSettings *);
hsBool MakeSceneObject (plErrorMsg *, plConvertSettings *);
hsBool PrepareSkin (plErrorMsg *, plConvertSettings *);
hsBool MakePhysical (plErrorMsg *, plConvertSettings *);
hsBool FirstComponentPass (plErrorMsg *, plConvertSettings *);
hsBool MakeController (plErrorMsg *, plConvertSettings *);
hsBool MakeCoordinateInterface (plErrorMsg *, plConvertSettings *);
hsBool MakeModifiers (plErrorMsg *, plConvertSettings *);
hsBool MakeParentOrRoomConnection (plErrorMsg *, plConvertSettings *);
hsBool MakeMesh (plErrorMsg *, plConvertSettings *);
hsBool MakeLight (plErrorMsg *, plConvertSettings *);
hsBool MakeOccluder (plErrorMsg *, plConvertSettings *);
hsBool ConvertComponents (plErrorMsg *, plConvertSettings *);
hsBool ClearData (plErrorMsg *, plConvertSettings *);
hsBool ShadeMesh (plErrorMsg *, plConvertSettings *);
hsBool MakeIfaceReferences (plErrorMsg *, plConvertSettings *);
hsBool ClearMaxNodeData (plErrorMsg *, plConvertSettings *);
hsBool DeInitComponents (plErrorMsg *, plConvertSettings *);
// Does specified function for all components attached to this node
enum { kSetupProperties, kPreConvert, kConvert };
hsBool DoComponents(int convertType, plErrorMsg *, plConvertSettings *);
plKey AddModifier(plModifier *pMod, const char* name);
hsBool ConvertToOccluder (plErrorMsg* pErrMsg, hsBool twoSided, hsBool isHole);
plDrawableCriteria GetDrawableCriteria(hsBool needBlending, hsBool needSorting);
Point3 GetFlexibility(); // returns Point3(flexibility, interRand, intraRand).
plXImposterComp* GetXImposterComp();
int AlphaHackLayersNeeded(int iSubMtl);
int NumUVWChannels();
hsBool VtxAlphaNotAvailable();
hsBool NonVtxPreshaded();
TriObject* GetTriObject(hsBool& deleteIt);
plAGModifier* HasAGMod();
plAGMasterMod* GetAGMasterMod();
plMaxNode* GetBonesRoot(); // Returns the root of my bones hierarchy, if I have any bones, else nil.
void GetBonesRootsRecur(hsTArray<plMaxNode*>& list);
plSceneObject* MakeCharacterHierarchy(plErrorMsg *pErrMsg);
void SetupBonesAliasesRecur(const char *rootName);
void SetupBoneHierarchyPalette(plMaxBoneMap *bones = nil);
void SetDISceneNodeSpans( plDrawInterface *di, hsBool needBlending );
hsBool IsLegalDecal(hsBool checkParent = true);
bool IsAnimatedLight();
// These are public so the animation component can use them, no one else should need them
void GetRTLightColAnim(IParamBlock2* ProperPB, plAGAnim* anim);
void GetRTConeAnim(IParamBlock2* ProperPB, plAGAnim* anim);
void GetRTLightAttenAnim(IParamBlock2* ProperPB, plAGAnim* anim);
// This is used in the shading pass, where the lightmap component can
// serve as a cache for some shading info. Returns nil if there is no LightMapComponent on this.
plLightMapComponent* GetLightMapComponent();
// Starting at 0, returns an incrementing index for each maxNode. Useful for assigning
// indices to sound objects attached to the node
UInt32 GetNextSoundIdx( void );
hsBool IsPhysical( void );
hsBool CanMakeMesh( Object *obj, plErrorMsg *pErrMsg, plConvertSettings *settings );
plDrawInterface* GetDrawInterface(); // Returns nil if there isn't a sceneobject and a drawinterface.
// Only call during convert
plPhysicalProps *GetPhysicalProps();
// Little helper function. Calls FindKey() in the resManager using the location (page) of this node
plKey FindPageKey( UInt16 classIdx, const char *name );
char *GetAgeName();
void CheckSynchOptions(plSynchedObject* so);
protected:
INode *GetRootNode() { return GetInterface()->GetRootNode(); }
plDrawableSpans *IGetSceneNodeSpans( plSceneNode *node, hsBool needBlending, hsBool needSorting=true );
plLightInfo* IMakeDirectional(plErrorMsg* pErrMsg, plConvertSettings* settings);
plLightInfo* IMakeOmni(plErrorMsg* pErrMsg, plConvertSettings* settings);
plLightInfo* IMakeSpot(plErrorMsg* pErrMsg, plConvertSettings* settings);
hsBool IGetProjection(plLightInfo* li, plErrorMsg* pErrMsg);
plLightInfo* IMakeRTDirectional(plErrorMsg* pErrMsg, plConvertSettings* settings);
plLightInfo* IMakeRTOmni(plErrorMsg* pErrMsg, plConvertSettings* settings);
plLightInfo* IMakeRTSpot(plErrorMsg* pErrMsg, plConvertSettings* settings);
plLightInfo* IMakeRTProjDirectional( plErrorMsg *pErrMsg, plConvertSettings *settings );
void IGetCone(plSpotLightInfo* liInfo, LightObject* light, LightState& ls);
void IGetLightColors(plLightInfo* liInfo, LightObject* light, LightState& ls);
void IGetLightAttenuation(plOmniLightInfo* liInfo, LightObject* light, LightState& ls);
// RunTime Lights versions
void IGetRTCone(plSpotLightInfo* liInfo, IParamBlock2* ProperPB);
void IGetRTLightColors(plLightInfo* liInfo, IParamBlock2* ProperPB);
void IGetRTLightAttenuation(plOmniLightInfo* liInfo, IParamBlock2* ProperPB);
// RunTime Light animation builders
hsBool IGetRTLightAttenValues(IParamBlock2* ProperPB, hsScalar& attenConst, hsScalar& attenLinear, hsScalar& attenQuadratic,hsScalar &attenCutoff);
void IAdjustRTColorByIntensity(plController* ctl, IParamBlock2* ProperPB);
hsBool IAttachRTLightModifier(plLightModifier* liMod);
plLightInfo* IMakeLight(plErrorMsg *pErrMsg, plConvertSettings *settings);
plSceneNode* IGetDrawableSceneNode(plErrorMsg *pErrMsg);
void IAssignSpansToDrawables( hsTArray<plGeometrySpan *> &spanArray, plDrawInterface *di,
plErrorMsg *pErrMsg, plConvertSettings *settings );
void IAssignSpan( plDrawableSpans *drawable, hsTArray<plGeometrySpan *> &spanArray, UInt32 &index,
hsMatrix44 &l2w, hsMatrix44 &w2l,
plErrorMsg *pErrMsg, plConvertSettings *settings );
void ISetupBones( plDrawableSpans *drawable, hsTArray<plGeometrySpan *> &spanArray,
hsMatrix44 &l2w, hsMatrix44 &w2l,
plErrorMsg *pErrMsg, plConvertSettings *settings );
hsBool IFindBones(plErrorMsg *pErrMsg, plConvertSettings *settings);
void IWipeBranchDrawable(hsBool b);
UInt32 IBuildInstanceList( Object *obj, TimeValue t, hsTArray<plMaxNode *> &nodes, hsBool beMoreAccurate = false );
hsBool IMakeInstanceSpans( plMaxNode *node, hsTArray<plGeometrySpan *> &spanArray,
plErrorMsg *pErrMsg, plConvertSettings *settings );
hsBool IMaterialsMatch( plMaxNode *otherNode, hsBool beMoreAccurate );
int IGetCachedAlphaHackValue( int iSubMtl );
void ISetCachedAlphaHackValue( int iSubMtl, int value );
friend class plLocationDlg;
};
class plMaxBoneMap
{
protected:
typedef std::map<plMaxNodeBase*, UInt32> BoneMap;
BoneMap fBones;
typedef std::map<plDrawable*, UInt32> DrawableMap;
DrawableMap fBaseMatrices;
public:
UInt8 fNumBones;
plMaxNodeBase *fOwner; // Make note of which node created us, so they can delete us.
plMaxBoneMap() : fNumBones(0), fOwner(nil) {}
void AddBone(plMaxNodeBase *bone);
UInt8 GetIndex(plMaxNodeBase *bone);
void FillBoneArray(plMaxNodeBase **boneArray);
UInt32 GetBaseMatrixIndex(plDrawable *draw);
void SetBaseMatrixIndex(plDrawable *draw, UInt32 idx);
void SortBones();
};
#endif

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,315 @@
/*==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==*/
#ifndef plMaxNodeBase_inc
#define plMaxNodeBase_inc
#include "hsTypes.h"
#include "hsTemplates.h"
#include "max.h"
#include "hsMatrix44.h"
#include "hsColorRGBA.h"
#include "../pnKeyedObject/plKey.h"
#include "plLoadMask.h"
class plLocation;
class plSceneObject;
class plModifier;
class plComponentBase;
class ISkin;
class plMaxNodeData;
class hsGMesh;
class plRenderLevel;
class plGeometrySpan;
class plSharedMesh;
class plMaxBoneMap;
//-------------------------------------------
// plMaxNodeBase
//-------------------------------------------
// CAREFUL! This class is different, it is derived from Max's INode (as you can see)
// But we can only add (NON Virtual) functions to plMaxNodeBase directly
// If you want some new Data members, you can add them by adding to the class
// plMaxNodeData This data is stored in each INode through some mechanisms supplied
// It would be nice of you to add GetFunctions for each new data member you add (see below)
//--------------------------------------------
// NOTE: an INode can be cast to a plMaxNodeBase, but currently it is the MakeSceneObject Pass which
// Adds the plMaxNodeData to the Node
//
// This class should only reference classes that are in the nucleus. Anything
// that needs more should go into plMaxNode
class plMaxNodeBase : public INode
{
public:
plMaxNodeData *GetMaxNodeData(); // perhaps with full getters and Setters, we can make this protected
void SetMaxNodeData(plMaxNodeData * pDat);
//------------------------------
// Get Data from MaxNodeData
//------------------------------
// If recalculate is true the cached value is ignored. (Useful in the SceneViewer)
hsBool CanConvert(bool recalculate=false);
plLocation GetLocation();
plKey GetKey();
plSceneObject* GetSceneObject();
hsBool GetForceLocal();
hsBool GetReverseSort();
hsBool GetSortAsOpaque();
hsBool GetRunTimeLight();
hsBool GetForceMatShade();
hsBool GetForceVisLOS();
hsBool GetEnviron();
hsBool GetEnvironOnly();
hsBool GetWaterDecEnv();
hsBool GetVS();
hsBool GetHasWaterHeight();
hsScalar GetWaterHeight();
hsBool GetSmoothAll();
hsBool GetForceSortable();
hsBool GetConcave();
hsBool GetCalcEdgeLens();
hsBool GetNoPreShade();
hsBool GetForcePreShade();
plKey GetRoomKey();
hsBool GetDrawable();
hsBool GetPhysical();
hsBool GetItinerant();
hsBool GetUnBounded();
hsBool GetDisableNormal();
UInt32 GetDecalLevel();
hsBool GetMovable();
hsBool GetNoShadow();
hsBool GetForceShadow();
hsBool GetAlphaTestHigh();
hsBool GetFilterInherit();
hsBool GetIsBarney();
hsBool GetNoSpanSort();
hsBool GetNoSpanReSort();
hsBool GetNoFaceSort();
hsBool GetNoDeferDraw();
hsBool GetBlendToFB();
hsBool GetForceMaterialCopy();
hsBool GetInstanced();
hsBool GetParticleRelated();
UInt32 GetSoundIdxCounter();
plSceneObject* GetAvatarSO();
BOOL HasFade();
Box3 GetFade();
hsBool GetDup2Sided();
hsBool GetRadiateNorms();
BOOL HasNormalChan();
int GetNormalChan();
BOOL GetGeoDice(int& maxFaces, float& maxSize, int& minFaces);
hsBool GetIsGUI();
plSharedMesh* GetSwappableGeom();
UInt32 GetSwappableGeomTarget();
plMaxBoneMap* GetBoneMap();
hsBool GetOverrideHighLevelSDL();
UInt8 GetAnimCompress();
hsScalar GetKeyReduceThreshold();
int NumRenderDependencies();
plMaxNodeBase* GetRenderDependency(int i);
int NumBones();
plMaxNodeBase* GetBone(int i);
//------------------------------
// Set Data from MaxNodeData
//------------------------------
void SetCanConvert(hsBool b);
void SetMesh(hsGMesh *p);
void SetRoomKey(plKey p);
void SetDrawable(hsBool b);
void SetPhysical(hsBool b);
void SetItinerant(hsBool b);
void SetUnBounded(hsBool b);
void SetDisableNormal(hsBool b);
void SetDecalLevel(UInt32 i);
void SetMovable(hsBool b);
void SetNoPreShade(hsBool b);
void SetForcePreShade(hsBool b);
void SetReverseSort(hsBool b);
void SetSortAsOpaque(hsBool b);
void SetVS(hsBool b);
void SetHasWaterHeight(hsBool b);
void SetWaterHeight(hsScalar h);
void SetSmoothAll(hsBool b);
void SetForceSortable(hsBool b);
void SetConcave(hsBool b);
void SetCalcEdgeLens(hsBool b);
void SetRunTimeLight(hsBool b);
void SetForceMatShade(hsBool b);
void SetForceVisLOS(hsBool b);
void SetEnviron(hsBool b);
void SetEnvironOnly(hsBool b);
void SetWaterDecEnv(hsBool b);
void SetForceLocal(hsBool b);
void SetIsBarney(hsBool b);
void SetForceShadow(hsBool b);
void SetAlphaTestHigh(hsBool b);
void SetFilterInherit(hsBool b);
void SetNoShadow(hsBool b);
void SetNoSpanSort(hsBool b);
void SetNoSpanReSort(hsBool b);
void SetNoFaceSort(hsBool b);
void SetNoDeferDraw(hsBool b);
void SetBlendToFB(hsBool b);
void SetForceMaterialCopy(hsBool b);
void SetInstanced(hsBool b);
void SetParticleRelated(hsBool b);
void SetSoundIdxCounter(UInt32 ctr);
void SetAvatarSO(plSceneObject *so);
void SetFade(const Box3& b);
void SetDup2Sided(hsBool b);
void SetRadiateNorms(hsBool b);
void SetNormalChan(int n);
void SetGeoDice(BOOL on, int maxFaces, float maxSize, int minFaces);
void SetIsGUI(hsBool b);
void SetSwappableGeom(plSharedMesh *sm);
void SetSwappableGeomTarget(UInt32 id);
void SetBoneMap(plMaxBoneMap *bones);
void SetOverrideHighLevelSDL(hsBool b);
void SetAnimCompress(UInt8 v);
void SetKeyReduceThreshold(hsScalar v);
hsBool AddRenderDependency(plMaxNodeBase* m);
hsBool RenderDependsOn(plMaxNodeBase* m);
void ClearRenderDependencies();
void AddBone(plMaxNodeBase* m);
void ClearBones();
// Dirty flags for SceneWatcher use
enum { kGeomDirty = 0x1, kMatDirty = 0x2, kAllDirty = 0xFF };
hsBool GetDirty(UInt8 i);
void SetDirty(UInt8 i, hsBool b);
plKey GetParentKey() { plMaxNodeBase *pPar = (plMaxNodeBase*)GetParentNode(); hsAssert(pPar, "No Parent"); return pPar->GetKey(); }
ISkin* FindSkinModifier(); // Returns the object's skin modifier if it has one, else nil
const plRenderLevel& GetRenderLevel(hsBool forBlend);
hsBool HasLoadMask();
plLoadMask GetLoadMask();
void AddLoadMask(const plLoadMask& m);
hsBool IsTMAnimated();
hsBool IsTMAnimatedRecur();
hsBool IsMovable(); // Checks to see whether this node will ever move in the scene
bool IsXRef(); // Returns true if object is an XRef or part of an XRef'd scene
//----------
// Component
//----------
hsBool IsComponent(Object *obj=nil); // Object pointer is only necessary for internal use,
hsBool IsExternComponent(Object *obj=nil);
plComponentBase *ConvertToComponent(); // Returns nil if node is not a component
// Normally you will only want the components that are attached to you
// because you are in their targets list. However, in some cases a
// component will want to know what other components are attached to it. In
// that case, set all to true, so that the attached components won't be
// verified to be in your target list.
UInt32 NumAttachedComponents(bool all=false);
plComponentBase *GetAttachedComponent(UInt32 i, bool all=false);
hsBool Contains(const Point3& worldPt); // is the world space point inside my (CONVEX) geometry or dummy box?
hsBool Contains(const Box3& bnd, const Matrix3& l2w); // is the box contained entirely inside my (CONVEX) geometry or dummy box?
hsScalar BoxVolume(const Box3& bnd, const Matrix3& l2w);
hsScalar RegionPriority(); // returns a dominance factor. If a point is in more than one environmental
// region, the region with highest priority wins.
Interface *GetInterface() { return ::GetCOREInterface(); }
static hsMatrix44 Matrix3ToMatrix44(const Matrix3& m3);
static Matrix3 Matrix44ToMatrix3(const hsMatrix44& m44);
// Don't use these two functions, they probably don't return what
// you think they do. See code comments.
Matrix3 GetWorldToParent(TimeValue t);
Matrix3 GetParentToWorld(TimeValue t);
hsMatrix44 GetLocalToParent44(TimeValue t = TimeValue(0));
hsMatrix44 GetParentToLocal44(TimeValue t = TimeValue(0));
hsMatrix44 GetLocalToWorld44(TimeValue t = TimeValue(0));
hsMatrix44 GetWorldToLocal44(TimeValue t = TimeValue(0));
hsMatrix44 GetOTM44(TimeValue t = TimeValue(0));
hsMatrix44 GetVertToLocal44(TimeValue t = TimeValue(0));
hsMatrix44 GetLocalToVert44(TimeValue t = TimeValue(0));
hsMatrix44 GetOBBToLocal44(TimeValue t = TimeValue(0));
hsMatrix44 GetLocalToOBB44(TimeValue t = TimeValue(0));
Matrix3 GetLocalToParent(TimeValue t = TimeValue(0));
Matrix3 GetParentToLocal(TimeValue t = TimeValue(0));
Matrix3 GetLocalToWorld(TimeValue t = TimeValue(0));
Matrix3 GetWorldToLocal(TimeValue t = TimeValue(0));
Matrix3 GetOTM(TimeValue t = TimeValue(0));
Matrix3 GetVertToLocal(TimeValue t = TimeValue(0));
Matrix3 GetLocalToVert(TimeValue t = TimeValue(0));
Matrix3 GetOBBToLocal(TimeValue t = TimeValue(0));
Matrix3 GetLocalToOBB(TimeValue t = TimeValue(0));
protected:
// AppDataChunk sub-chunk id's
enum
{
kPlasmaAgeChunk, // No longer in use, but cleared from old files
kPlasmaDistChunk, // No longer in use, but cleared from old files
kPlasmaRoomChunk, // No longer in use, but cleared from old files
kPlasmaMaxNodeDataChunk,
kPlasmaSceneViewerChunk,
kPlasmaLightChunk, // No longer in use, but cleared from old files
};
UInt8 *IGetSceneViewerChunk();
// Attempts to convert a RefMaker pointer to a component. Returns nil if it is not a component.
plComponentBase *IRefMakerToComponent(ReferenceMaker *maker, bool all);
UInt32 IGetMajorRenderLevel(hsBool forBlend);
UInt32 IGetMinorRenderLevel(hsBool forBlend);
hsBool IRenderLevelSet(hsBool forBlend);
void ISetRenderLevel(const plRenderLevel& l, hsBool forBlend);
const plRenderLevel& IGetRenderLevel(hsBool forBlend);
plRenderLevel ICalcRenderLevel(hsBool forBlend);
};
#endif //plMaxNodeBase_inc

View File

@ -0,0 +1,451 @@
/*==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==*/
#ifndef plMaxNodeData_inc
#define plMaxNodeData_inc
#include "hsTypes.h"
#include "hsTemplates.h"
#include "hsColorRGBA.h"
#include "plRenderLevel.h"
#include "plPhysicalProps.h"
#include "hsBitVector.h"
#include "../pnKeyedObject/plKey.h"
#include "plLoadMask.h"
class plMaxNodeBase;
class plMaxNode;
class plLocation;
class plSceneObject;
class hsGMesh;
class plGeometrySpan;
class plMaxBoneMap;
class plSharedMesh;
class plMaxNodeBaseTab : public Tab<plMaxNodeBase*>
{
};
//
// Created hoping to trim some fat so to speak for all the bools that
// we are tossing around.
//
class DataBF
{
public:
enum DatBit
{
kCanConvert = 0x0,
kForceLocal,
kDrawable, // Absence of this prop forbids making this drawable
kBlendToFB,
kItinerant,
kRunTimeLight,
kMovable,
kIsBarney,
kForceMatCopy,
kNoPreShade,
kIsInstanced,
kParticleRelated,
kNoSpanReSort,
kHasFade,
kNoFaceSort,
kNoSpanSort,
kNoDeferDraw,
kBLevelSet,
kOLevelSet,
kDup2Sided,
kRadiateNorms,
kGeoDice,
kForcePreShade,
kIsGUI,
kSwappableGeomTarget,
kNoShadow,
kForceShadow,
kFilterInherit,
kReverseSort,
kVS,
kConcave,
kCalcEdgeLens,
kEnviron,
kEnvironOnly,
kPhysical, // Absence of this prop forbids making this physical
kSmoothAll,
kForceSortable,
kOverrideHighLevelSDL,
kDisableNormal,
kHasLoadMask,
kWaterDecEnv,
kWaterHeight,
kAlphaTestHigh,
kForceMatShade,
kUnBounded,
kForceVisLOS,
kSortAsOpaque,
};
hsBitVector* fBitVector;
DataBF()
{
fBitVector = TRACKED_NEW hsBitVector;
fBitVector->SetBit(kDrawable);
fBitVector->SetBit(kPhysical);
}
virtual ~DataBF() { delete fBitVector; }
DataBF& operator=(const DataBF& ot)
{
*fBitVector = *ot.fBitVector;
return *this;
}
DataBF(const DataBF& ot)
{
fBitVector = TRACKED_NEW hsBitVector;
*fBitVector = *ot.fBitVector;
}
void Init()
{
fBitVector = TRACKED_NEW hsBitVector;
fBitVector->SetBit(kDrawable);
fBitVector->SetBit(kPhysical);
}
void DeInit() { delete fBitVector; fBitVector = nil; }
hsBool CanBF(DatBit bitChoice) { return fBitVector->IsBitSet(bitChoice); }
void SetBF(hsBool b, DatBit bitChoice) { fBitVector->SetBit(bitChoice, b); }
};
class plMaxNodeData
{
public:
plMaxNodeData() :
fpKey(nil),
fpSO(nil) ,
fDecalLevel(0),
fpMesh(nil),
fpRoomKey(nil),
fSoundIdxCounter( 0 ),
fAvatarSO(nil),
fFade(Point3(0,0,0), Point3(0,0,0)),
fNormalChan(0),
fWaterHeight(0),
fGDMaxFaces(0), fGDMaxSize(0), fGDMinFaces(0),
fSwapMesh(nil),
fSwapTargetID((UInt32)-1),
fCachedAlphaHackLayerCounts(nil),
fBoneMap(nil),
fAnimCompression(1), // Should be plAnimCompressComp::kCompressionLow,
// but I don't want to include the entire header.
fKeyReduceThreshold(0.0002)
{ }
~plMaxNodeData()
{
fpKey = nil;
fpRoomKey = nil;
fpSO = 0;
fAvatarSO = nil;
delete fCachedAlphaHackLayerCounts;
MaxDatBF.DeInit();
}
// Call init on MaxNodeData whose constructor was never called, e.g. if it was malloc'd.
plMaxNodeData& Init()
{
memset( &fpKey, 0, sizeof( plKey ) );
memset( &fpRoomKey, 0, sizeof( plKey ) );
fRenderDependencies.Init();
fBones.Init();
fCachedAlphaHackLayerCounts = nil;
MaxDatBF.Init();
return *this;
}
// Ditto
void DeInit( void )
{
fpKey = nil;
fpRoomKey = nil;
fpSO = 0; fAvatarSO = nil;
delete fCachedAlphaHackLayerCounts;
fCachedAlphaHackLayerCounts = nil;
MaxDatBF.DeInit();
}
plKey GetKey() { return fpKey; }
void SetKey(plKey p ) { fpKey = p; }
plSceneObject * GetSceneObject() { return fpSO; }
void SetSceneObject(plSceneObject *p) { fpSO = p; }
hsBool CanConvert() { return MaxDatBF.CanBF(MaxDatBF.kCanConvert); }
void SetCanConvert(hsBool b) { MaxDatBF.SetBF(b, MaxDatBF.kCanConvert); }
hsBool GetForceLocal() { return MaxDatBF.CanBF(MaxDatBF.kForceLocal); }
void SetForceLocal(hsBool b) { MaxDatBF.SetBF(b, MaxDatBF.kForceLocal); }
void * GetMesh() { return fpMesh; } // void pointer for header simplicity
void SetMesh(hsGMesh *p) { fpMesh = p; }
hsBool GetDrawable() {return MaxDatBF.CanBF(MaxDatBF.kDrawable); }
void SetDrawable(hsBool b) { MaxDatBF.SetBF(b, MaxDatBF.kDrawable); }
hsBool GetPhysical() {return MaxDatBF.CanBF(MaxDatBF.kPhysical); }
void SetPhysical(hsBool b) { MaxDatBF.SetBF(b, MaxDatBF.kPhysical); }
hsBool GetRunTimeLight() {return MaxDatBF.CanBF(MaxDatBF.kRunTimeLight); }
void SetRunTimeLight(hsBool b) { MaxDatBF.SetBF(b, MaxDatBF.kRunTimeLight); }
hsBool GetForceMatShade() {return MaxDatBF.CanBF(MaxDatBF.kForceMatShade); }
void SetForceMatShade(hsBool b) { MaxDatBF.SetBF(b, MaxDatBF.kForceMatShade); }
hsBool GetForceVisLOS() {return MaxDatBF.CanBF(MaxDatBF.kForceVisLOS); }
void SetForceVisLOS(hsBool b) { MaxDatBF.SetBF(b, MaxDatBF.kForceVisLOS); }
hsBool GetEnviron() {return MaxDatBF.CanBF(MaxDatBF.kEnviron); }
void SetEnviron(hsBool b) { MaxDatBF.SetBF(b, MaxDatBF.kEnviron); }
hsBool GetEnvironOnly() {return MaxDatBF.CanBF(MaxDatBF.kEnvironOnly); }
void SetEnvironOnly(hsBool b) { MaxDatBF.SetBF(b, MaxDatBF.kEnvironOnly); }
hsBool GetWaterDecEnv() { return MaxDatBF.CanBF(MaxDatBF.kWaterDecEnv); }
void SetWaterDecEnv(hsBool b) { MaxDatBF.SetBF(b, MaxDatBF.kWaterDecEnv); }
hsBool GetItinerant() {return MaxDatBF.CanBF(MaxDatBF.kItinerant); }
void SetItinerant(hsBool b) { MaxDatBF.SetBF(b, MaxDatBF.kItinerant); }
hsBool GetUnBounded() {return MaxDatBF.CanBF(MaxDatBF.kUnBounded); }
void SetUnBounded(hsBool b) { MaxDatBF.SetBF(b, MaxDatBF.kUnBounded); }
hsBool GetDisableNormal() {return MaxDatBF.CanBF(MaxDatBF.kDisableNormal); }
void SetDisableNormal(hsBool b) { MaxDatBF.SetBF(b, MaxDatBF.kDisableNormal); }
hsBool GetMovable() {return MaxDatBF.CanBF(MaxDatBF.kMovable); }
void SetMovable(hsBool b) { MaxDatBF.SetBF(b, MaxDatBF.kMovable); }
hsBool GetNoPreShade() {return MaxDatBF.CanBF(MaxDatBF.kNoPreShade); }
void SetNoPreShade(hsBool b) { MaxDatBF.SetBF(b, MaxDatBF.kNoPreShade); }
hsBool GetForcePreShade() {return MaxDatBF.CanBF(MaxDatBF.kForcePreShade); }
void SetForcePreShade(hsBool b) { MaxDatBF.SetBF(b, MaxDatBF.kForcePreShade); }
hsBool GetNoShadow() {return MaxDatBF.CanBF(MaxDatBF.kNoShadow); }
void SetNoShadow(hsBool b) { MaxDatBF.SetBF(b, MaxDatBF.kNoShadow); }
hsBool GetForceShadow() {return MaxDatBF.CanBF(MaxDatBF.kForceShadow); }
void SetForceShadow(hsBool b) { MaxDatBF.SetBF(b, MaxDatBF.kForceShadow); }
hsBool GetAlphaTestHigh() {return MaxDatBF.CanBF(MaxDatBF.kAlphaTestHigh); }
void SetAlphaTestHigh(hsBool b) { MaxDatBF.SetBF(b, MaxDatBF.kAlphaTestHigh); }
hsBool GetFilterInherit() {return MaxDatBF.CanBF(MaxDatBF.kFilterInherit); }
void SetFilterInherit(hsBool b) { MaxDatBF.SetBF(b, MaxDatBF.kFilterInherit); }
hsBool GetIsBarney() {return MaxDatBF.CanBF(MaxDatBF.kIsBarney); }
void SetIsBarney(hsBool b) { MaxDatBF.SetBF(b, MaxDatBF.kIsBarney); }
hsBool GetNoSpanSort() {return MaxDatBF.CanBF(MaxDatBF.kNoSpanSort); }
void SetNoSpanSort(hsBool b) { MaxDatBF.SetBF(b, MaxDatBF.kNoSpanSort); }
hsBool GetNoSpanReSort() {return MaxDatBF.CanBF(MaxDatBF.kNoSpanReSort); }
void SetNoSpanReSort(hsBool b) { MaxDatBF.SetBF(b, MaxDatBF.kNoSpanReSort); }
hsBool GetNoFaceSort() {return MaxDatBF.CanBF(MaxDatBF.kNoFaceSort); }
void SetNoFaceSort(hsBool b) { MaxDatBF.SetBF(b, MaxDatBF.kNoFaceSort); }
hsBool GetReverseSort() {return MaxDatBF.CanBF(MaxDatBF.kReverseSort); }
void SetReverseSort(hsBool b) { MaxDatBF.SetBF(b, MaxDatBF.kReverseSort); }
hsBool GetSortAsOpaque() {return MaxDatBF.CanBF(MaxDatBF.kSortAsOpaque); }
void SetSortAsOpaque(hsBool b) { MaxDatBF.SetBF(b, MaxDatBF.kSortAsOpaque); }
hsBool GetVS() {return MaxDatBF.CanBF(MaxDatBF.kVS); }
void SetVS(hsBool b) { MaxDatBF.SetBF(b, MaxDatBF.kVS); }
hsBool GetHasWaterHeight() { return MaxDatBF.CanBF(MaxDatBF.kWaterHeight); }
void SetHasWaterHeight(hsBool b) { MaxDatBF.SetBF(b, MaxDatBF.kWaterHeight); }
hsScalar GetWaterHeight() { return fWaterHeight; }
void SetWaterHeight(hsScalar f) { SetHasWaterHeight(true); fWaterHeight = f; }
hsBool GetSmoothAll() {return MaxDatBF.CanBF(MaxDatBF.kSmoothAll); }
void SetSmoothAll(hsBool b) { MaxDatBF.SetBF(b, MaxDatBF.kSmoothAll); }
hsBool GetForceSortable() {return MaxDatBF.CanBF(MaxDatBF.kForceSortable); }
void SetForceSortable(hsBool b) { MaxDatBF.SetBF(b, MaxDatBF.kForceSortable); }
hsBool GetConcave() {return MaxDatBF.CanBF(MaxDatBF.kConcave); }
void SetConcave(hsBool b) { MaxDatBF.SetBF(b, MaxDatBF.kConcave); }
hsBool GetCalcEdgeLens() {return MaxDatBF.CanBF(MaxDatBF.kCalcEdgeLens); }
void SetCalcEdgeLens(hsBool b) { MaxDatBF.SetBF(b, MaxDatBF.kCalcEdgeLens); }
hsBool GetNoDeferDraw() {return MaxDatBF.CanBF(MaxDatBF.kNoDeferDraw); }
void SetNoDeferDraw(hsBool b) { MaxDatBF.SetBF(b, MaxDatBF.kNoDeferDraw); }
hsBool GetBlendToFB() {return MaxDatBF.CanBF(MaxDatBF.kBlendToFB); }
void SetBlendToFB(hsBool b) { MaxDatBF.SetBF(b, MaxDatBF.kBlendToFB); }
hsBool GetForceMaterialCopy() {return MaxDatBF.CanBF(MaxDatBF.kForceMatCopy); }
void SetForceMaterialCopy(hsBool b) { MaxDatBF.SetBF(b, MaxDatBF.kForceMatCopy); }
hsBool GetInstanced() {return MaxDatBF.CanBF(MaxDatBF.kIsInstanced); }
void SetInstanced(hsBool b) { MaxDatBF.SetBF(b, MaxDatBF.kIsInstanced); }
hsBool GetParticleRelated() {return MaxDatBF.CanBF(MaxDatBF.kParticleRelated); }
void SetParticleRelated(hsBool b) { MaxDatBF.SetBF(b, MaxDatBF.kParticleRelated); }
hsBool GetDup2Sided() {return MaxDatBF.CanBF(MaxDatBF.kDup2Sided); }
void SetDup2Sided(hsBool b) { MaxDatBF.SetBF(b, MaxDatBF.kDup2Sided); }
hsBool GetRadiateNorms() {return MaxDatBF.CanBF(MaxDatBF.kRadiateNorms); }
void SetRadiateNorms(hsBool b) { MaxDatBF.SetBF(b, MaxDatBF.kRadiateNorms); }
hsBool GetGeoDice() {return MaxDatBF.CanBF(MaxDatBF.kGeoDice); }
void SetGeoDice(hsBool b) { MaxDatBF.SetBF(b, MaxDatBF.kGeoDice); }
hsBool GetIsGUI() {return MaxDatBF.CanBF(MaxDatBF.kIsGUI); }
void SetIsGUI(hsBool b) { MaxDatBF.SetBF(b, MaxDatBF.kIsGUI); }
plSharedMesh* GetSwappableGeom() { return fSwapMesh;}
void SetSwappableGeom(plSharedMesh *sm) { fSwapMesh = sm; }
UInt32 GetSwappableGeomTarget() { return fSwapTargetID;}
void SetSwappableGeomTarget(UInt32 id) { fSwapTargetID = id;}
plMaxBoneMap* GetBoneMap() { return fBoneMap;}
void SetBoneMap(plMaxBoneMap *bones) { fBoneMap = bones;}
int GetGeoDiceMaxFaces() { return fGDMaxFaces; }
void SetGeoDiceMaxFaces(int f) { fGDMaxFaces = f; }
float GetGeoDiceMaxSize() { return fGDMaxSize; }
void SetGeoDiceMaxSize(float f) { fGDMaxSize = f; }
int GetGeoDiceMinFaces() { return fGDMinFaces; }
void SetGeoDiceMinFaces(int f) { fGDMinFaces = f; }
plKey GetRoomKey() { return fpRoomKey; }
void SetRoomKey(plKey p) { fpRoomKey = p; }
UInt32 GetDecalLevel() { return fDecalLevel; }
void SetDecalLevel(UInt32 i) { fDecalLevel = i; }
UInt32 GetSoundIdxCounter() { return fSoundIdxCounter; }
void SetSoundIdxCounter( UInt32 i ) { fSoundIdxCounter = i; }
plSceneObject * GetAvatarSO() { return fAvatarSO; }
void SetAvatarSO(plSceneObject *so) { fAvatarSO = so; }
int NumRenderDependencies() { return fRenderDependencies.Count(); }
plMaxNodeBase* GetRenderDependency(int i) { return fRenderDependencies[i]; }
void AddRenderDependency(plMaxNodeBase* m) { fRenderDependencies.Append(1, &m); }
void ClearRenderDependencies() { fRenderDependencies.ZeroCount(); }
int NumBones() { return fBones.Count(); }
plMaxNodeBase* GetBone(int i) { return fBones[i]; }
void AddBone(plMaxNodeBase* m) { fBones.Append(1, &m); }
void ClearBones() { fBones.ZeroCount(); }
hsBool HasFade() { return MaxDatBF.CanBF(MaxDatBF.kHasFade); }
void SetFade(const Box3& b) { MaxDatBF.SetBF((b.Min()[2] != 0)||(b.Max()[2] != 0), MaxDatBF.kHasFade); fFade = b; }
Box3 GetFade() { return fFade; }
hsBool HasLoadMask() { return MaxDatBF.CanBF(MaxDatBF.kHasLoadMask); }
plLoadMask GetLoadMask() { return HasLoadMask() ? fLoadMask : plLoadMask::kAlways; }
void AddLoadMask(const plLoadMask& m) { if( !HasLoadMask() ) { fLoadMask = m; MaxDatBF.SetBF(true, MaxDatBF.kHasLoadMask); }else{ fLoadMask |= m; } }
hsBool HasNormalChan() { return fNormalChan > 0; }
void SetNormalChan(int n) { fNormalChan = n; }
int GetNormalChan() { return fNormalChan; }
hsBool BlendLevelSet() { return MaxDatBF.CanBF(MaxDatBF.kBLevelSet); }
void SetBlendLevel(const plRenderLevel& l) { fBlendLevel = l; MaxDatBF.SetBF(true, MaxDatBF.kBLevelSet); }
const plRenderLevel& GetBlendLevel() { return fBlendLevel; }
hsBool OpaqueLevelSet() { return MaxDatBF.CanBF(MaxDatBF.kOLevelSet); }
void SetOpaqueLevel(const plRenderLevel& l) { fOpaqueLevel = l; MaxDatBF.SetBF(true, MaxDatBF.kOLevelSet); }
const plRenderLevel& GetOpaqueLevel() { return fOpaqueLevel; }
plPhysicalProps* GetPhysicalProps() { return &fPhysicalProps; }
hsTArray<int> *GetAlphaHackLayersCache( void ) { return fCachedAlphaHackLayerCounts; }
void SetAlphaHackLayersCache( hsTArray<int> *cache ) { fCachedAlphaHackLayerCounts = cache; }
hsBool GetOverrideHighLevelSDL() { return MaxDatBF.CanBF(MaxDatBF.kOverrideHighLevelSDL); }
void SetOverrideHighLevelSDL(hsBool b) { MaxDatBF.SetBF(b, MaxDatBF.kOverrideHighLevelSDL); }
UInt8 GetAnimCompress() { return fAnimCompression; }
void SetAnimCompress(UInt8 v) { fAnimCompression = v; }
hsScalar GetKeyReduceThreshold() { return fKeyReduceThreshold; }
void SetKeyReduceThreshold(hsScalar v) { fKeyReduceThreshold = v; }
protected:
plKey fpKey;
plSceneObject * fpSO;
// hacking this in here temporarily because everything's about to change in the mesh world...
hsGMesh* fpMesh;
plKey fpRoomKey;
UInt32 fDecalLevel;
Int32 fNormalChan;
UInt32 fSoundIdxCounter;
plSceneObject * fAvatarSO;
plMaxNodeBaseTab fRenderDependencies;
plMaxNodeBaseTab fBones;
Box3 fFade;
int fGDMaxFaces;
float fGDMaxSize;
int fGDMinFaces;
plRenderLevel fBlendLevel;
plRenderLevel fOpaqueLevel;
plPhysicalProps fPhysicalProps;
UInt32 fSwapTargetID;
hsTArray<int> *fCachedAlphaHackLayerCounts;
plSharedMesh *fSwapMesh;
plMaxBoneMap *fBoneMap;
plLoadMask fLoadMask;
hsScalar fWaterHeight;
UInt8 fAnimCompression;
hsScalar fKeyReduceThreshold;
DataBF MaxDatBF;
};
#endif // plSimpleConvert_inc

View File

@ -0,0 +1,163 @@
/*==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 "HeadSpin.h"
#include "plMaxUtils.h"
#include "resource.h"
#include "hsResMgr.h"
#include "../plResMgr/plPageInfo.h"
#include "../pnKeyedObject/plUoid.h"
#include "../pnKeyedObject/plKey.h"
#include "../pnFactory/plFactory.h"
class MaxUtilsClassDesc : public ClassDesc
{
public:
int IsPublic() { return TRUE; }
void* Create(BOOL loading) { return &plMaxUtils::Instance(); }
const TCHAR* ClassName() { return _T("Plasma Debug Utils"); }
SClass_ID SuperClassID() { return UTILITY_CLASS_ID; }
Class_ID ClassID() { return Class_ID(0x316610ee, 0xebe62c3); }
const TCHAR* Category() { return _T(""); }
};
static MaxUtilsClassDesc theMaxUtilsClassDesc;
ClassDesc* GetMaxUtilsDesc() { return &theMaxUtilsClassDesc; }
plMaxUtils::plMaxUtils() : fhPanel(nil), fhResDlg(nil)
{
}
plMaxUtils& plMaxUtils::Instance()
{
static plMaxUtils theInstance;
return theInstance;
}
void plMaxUtils::BeginEditParams(Interface *ip, IUtil *iu)
{
fhPanel = GetCOREInterface()->AddRollupPage(hInstance,
MAKEINTRESOURCE(IDD_UTILS),
ForwardDlgProc,
"Plasma Debug Utils");
}
void plMaxUtils::EndEditParams(Interface *ip, IUtil *iu)
{
GetCOREInterface()->DeleteRollupPage(fhPanel);
}
BOOL CALLBACK plMaxUtils::ForwardDlgProc(HWND hDlg, UINT msg, WPARAM wParam, LPARAM lParam)
{
return Instance().DlgProc(hDlg, msg, wParam, lParam);
}
int ClearTextureIds();
BOOL plMaxUtils::DlgProc(HWND hDlg, UINT msg, WPARAM wParam, LPARAM lParam)
{
switch (msg)
{
case WM_COMMAND:
if (HIWORD(wParam) == BN_CLICKED && LOWORD(wParam) == IDC_RES)
{
int numCleared = ClearTextureIds();
char buf[256];
sprintf(buf, "Cleared %d texture ids", numCleared);
MessageBox(NULL, buf, "AssetMan Clear", MB_OK);
return TRUE;
}
break;
}
return FALSE;
}
#include "plMtlCollector.h"
#include "../MaxPlasmaMtls/Layers/plPlasmaMAXLayer.h"
#include "../../AssetMan/PublicInterface/AssManTypes.h"
int ClearTextureIds()
{
int numCleared = 0;
TexSet texmaps;
plMtlCollector::GetMtls(nil, &texmaps);
TexSet::iterator texIt = texmaps.begin();
for (; texIt != texmaps.end(); texIt++)
{
Texmap* texmap = (*texIt);
plPlasmaMAXLayer* layer = plPlasmaMAXLayer::GetPlasmaMAXLayer(texmap);
if (layer)
{
int numBitmaps = layer->GetNumBitmaps();
for (int i = 0; i < numBitmaps; i++)
{
jvUniqueId assetId;
layer->GetBitmapAssetId(assetId, i);
if (!assetId.IsEmpty())
{
assetId.SetEmpty();
layer->SetBitmapAssetId(assetId, i);
numCleared++;
}
}
}
}
return numCleared;
}
/*
void ClearAssetsRecur(plMaxNode* node)
{
plComponentBase* comp = node->ConvertToComponent();
if (comp && plAudioComp::IsSoundComponent(comp))
{
plBaseSoundEmitterComponent* soundComp = (plBaseSoundEmitterComponent*)comp;
soundComp->SetSoundAssetId(kBaseSound,
kCoverSound
)
}
}
*/

View File

@ -0,0 +1,65 @@
/*==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 "max.h"
#include "utilapi.h"
// This a central repository for handy debugging tools for Max that don't fit in anywhere else.
class plMaxUtils : public UtilityObj
{
protected:
HWND fhPanel;
HWND fhResDlg;
plMaxUtils();
public:
static plMaxUtils& Instance();
void DeleteThis() {};
void BeginEditParams(Interface *ip, IUtil *iu);
void EndEditParams(Interface *ip, IUtil *iu);
static BOOL CALLBACK ForwardDlgProc(HWND hDlg, UINT msg, WPARAM wParam, LPARAM lParam);
BOOL DlgProc(HWND hDlg, UINT msg, WPARAM wParam, LPARAM lParam);
static BOOL CALLBACK ResDlgProc(HWND hDlg, UINT msg, WPARAM wParam, LPARAM lParam);
};

View File

@ -0,0 +1,289 @@
/*==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 "HeadSpin.h"
#include "plMtlCollector.h"
#include "../MaxPlasmaMtls/Layers/plPlasmaMAXLayer.h"
#include "../MaxPlasmaMtls/Materials/plCompositeMtl.h"
#include "../MaxPlasmaMtls/Materials/plDecalMtl.h"
#include "../MaxPlasmaMtls/Materials/plMultipassMtl.h"
#include "../MaxPlasmaMtls/Materials/plParticleMtl.h"
#include "../MaxPlasmaMtls/Materials/plPassMtl.h"
#include "../MaxPlasmaMtls/Materials/plClothingMtl.h"
#include "../MaxComponent/plGUIComponents.h"
#include "../MaxComponent/pfGUISkinComp.h"
#include "../MaxComponent/plMiscComponents.h"
#include "../MaxMain/plMaxNodeBase.h"
static bool IsPlasmaMtl(Mtl *mtl)
{
if (mtl->ClassID() == COMP_MTL_CLASS_ID ||
mtl->ClassID() == DECAL_MTL_CLASS_ID ||
mtl->ClassID() == MULTIMTL_CLASS_ID ||
mtl->ClassID() == PARTICLE_MTL_CLASS_ID ||
mtl->ClassID() == PASS_MTL_CLASS_ID ||
mtl->ClassID() == CLOTHING_MTL_CLASS_ID)
return true;
return false;
}
static bool IsTexmapOK(Texmap *tex, UInt8 flags)
{
if (flags & plMtlCollector::kPlasmaOnly && !plPlasmaMAXLayer::GetPlasmaMAXLayer(tex))
return false;
return true;
}
static bool IsMtlOK(Mtl *mtl, UInt8 flags)
{
if (flags & plMtlCollector::kPlasmaOnly && !IsPlasmaMtl(mtl))
return false;
if (flags & plMtlCollector::kNoMultiMtl && mtl->ClassID() == MULTIMTL_CLASS_ID)
return false;
if (flags & plMtlCollector::kClothingMtlOnly && mtl->ClassID() != CLOTHING_MTL_CLASS_ID)
return false;
return true;
}
void GetMtlsRecur(MtlBase *mtlBase, MtlSet* mtls, TexSet* texmaps, UInt32 flags)
{
if (!mtlBase)
return;
if (mtlBase->SuperClassID() == TEXMAP_CLASS_ID)
{
Texmap* tex = (Texmap*)mtlBase;
if (texmaps && IsTexmapOK(tex, flags))
texmaps->insert(tex);
}
else if(mtlBase->SuperClassID() == MATERIAL_CLASS_ID)
{
Mtl* mtl = (Mtl*)mtlBase;
if (mtls && IsMtlOK(mtl, flags))
mtls->insert(mtl);
// Get the bitmaps from all the textures this material contains
int i;
int numTex = mtl->NumSubTexmaps();
for (i = 0; i < numTex; i++)
{
Texmap *tex = mtl->GetSubTexmap(i);
if (tex)
{
if (texmaps && IsTexmapOK(tex, flags))
texmaps->insert(tex);
}
}
// Do the same for any submtls
if (!(flags & plMtlCollector::kNoSubMtls))
{
int numMtl = mtl->NumSubMtls();
for (i = 0; i < numMtl; i++)
GetMtlsRecur(mtl->GetSubMtl(i), mtls, texmaps, flags);
}
}
else
{
hsAssert(0, "What kind of material is this?");
}
}
static void GetTexmapPBs(Texmap* tex, PBSet& pbs)
{
if (!tex)
return;
plPlasmaMAXLayer *plasma = plPlasmaMAXLayer::GetPlasmaMAXLayer( tex );
if( plasma != nil )
{
int i;
for( i = 0; i < plasma->GetNumBitmaps(); i++ )
{
PBBitmap *pbbm = plasma->GetPBBitmap( i );
if( pbbm != nil )
pbs.insert( pbbm );
}
}
else
{
for (int i = 0; i < tex->NumRefs(); i++)
{
ReferenceTarget* r = tex->GetReference(i);
if (r && r->SuperClassID() == PARAMETER_BLOCK2_CLASS_ID)
{
IParamBlock2* pb = (IParamBlock2*)r;
for (int j = 0; j < pb->NumParams(); j++)
{
if (pb->GetParameterType(pb->IndextoID(j)) == TYPE_BITMAP)
{
PBBitmap *pbbm = pb->GetBitmap(j);
if (pbbm)
pbs.insert(pbbm);
}
}
}
}
}
}
#include "../MaxPlasmaLights/plRealTimeLightBase.h"
static void GetNodeMtlsRecur(INode *node, MtlSet* mtls, TexSet* texmaps, UInt32 flags)
{
Mtl *mtl = node->GetMtl();
GetMtlsRecur(mtl, mtls, texmaps, flags);
Object* obj = node->GetObjectRef();
if (obj && (obj->ClassID() == RTSPOT_LIGHT_CLASSID || obj->ClassID() == RTPDIR_LIGHT_CLASSID))
{
Texmap* texmap = ((plRTLightBase*)obj)->GetProjMap();
GetMtlsRecur(texmap, mtls, texmaps, flags);
}
plGUIControlBase *gui = plGUIControlBase::GetGUIComp( node );
if( gui != nil )
{
UInt32 i;
for( i = 0; i < gui->GetNumMtls(); i++ )
GetMtlsRecur( gui->GetMtl( i ), mtls, texmaps, flags );
}
else
{
// Skins aren't controls
plGUISkinComp *guiSkin = plGUISkinComp::GetGUIComp( node );
if( guiSkin != nil )
{
UInt32 i;
for( i = 0; i < guiSkin->GetNumMtls(); i++ )
GetMtlsRecur( guiSkin->GetMtl( i ), mtls, texmaps, flags );
}
else
{
// Um, other components
plComponentBase *base = ( ( plMaxNodeBase *)node )->ConvertToComponent();
if( base != nil )
{
if( base->ClassID() == IMAGE_LIB_CID )
{
pfImageLibComponent *iLib = (pfImageLibComponent *)base;
UInt32 i;
for( i = 0; i < iLib->GetNumBitmaps(); i++ )
GetMtlsRecur( iLib->GetBitmap( i ), mtls, texmaps, flags );
}
}
}
}
for (int i = 0; i < node->NumberOfChildren(); i++)
GetNodeMtlsRecur(node->GetChildNode(i), mtls, texmaps, flags);
}
static void GetEditorMtls(MtlSet* mtls, TexSet* texmaps, UInt32 flags)
{
static const int kNumEditorSlots = 24;
Interface *ip = GetCOREInterface();
for (int i = 0; i < kNumEditorSlots; i++)
{
MtlBase *mtlBase = ip->GetMtlSlot(i);
GetMtlsRecur(mtlBase, mtls, texmaps, flags);
}
}
void plMtlCollector::GetMtls(MtlSet* mtls, TexSet* texmaps, UInt32 flags)
{
Interface *ip = GetCOREInterface();
// Make a list of all the textures from the GetSceneMtls() func
MtlBaseLib* sceneMtls = ip->GetSceneMtls();
for(int i = 0; i < sceneMtls->Count(); i++)
{
GetMtlsRecur((*sceneMtls)[i], mtls, texmaps, flags);
}
// Add any more we find traversing the node hierarchy
INode *root = ip->GetRootNode();
GetNodeMtlsRecur(root, mtls, texmaps, flags);
if (!(flags & kUsedOnly))
GetEditorMtls(mtls, texmaps, flags);
}
void plMtlCollector::GetMtlLayers(Mtl *mtl, LayerSet& layers)
{
TexSet tex;
GetMtlsRecur(mtl, nil, &tex, kPlasmaOnly);
TexSet::iterator it = tex.begin();
for (; it != tex.end(); it++)
{
layers.insert((plPlasmaMAXLayer*)*it);
}
}
void plMtlCollector::GetAllTextures(TexNameSet& texNames)
{
TexSet tex;
GetMtls(nil, &tex);
PBSet pbs;
TexSet::iterator it = tex.begin();
for (; it != tex.end(); it++)
GetTexmapPBs(*it, pbs);
PBSet::iterator pbIt = pbs.begin();
for (; pbIt != pbs.end(); pbIt++)
{
PBBitmap* pbbm = *pbIt;
texNames.insert(pbbm->bi.Name());
}
}

View File

@ -0,0 +1,81 @@
/*==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==*/
#ifndef plMtlCollector_h_inc
#define plMtlCollector_h_inc
#include "hsTypes.h"
#include <set>
#include "hsSTLSortUtils.h"
class Mtl;
class Texmap;
class plPlasmaMAXLayer;
class PBBitmap;
typedef std::set<Mtl*> MtlSet;
typedef std::set<Texmap*> TexSet;
typedef std::set<plPlasmaMAXLayer*> LayerSet;
typedef std::set<PBBitmap*> PBSet;
typedef std::set<const char*, stringISorter> TexNameSet;
class plMtlCollector
{
public:
enum
{
kUsedOnly = 0x1,
kPlasmaOnly = 0x2,
kNoMultiMtl = 0x4,
kClothingMtlOnly = 0x8,
kNoSubMtls = 0x10,
};
static void GetMtls(MtlSet* mtls, TexSet* texmaps, UInt32 flags=0);
static void GetMtlLayers(Mtl *mtl, LayerSet& layers);
// Warning: These pointers are only valid until you return control to Max
// (where a bitmap could be modified). Don't hang on to them!
static void GetAllTextures(TexNameSet& texNames);
};
#endif // plMtlCollector_h_inc

View File

@ -0,0 +1,74 @@
/*==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 "HeadSpin.h"
#include "max.h"
#include "plNodeLock.h"
void plNodeLock::Lock(BOOL on)
{
Interface *ip = GetCOREInterface();
ISetLockRecur(ip->GetRootNode(), on);
}
void plNodeLock::ISetLockRecur(INode* node, BOOL on)
{
BOOL isSel = node->Selected();
if( isSel )
{
node->SetTransformLock(INODE_LOCKPOS, INODE_LOCK_X, on);
node->SetTransformLock(INODE_LOCKPOS, INODE_LOCK_Y, on);
node->SetTransformLock(INODE_LOCKPOS, INODE_LOCK_Z, on);
node->SetTransformLock(INODE_LOCKROT, INODE_LOCK_X, on);
node->SetTransformLock(INODE_LOCKROT, INODE_LOCK_Y, on);
node->SetTransformLock(INODE_LOCKROT, INODE_LOCK_Z, on);
node->SetTransformLock(INODE_LOCKSCL, INODE_LOCK_X, on);
node->SetTransformLock(INODE_LOCKSCL, INODE_LOCK_Y, on);
node->SetTransformLock(INODE_LOCKSCL, INODE_LOCK_Z, on);
}
int i;
for( i = 0; i < node->NumberOfChildren(); i++ )
ISetLockRecur(node->GetChildNode(i), on);
}

View File

@ -0,0 +1,59 @@
/*==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==*/
#ifndef plNodeLock_inc
#define plNodeLock_inc
class plNodeLock
{
protected:
void ISetLockRecur(INode* node, BOOL on);
public:
plNodeLock() {}
~plNodeLock() {}
void Lock(BOOL on = true); // on = true locks, on = false unlocks
void Unlock() { Lock(false); }
};
#endif // plNodeLock_inc

View File

@ -0,0 +1,514 @@
/*==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 "plPhysXCooking.h"
#include "hsGeometry3.h"
#include "../plPhysX/plSimulationMgr.h"
#include "../plPhysX/plPXStream.h"
#include "../plPhysX/plPXConvert.h"
#include "hsSTLStream.h"
#include "Nx.h"
#include "NxStream.h"
#include "NxPhysics.h"
#include "NxCooking.h"
#include "NxPlane.h"
#include "NxUtilLib.h"
#include "NxMat33.h"
bool plPhysXCooking::fSkipErrors = false;
NxUtilLib* plPhysXCooking::fUtilLib =nil;
//assumes that the Vectors are normalized
hsBool ThreePlaneIntersect(const NxVec3& norm0, const NxVec3& point0,
const NxVec3& norm1, const NxVec3& point1,
const NxVec3& norm2, const NxVec3& point2, NxVec3& loc)
{
//need to make sure these planes aren't parallel
hsBool suc=0;
NxVec3 cross=norm1.cross( norm2);
hsScalar denom=norm0.dot(cross);
if(abs(denom)<0.0001) return 0;//basically paralell
// if we are here there must be a point in 3 space
try{
hsScalar d1,d2,d3;
d1=norm0.dot(point0);
d2=norm1.dot(point1);
d3=norm2.dot(point2);
NxVec3 n1Xn2=norm1.cross(norm2);
NxVec3 n2Xn0=norm2.cross(norm0);
NxVec3 n0Xn1=norm0.cross(norm1);
NxVec3 pos=(d1*n1Xn2+ d2*n2Xn0 + d3*n0Xn1)/(denom);
loc.x=pos.x;
loc.y=pos.y;
loc.z=pos.z;
suc= 1;
}
catch(...)
{
suc=0;
}
return suc;
}
void plPhysXCooking::Init()
{
NxInitCooking();
NxUtilLib* fUtilLib=NxGetUtilLib();
NxCookingParams parms=NxGetCookingParams();
parms.skinWidth=.05;
NxSetCookingParams(parms);
}
void plPhysXCooking::Shutdown()
{
NxCloseCooking();
fUtilLib=nil;
fSkipErrors = false;
}
hsVectorStream* plPhysXCooking::CookTrimesh(int nVerts, hsPoint3* verts, int nFaces, UInt16* faces)
{
NxTriangleMeshDesc triDesc;
triDesc.numVertices = nVerts;
triDesc.pointStrideBytes = sizeof(hsPoint3);
triDesc.points = verts;
triDesc.numTriangles = nFaces;
triDesc.triangleStrideBytes = sizeof(UInt16) * 3;
triDesc.triangles = faces;
triDesc.flags = NX_MF_16_BIT_INDICES;
hsVectorStream* ram = TRACKED_NEW hsVectorStream;
plPXStream buf(ram);
bool status = NxCookTriangleMesh(triDesc, buf);
hsAssert(status, "Trimesh failed to cook");
if (status)
{
ram->Rewind();
return ram;
}
else
{
delete ram;
return nil;
}
}
bool plPhysXCooking::IsPointInsideHull(hsPlane3* hull, int nPlanes, const hsPoint3& pos)
{
int i;
for( i = 0; i < nPlanes; i++ )
{
// add a fudge to the point so not to trip on the ever so slightly concave
// ... so pull the point out in the direction of the normal of the plane we are testing.
hsPoint3 fudgepos = pos + (hull[i].GetNormal()*0.005f);
if (!ITestPlane(fudgepos, hull[i]))
return false;
}
return true;
}
bool plPhysXCooking::TestIfConvex(NxConvexMesh* convexMesh, int nVerts, hsPoint3* verts)
{
bool retVal = true;
// build planes from the convex mesh
NxConvexMeshDesc desc;
convexMesh->saveToDesc(desc);
hsPlane3* planes = TRACKED_NEW hsPlane3[desc.numTriangles];
int i;
for ( i = 0; i < desc.numTriangles; i++)
{
UInt32* triangle = (UInt32*)(((char*)desc.triangles) + desc.triangleStrideBytes*i);
float* vertex1 = (float*)(((char*)desc.points) + desc.pointStrideBytes*triangle[0]);
float* vertex2 = (float*)(((char*)desc.points) + desc.pointStrideBytes*triangle[1]);
float* vertex3 = (float*)(((char*)desc.points) + desc.pointStrideBytes*triangle[2]);
hsPoint3 pt1(vertex1[0],vertex1[1],vertex1[2]);
hsPoint3 pt2(vertex2[0],vertex2[1],vertex2[2]);
hsPoint3 pt3(vertex3[0],vertex3[1],vertex3[2]);
planes[i] = hsPlane3(&pt1,&pt2,&pt3);
}
// now see if any of the points from the mesh are inside the hull
for (int j=0; j<nVerts && retVal; j++)
{
if ( IsPointInsideHull(planes,desc.numTriangles,verts[j]) )
retVal = false;
}
delete [] planes;
return retVal;
}
hsVectorStream* plPhysXCooking::CookHull(int nVerts, hsPoint3* verts, bool inflate)
{
NxConvexMeshDesc convexDesc;
convexDesc.numVertices = nVerts;
convexDesc.pointStrideBytes = sizeof(hsPoint3);
convexDesc.points = verts;
convexDesc.flags = NX_CF_COMPUTE_CONVEX;
if(inflate)
{
convexDesc.flags|= NX_CF_INFLATE_CONVEX ;
}
hsVectorStream* ram = TRACKED_NEW hsVectorStream;
plPXStream buf(ram);
bool status = NxCookConvexMesh(convexDesc, buf);
hsAssert(status, "Convex mesh failed to cook");
if (status)
{
ram->Rewind();
return ram;
}
else
{
delete ram;
return nil;
}
}
/*
NxTriangleMesh* ReadExplicit(hsStream* stream)
{
const int nVertices = stream->ReadSwap32();
hsPoint3* pVertices = TRACKED_NEW hsPoint3[nVertices];
stream->ReadSwapScalar(nVertices*3, (float*)pVertices);
const int nFaces = stream->ReadSwap32();
unsigned short* pTriangles = TRACKED_NEW unsigned short[nFaces * 3];
stream->ReadSwap16(nFaces * 3, pTriangles);
NxTriangleMeshDesc triDesc;
triDesc.numVertices = nVertices;
triDesc.pointStrideBytes = sizeof(hsPoint3);
triDesc.points = pVertices;
triDesc.numTriangles = nFaces;
triDesc.triangleStrideBytes = sizeof(UInt16) * 3;
triDesc.triangles = pTriangles;
triDesc.flags = NX_MF_16_BIT_INDICES;// | NX_MF_FLIPNORMALS;
hsRAMStream ram;
plNxStream buf(&ram);
NxInitCooking();
bool status = NxCookTriangleMesh(triDesc, buf);
hsAssert(status, "Trimesh failed to cook");
NxCloseCooking();
delete[] pVertices;
delete[] pTriangles;
if (status)
{
ram.Rewind();
return plSimulationMgr::GetInstance()->GetSDK()->createTriangleMesh(buf);
}
return nil;
}
NxConvexMesh* ReadConvexHull(hsStream* stream)
{
const int nVertices = stream->ReadSwap32();
hsPoint3* pVertices = TRACKED_NEW hsPoint3[nVertices];
stream->ReadSwapScalar(nVertices*3, (float*)pVertices);
NxConvexMeshDesc convexDesc;
convexDesc.numVertices = nVertices;
convexDesc.pointStrideBytes = sizeof(hsPoint3);
convexDesc.points = pVertices;
convexDesc.flags = NX_CF_COMPUTE_CONVEX;
hsRAMStream ram;
plNxStream buf(&ram);
NxInitCooking();
bool status = NxCookConvexMesh(convexDesc, buf);
hsAssert(status, "Convex mesh failed to cook");
NxCloseCooking();
delete[] pVertices;
if (status)
{
ram.Rewind();
return plSimulationMgr::GetInstance()->GetSDK()->createConvexMesh(buf);
}
return nil;
}
void ReadBoxFromHull(hsStream* stream, NxBoxShapeDesc& box)
{
const int nVertices = stream->ReadSwap32();
hsPoint3* pVertices = TRACKED_NEW hsPoint3[nVertices];
stream->ReadSwapScalar(nVertices*3, (float*)pVertices);
hsScalar minX, minY, minZ, maxX, maxY, maxZ;
minX = minY = minZ = FLT_MAX;
maxX = maxY = maxZ = -FLT_MAX;
for (int i = 0; i < nVertices; i++)
{
hsPoint3& vec = pVertices[i];
minX = hsMinimum(minX, vec.fX);
minY = hsMinimum(minY, vec.fY);
minZ = hsMinimum(minZ, vec.fZ);
maxX = hsMaximum(maxX, vec.fX);
maxY = hsMaximum(maxY, vec.fY);
maxZ = hsMaximum(maxZ, vec.fZ);
}
delete[] pVertices;
float xWidth = maxX - minX;
float yWidth = maxY - minY;
float zWidth = maxZ - minZ;
box.dimensions.x = xWidth / 2;
box.dimensions.y = yWidth / 2;
box.dimensions.z = zWidth / 2;
// hsMatrix44 mat;
// box.localPose.getRowMajor44(&mat.fMap[0][0]);
// hsPoint3 trans(minX + (xWidth / 2), minY + (yWidth / 2), minY + (yWidth / 2));
// mat.SetTranslate(&trans);
// box.localPose.setRowMajor44(&mat.fMap[0][0]);
}
*/
hsBool ProjectPointOnToPlane(const hsVector3& planeNormal,hsScalar& d0,
const hsVector3 pointToProject, hsPoint3& res)
{
NxVec3 vec=plPXConvert::Vector(planeNormal);
NxVec3 orig,projected;
orig=plPXConvert::Vector(pointToProject);
NxPlane* pl=new NxPlane(vec,d0);
projected=pl->project(orig);
res.fX=projected.x;
res.fY=projected.y;
res.fZ=projected.z;
return 1;
}
void plPhysXCooking::PCA(const NxVec3* points,int numPoints, NxMat33& out)
{
NxVec3 mean(0.f,0.f,0.f);
hsScalar Cov[3][3];
memset(Cov,0,9* sizeof hsScalar);
for(int i=0; i<numPoints;i++)
{
mean+=points[i];
}
mean=mean/(hsScalar)numPoints;
for(int i=0;i<numPoints;i++)
{
Cov[0][0]+=pow(points[i].x-mean.x ,2.0f)/(hsScalar)(numPoints);
Cov[1][1]+=pow(points[i].y-mean.y ,2.0f)/(hsScalar)(numPoints);
Cov[2][2]+=pow(points[i].z-mean.z ,2.0f)/(hsScalar)(numPoints);
Cov[0][1]+=(points[i].x-mean.x)*(points[i].y-mean.y)/(hsScalar)(numPoints);
Cov[0][2]+=(points[i].x-mean.x)*(points[i].z-mean.z)/(hsScalar)(numPoints);
Cov[1][2]+=(points[i].y-mean.y)*(points[i].z-mean.z)/(hsScalar)(numPoints);
}
Cov[2][0]=Cov[0][2];
Cov[1][0]=Cov[0][1];
Cov[2][1]=Cov[1][2];
NxF32 Covun[9];
for(int i=0;i<3;i++)
{
for(int j=0; j<3;j++)
{
Covun[3*i +j]=Cov[i][j];
}
}
NxVec3 eigenVals;
NxMat33 CovNx,Rot;
CovNx.setRowMajor(Covun);
if(fUtilLib==nil)Init();
NxDiagonalizeInertiaTensor(CovNx,eigenVals,out);
}
hsVectorStream* plPhysXCooking::IMakePolytope(const plMaxMeshExtractor::NeutralMesh& inMesh)
{
hsBool success=0;
std::vector<hsPoint3> outCloud;
hsPoint3 offset;
int numPlanes=26;
float planeMax[26];
int indexMax[26];
hsPoint3 AABBMin(FLT_MAX,FLT_MAX,FLT_MAX);
hsPoint3 AABBMax(-FLT_MAX,-FLT_MAX,-FLT_MAX);
//prep
NxVec3* vectors = TRACKED_NEW NxVec3[26];
int curvec=0;
for(int xcomp= -1;xcomp<2;xcomp++)
{
for(int ycomp= -1;ycomp<2;ycomp++)
{
for(int zcomp= -1;zcomp<2;zcomp++)
{
if(!((xcomp==0)&&(ycomp==0)&&(zcomp==0)))
{
vectors[curvec].set((hsScalar)(xcomp),(hsScalar)(ycomp),(hsScalar)(zcomp));
vectors[curvec].normalize();
planeMax[curvec]=(-FLT_MAX);
//indexMax[curvec]=0;
curvec++;
}
}
}
}
/*
for(int i=0;i<26;i++)
{//make your max and mins
planeMax[i]=(-FLT_MAX);
}
*/
hsPoint3 centroid(0.0f,0.0f,0.0f);
for(int i=0;i<inMesh.fNumVerts;i++) centroid+=inMesh.fVerts[i];
centroid=centroid/(float)inMesh.fNumVerts;
//temp
NxVec3* nxLocs=new NxVec3[inMesh.fNumVerts];
NxVec3* nxLocs2=new NxVec3[inMesh.fNumVerts];
for(int i=0;i<inMesh.fNumVerts;i++)
{
hsPoint3 temppt=inMesh.fVerts[i] - centroid;
nxLocs[i]=plPXConvert::Point(temppt);
}
NxMat33 rot;
NxVec3 eigen;
PCA(nxLocs,inMesh.fNumVerts,rot);
NxMat33 invrot;
rot.getInverse(invrot);
for(int i=0; i<inMesh.fNumVerts;i++)
{
nxLocs2[i]=invrot*nxLocs[i];
}
for(int i=0;i<inMesh.fNumVerts;i++)
{
for(int plane=0;plane<26;plane++)
{
float dist=nxLocs2[i].dot(vectors[plane]);
if(dist>=planeMax[plane])
{
planeMax[plane]=dist;
indexMax[plane]=i;
}
}
}
for(int i=0;i<inMesh.fNumVerts;i++)
{
AABBMin.fX = hsMinimum(nxLocs2[i].x, AABBMin.fX);
AABBMin.fY = hsMinimum(nxLocs2[i].y, AABBMin.fY);
AABBMin.fZ = hsMinimum(nxLocs2[i].z, AABBMin.fZ);
AABBMax.fX = hsMaximum(nxLocs2[i].x, AABBMax.fX);
AABBMax.fY = hsMaximum(nxLocs2[i].y, AABBMax.fY);
AABBMax.fZ = hsMaximum(nxLocs2[i].z, AABBMax.fZ);
}
int resultingPoints=0;
for(int i=0;i<26;i++)
{
for(int j=0;j<26;j++)
{
for(int k=0;k<26;k++)
{
NxVec3 res;
if(ThreePlaneIntersect(vectors[i],nxLocs2[indexMax[i]],vectors[j],nxLocs2[indexMax[j]], vectors[k],nxLocs2[indexMax[k]],res))
{
//check it is within all slabs
bool within=true;
int curplane=0;
do
{
float intersecdist=res.dot(vectors[curplane]);
if((intersecdist-planeMax[curplane])>0.0001)
{
within=false;
}
curplane++;
}
while((curplane<26)&&within);
if(within)
// if((res.x>=AABBMin.fX)&&(res.x<=AABBMax.fX)&&
// (res.y>=AABBMin.fY)&&(res.y<=AABBMax.fY)&&
// (res.z>=AABBMin.fZ)&&(res.z<=AABBMax.fZ))
{
NxVec3 reverted;
reverted=rot*res;
reverted.x=reverted.x +centroid.fX;
reverted.y=reverted.y +centroid.fY;
reverted.z=reverted.z +centroid.fZ;
hsPoint3 out;
out=plPXConvert::Point(reverted);
outCloud.push_back(out);
}
}
}
}
}
//planes discovered
//this is'nt right
//cleanup
offset=centroid;
delete[] vectors;
hsPoint3* pointages=TRACKED_NEW hsPoint3[outCloud.size()];
for(int x=0;x<outCloud.size();x++)pointages[x]=outCloud[x];
hsVectorStream* vectorstrm;
vectorstrm= CookHull(outCloud.size(),pointages,true);
delete[] pointages;
delete[] nxLocs;
delete[] nxLocs2;
return vectorstrm;
}

View File

@ -0,0 +1,80 @@
/*==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==*/
#ifndef plPhysXCooking_h_inc
#define plPhysXCooking_h_inc
#include "hsTypes.h"
#include "hsGeometry3.h"
#include "plMaxMeshExtractor.h"
class hsStream;
class hsVectorStream;
class NxConvexMesh;
class NxUtilLib;
class NxVec3;
class NxMat33;
class plPhysXCooking
{
public:
static void Init();
static void Shutdown();
static hsVectorStream* CookTrimesh(int nVerts, hsPoint3* verts, int nFaces, UInt16* faces);
static bool TestIfConvex(NxConvexMesh* convexMesh, int nVerts, hsPoint3* verts);
static hsVectorStream* CookHull(int nVerts, hsPoint3* verts,bool inflate);
static bool IsPointInsideHull(hsPlane3* hull, int nPlanes, const hsPoint3& pos);
static inline bool ITestPlane(const hsPoint3 &pos, const hsPlane3 &plane)
{
hsScalar dis = plane.fN.InnerProduct(pos);
dis += plane.fD;
if( dis > 0.f )
return false;
return true;
};
static void PCA(const NxVec3* points,int numPoints, NxMat33& out);
static NxUtilLib* fUtilLib;
static bool fSkipErrors;
static hsVectorStream* IMakePolytope(const plMaxMeshExtractor::NeutralMesh& inMesh);
};
#endif // plPhysXCooking_h_inc

View File

@ -0,0 +1,325 @@
/*==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 "HeadSpin.h"
#include "plPhysicalProps.h"
#include "../plPhysical/plSimDefs.h"
// For plBoundsType
#include "../pnSceneObject/plSimulationInterface.h"
#include "plMaxNode.h"
#include "../MaxExport/plErrorMsg.h"
/** These enums are used to indicate which parameters are ignorable and can
be overridden.
We can't use the "PhysFlags," below, for this, because those only cover boolean properties.
*** We should use the same enum for both and just not worry that some of the enums aren't
usable as "ignore" flags, -- the readability & simplification gain would be worth it. */
enum CanIgnore
{
kMemberGroup = 0x1,
kBounceGroup = 0x2,
kReportGroup = 0x4,
kMass = 0x8,
kFriction = 0x10,
kRestitution = 0x20,
kBoundsType = 0x40,
kProxyNode = 0x80,
kPinned = 0x100,
kAlignToOwner = 0x200,
kCameraAvoid = 0x400,
kPhysAnim = 0x800,
kCanIgnoreLOSBlockCamera = 0x1000,
kCanIgnoreLOSBlockUI = 0x2000,
kCanIgnoreLOSUIItem = 0x4000,
kCanIgnoreLOSBlockCustom = 0x8000,
kCanIgnoreLOSShootable = 0x10000,
kCanIgnoreLOSAvatarWalkable = 0x20000,
kCanIgnoreLOSSwimRegion = 0x40000,
kAll = 0xffffffff
};
enum PhysFlags
{
kFlagPinned = 0x1,
kFlagAlignToOwner = 0x2,
kFlagCameraAvoid = 0x4,
kFlagPhysAnim = 0x8,
kFlagStartInactive = 0x10,
kFlagNoSynchronize = 0x20,
kFlagLOSBlockCamera = 0x40,
kFlagLOSBlockUI = 0x80,
kFlagLOSUIItem = 0x100,
kFlagLOSBlockCustom = 0x200,
kFlagLOSShootable = 0x400,
kFlagLOSAvatarWalkable = 0x800,
kFlagLOSSwimRegion = 0x1000,
};
plPhysicalProps::plPhysicalProps() :
fUsed(false),
fCanIgnore(kAll),
fGroup(0),
fReportGroup(0),
fMass(0),
fFriction(0),
fRestitution(0),
fBoundsType(plSimDefs::kHullBounds),
fProxyNode(nil),
fFlags(0),
fSubworld(nil),
fNoSynchronize(0),
fStartInactive(0),
fAvAnimPushable(0)
{
}
bool plPhysicalProps::SetGroup(UInt32 group, plMaxNode *node, plErrorMsg *errMsg, bool canIgnore)
{
return ISetParam(fGroup, group, kMemberGroup, canIgnore, node, errMsg);
}
bool plPhysicalProps::SetReportGroup(UInt32 notifyGroup, plMaxNode *node, plErrorMsg *errMsg, bool canIgnore)
{
return ISetParam(fReportGroup, notifyGroup, kReportGroup, canIgnore, node, errMsg);
}
bool plPhysicalProps::SetMass(float mass, plMaxNode *node, plErrorMsg *errMsg, bool canIgnore)
{
if(mass != 0.0f)
{
if (!GetPinned())
node->SetMovable(true);
node->SetForceLocal(true);
}
return ISetParam(fMass, mass, kMass, canIgnore, node, errMsg);
}
bool plPhysicalProps::SetFriction(float friction, plMaxNode *node, plErrorMsg *errMsg, bool canIgnore)
{
return ISetParam(fFriction, friction, kFriction, canIgnore, node, errMsg);
}
bool plPhysicalProps::SetRestitution(float restitution, plMaxNode *node, plErrorMsg *errMsg, bool canIgnore)
{
return ISetParam(fRestitution, restitution, kRestitution, canIgnore, node, errMsg);
}
bool plPhysicalProps::SetBoundsType(int boundsType, plMaxNode *node, plErrorMsg *errMsg, bool canIgnore)
{
hsAssert(boundsType >= 1 && boundsType < plSimDefs::kNumBounds, "Bad bounds type");
return ISetParam(fBoundsType, boundsType, kBoundsType, canIgnore, node, errMsg);
}
bool plPhysicalProps::SetProxyNode(plMaxNode *proxyNode, plMaxNode *node, plErrorMsg *errMsg, bool canIgnore)
{
if( proxyNode )
proxyNode->SetDrawable(false);
return ISetParam(fProxyNode, proxyNode, kProxyNode, canIgnore, node, errMsg);
}
bool plPhysicalProps::IGetFlagParam(int flagType)
{
return ((fFlags & flagType) != 0);
}
bool plPhysicalProps::ISetFlagParam(bool val, int flagType, int type, bool canIgnore, plMaxNode *node, plErrorMsg *errMsg)
{
bool ourVal = IGetFlagParam(flagType);
if (ISetParam(ourVal, val, type, canIgnore, node, errMsg))
{
if (ourVal)
fFlags |= flagType;
else
fFlags &= ~flagType;
return true;
}
return false;
}
bool plPhysicalProps::SetPinned(bool status, plMaxNode *node, plErrorMsg *errMsg, bool canIgnore)
{
return ISetFlagParam(status, kFlagPinned, kPinned, canIgnore, node, errMsg);
}
bool plPhysicalProps::SetLOSBlockCamera(bool status, plMaxNode *node, plErrorMsg *errMsg, bool canIgnore)
{
return ISetFlagParam(status, kFlagLOSBlockCamera, kCanIgnoreLOSBlockCamera, canIgnore, node, errMsg);
}
bool plPhysicalProps::GetLOSBlockCamera()
{
return IGetFlagParam(kFlagLOSBlockCamera);
}
bool plPhysicalProps::SetLOSBlockUI(bool status, plMaxNode *node, plErrorMsg *errMsg, bool canIgnore)
{
return ISetFlagParam(status, kFlagLOSBlockUI, kCanIgnoreLOSBlockUI, canIgnore, node, errMsg);
}
bool plPhysicalProps::GetLOSBlockUI()
{
return IGetFlagParam(kFlagLOSBlockUI);
}
bool plPhysicalProps::SetLOSUIItem(bool status, plMaxNode *node, plErrorMsg *errMsg, bool canIgnore)
{
return ISetFlagParam(status, kFlagLOSUIItem, kCanIgnoreLOSUIItem, canIgnore, node, errMsg);
}
bool plPhysicalProps::GetLOSUIItem()
{
return IGetFlagParam(kFlagLOSUIItem);
}
bool plPhysicalProps::SetLOSBlockCustom(bool status, plMaxNode *node, plErrorMsg *errMsg, bool canIgnore)
{
return ISetFlagParam(status, kFlagLOSBlockCustom, kCanIgnoreLOSBlockCustom, canIgnore, node, errMsg);
}
bool plPhysicalProps::GetLOSBlockCustom()
{
return IGetFlagParam(kFlagLOSBlockCustom);
}
bool plPhysicalProps::SetCameraAvoidFlag(bool allowLOS, plMaxNode *node, plErrorMsg *errMsg, bool canIgnore)
{
return ISetFlagParam(allowLOS, kFlagCameraAvoid, kCameraAvoid, canIgnore, node, errMsg);
}
bool plPhysicalProps::SetLOSShootable(bool status, plMaxNode *node, plErrorMsg *errMsg, bool canIgnore)
{
return ISetFlagParam(status, kFlagLOSShootable, kCanIgnoreLOSShootable, canIgnore, node, errMsg);
}
bool plPhysicalProps::GetLOSShootable()
{
return IGetFlagParam(kFlagLOSShootable);
}
bool plPhysicalProps::SetLOSAvatarWalkable(bool status, plMaxNode *node, plErrorMsg *errMsg, bool canIgnore)
{
return ISetFlagParam(status, kFlagLOSAvatarWalkable, kCanIgnoreLOSAvatarWalkable, canIgnore, node, errMsg);
}
bool plPhysicalProps::GetLOSAvatarWalkable()
{
return IGetFlagParam(kFlagLOSAvatarWalkable);
}
bool plPhysicalProps::SetLOSSwimRegion(bool status, plMaxNode *node, plErrorMsg *errMsg, bool canIgnore)
{
return ISetFlagParam(status, kFlagLOSSwimRegion, kCanIgnoreLOSSwimRegion, canIgnore, node, errMsg);
}
bool plPhysicalProps::GetLOSSwimRegion()
{
return IGetFlagParam(kFlagLOSSwimRegion);
}
//bool plPhysicalProps::SetUILOSFlag(bool allowLOS, plMaxNode *node, plErrorMsg *errMsg, bool canIgnore)
//{
// return ISetFlagParam(allowLOS, kFlagUILOS, kUILOS, canIgnore, node, errMsg);
//}
bool plPhysicalProps::SetAlignToOwner(bool alignToOwner, plMaxNode *node, plErrorMsg *errMsg, bool canIgnore)
{
return ISetFlagParam(alignToOwner, kFlagAlignToOwner, kAlignToOwner, canIgnore, node, errMsg);
}
bool plPhysicalProps::SetSubworld(plMaxNode* subworld)
{
// Note that we do *not* set fUsed, because we don't (necessarily) want a physical for this node.
// We just want to remember that it is a subworld.
fSubworld = subworld;
return true;
}
bool plPhysicalProps::SetPhysAnim(bool anim, plMaxNode *node, plErrorMsg *errMsg, bool canIgnore)
{
return ISetFlagParam(anim, kFlagPhysAnim, kPhysAnim, canIgnore, node, errMsg);
}
bool plPhysicalProps::GetPinned()
{
return IGetFlagParam(kFlagPinned);
}
bool plPhysicalProps::GetCameraAvoid()
{
return IGetFlagParam(kFlagCameraAvoid);
}
bool plPhysicalProps::GetAlignToOwner()
{
return IGetFlagParam(kFlagAlignToOwner);
}
bool plPhysicalProps::GetPhysAnim()
{
return IGetFlagParam(kFlagPhysAnim);
}
void plPhysicalProps::SetCanIgnore(UInt32 type, bool canIgnore)
{
if (canIgnore)
fCanIgnore |= type;
else
fCanIgnore &= ~type;
}
bool plPhysicalProps::CanIgnore(UInt32 type)
{
return ((fCanIgnore & type) != 0);
}
void plPhysicalProps::IDisplayErrorMsg(plMaxNode *node, plErrorMsg *errMsg)
{
if (!errMsg->IsBogus())
{
errMsg->Set(true,
"Physics Conflict",
"The node \"%s\" has a conflict in its physical settings.\nMake sure the physical components on it are compatible.",
node->GetName()).Show();
}
}

View File

@ -0,0 +1,179 @@
/*==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==*/
#ifndef plPhysicalProps_h_inc
#define plPhysicalProps_h_inc
#include "hsTypes.h"
#include "..\..\NucleusLib\pnKeyedObject\plKey.h"
class plMaxNode;
class plErrorMsg;
class plPhysicalProps
{
public:
//
// Set canIgnore to true if it is OK for someone else's setting to override yours
// If any of the Set functions return false, there was a conflict and the export will be aborted.
//
bool SetGroup(UInt32 group, plMaxNode *node, plErrorMsg *errMsg, bool canIgnore=false);
bool SetReportGroup(UInt32 notifyGroup, plMaxNode *node, plErrorMsg *errMsg, bool canIgnore=false);
bool SetMass(float mass, plMaxNode *node, plErrorMsg *errMsg, bool canIgnore=false);
bool SetFriction(float friction, plMaxNode *node, plErrorMsg *errMsg, bool canIgnore=false);
bool SetRestitution(float restitution, plMaxNode *node, plErrorMsg *errMsg, bool canIgnore=false);
// From plBoundsType
bool SetBoundsType(int boundsType, plMaxNode *node, plErrorMsg *errMsg, bool canIgnore=false);
// An alternate node for the physical to be created from
bool SetProxyNode(plMaxNode *proxyNode, plMaxNode *node, plErrorMsg *errMsg, bool canIgnore=false);
// If you're going to pin a node and set its mass greater than zero, do the pin first.
// That way it will not be flagged as movable.
bool SetPinned(bool pinned, plMaxNode *node, plErrorMsg *errMsg, bool canIgnore=false);
/** Allow line-of-sight-checks to pass through this object.
Set to true if you don't want this object to block LOS probes.
Set to false if you do want this object to block LOS probes. */
bool SetAlignToOwner(bool alignToOwner, plMaxNode *node, plErrorMsg *errMsg, bool canIgnore=false);
bool SetCameraAvoidFlag(bool allowLOS, plMaxNode *node, plErrorMsg *errMsg, bool canIgnore=false);
// bool SetAllowLOS(bool allowLOS, plMaxNode *node, plErrorMsg *errMsg, bool canIgnore=false);
// bool SetCameraLOSFlag(bool allowLOS, plMaxNode *node, plErrorMsg *errMsg, bool canIgnore=false);
// bool SetUILOSFlag(bool allowLOS, plMaxNode *node, plErrorMsg *errMsg, bool canIgnore=false);
// New LOS Types....
bool SetLOSBlockCamera(bool status, plMaxNode *node, plErrorMsg *errMsg, bool canIgnore = false);
bool SetLOSBlockUI(bool status, plMaxNode *node, plErrorMsg *errMsg, bool canIgnore = false);
bool SetLOSUIItem(bool status, plMaxNode *node, plErrorMsg *errMsg, bool canIgnore = false);
bool SetLOSBlockCustom(bool status, plMaxNode *node, plErrorMsg *errMsg, bool canIgnore = false);
bool SetLOSShootable(bool status, plMaxNode *node, plErrorMsg *errMsg, bool canIgnore= false);
bool SetLOSAvatarWalkable(bool status, plMaxNode *node, plErrorMsg *errMsg, bool canIgnore= false);
bool SetLOSSwimRegion(bool status, plMaxNode *node, plErrorMsg *errMsg, bool canIgnore = false);
bool SetSubworld(plMaxNode* subworld);
bool SetPhysAnim(bool anim, plMaxNode *node, plErrorMsg *errMsg, bool canIgnore=false);
void SetStartInactive(int on) { fStartInactive = on; };
void SetNoSynchronize(int on) { fNoSynchronize = on; };
void SetAvAnimPushable(int on) { fAvAnimPushable = on; };
bool IsUsed() { return fUsed; }
UInt32 GetGroup() { return fGroup; }
UInt32 GetReportGroup() { return fReportGroup; }
float GetMass() { return fMass; }
float GetFriction() { return fFriction; }
float GetRestitution() { return fRestitution; }
int GetBoundsType() { return fBoundsType; }
plMaxNode* GetProxyNode() { return fProxyNode; }
bool GetPinned();
bool GetCameraAvoid();
bool GetAlignToOwner();
plMaxNode* GetSubworld() { return fSubworld; }
bool GetPhysAnim();
// New LOS Types
bool GetLOSBlockCamera();
bool GetLOSBlockUI();
bool GetLOSUIItem();
bool GetLOSBlockCustom();
bool GetLOSShootable();
bool GetLOSAvatarWalkable();
bool GetLOSSwimRegion();
int GetStartInactive() { return fStartInactive; };
int GetNoSynchronize() { return fNoSynchronize; };
int GetAvAnimPushable() { return fAvAnimPushable; };
protected:
bool fUsed;
UInt32 fCanIgnore;
UInt32 fGroup;
UInt32 fReportGroup;
float fMass;
float fFriction;
float fRestitution;
int fBoundsType;
plMaxNode *fProxyNode;
UInt32 fFlags;
plMaxNode* fSubworld;
int fStartInactive;
int fNoSynchronize;
int fAvAnimPushable;
bool IGetFlagParam(int flagType);
bool ISetFlagParam(bool val, int flagType, int type, bool canIgnore, plMaxNode *node, plErrorMsg *errMsg);
// Because VC++ sucks, this has to be inlined.
template <class T> bool ISetParam(T& ourVal, T& theirVal, int type, bool otherCanIgnore, plMaxNode *node, plErrorMsg *errMsg)
{
fUsed = true;
if (ourVal != theirVal)
{
if (CanIgnore(type))
{
ourVal = theirVal;
if (!otherCanIgnore)
SetCanIgnore(type, false);
}
else if (!otherCanIgnore)
{
IDisplayErrorMsg(node, errMsg);
fUsed = false;
return false;
}
}
return true;
}
void SetCanIgnore(UInt32 type, bool canIgnore);
bool CanIgnore(UInt32 type);
void IDisplayErrorMsg(plMaxNode *node, plErrorMsg *errMsg);
// Only plMaxNodeData can create these
plPhysicalProps();
friend class plMaxNodeData;
};
#endif // plPhysicalProps_h_inc

View File

@ -0,0 +1,54 @@
/*==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==*/
//
// This message is used to notify the SceneWatcher of changes in the materials.
// There is a refmsg sent out when material parameters change, but for some
// reason it is not propogated to the node that the material is applied to.
// User refmsgs always make it through though.
//
#define REFMSG_USER_MAT REFMSG_USER+1
#define REFMSG_USER_TARGET_ADD REFMSG_USER+2
#define REFMSG_USER_TARGET_DELETE REFMSG_USER+3
#define REFMSG_USER_COMP_REF_CHANGED REFMSG_USER+4

View File

@ -0,0 +1,541 @@
/*==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 "HeadSpin.h"
#include "plPluginResManager.h"
#include "hsTypes.h"
#include "hsTemplates.h"
#include "../plResMgr/plRegistryNode.h"
#include "../plResMgr/plRegistryHelpers.h"
#include "../plResMgr/plVersion.h"
#include "../plResMgr/plResMgrSettings.h"
#include "../plScene/plSceneNode.h"
#include "../pnKeyedObject/plKey.h"
#include "../pnKeyedObject/plKeyImp.h"
#include "../plAgeDescription/plAgeDescription.h"
#include "plgDispatch.h"
// For our common object libs
#include "plCommonObjLib.h"
#include "../MaxComponent/plMiscComponents.h"
plKey plPluginResManager::NameToLoc(const char* age, const char* page, Int32 sequenceNumber, hsBool itinerant)
{
// Hack for now--always prefer paging out sceneNodes first
fPageOutHint = plSceneNode::Index();
// Get or create our page
plRegistryPageNode* pageNode = INameToPage(age, page, sequenceNumber, itinerant);
hsAssert(pageNode != nil, "No page returned from INameToPage(), shouldn't be possible");
// Go find the sceneNode now, since we know the page exists (go through our normal channels, though)
char keyName[256];
sprintf(keyName, "%s_%s", age, page);
plUoid nodeUoid(pageNode->GetPageInfo().GetLocation(), plSceneNode::Index(), keyName);
plKey snKey = FindKey(nodeUoid);
if (snKey == nil)
{
// Not found, create a new one
plSceneNode *newSceneNode = TRACKED_NEW plSceneNode;
snKey = NewKey(keyName, newSceneNode, pageNode->GetPageInfo().GetLocation());
// Call init after it gets a key
newSceneNode->Init();
// Add to our list of exported nodes
fExportedNodes.Append(newSceneNode);
newSceneNode->GetKey()->RefObject();
}
else
{
hsAssert(snKey->ObjectIsLoaded() != nil, "Somehow we still have the key for a sceneNode that hasn't been loaded.");
// Force load, or attempt to at least
plSceneNode* node = plSceneNode::ConvertNoRef(snKey->VerifyLoaded());
// Add to our list if necessary
if (fExportedNodes.Find(node) == fExportedNodes.kMissingIndex)
{
fExportedNodes.Append(node);
node->GetKey()->RefObject();
}
}
// Return the key
return snKey;
}
//// INameToPage /////////////////////////////////////////////////////////////
// Given the age/chapter/page combo we all know and love, plus an optional
// seqNumber, returns the page for that combo (either by preloading it or
// by creating it).
plRegistryPageNode* plPluginResManager::INameToPage(const char* age, const char* page, Int32 sequenceNumber, hsBool itinerant)
{
// Find the location first, to see if it already exists
plRegistryPageNode* pageNode = FindPage(age, page);
if (pageNode == nil)
{
// This page does not yet exist, so create a new page
if (sequenceNumber != UInt32(-1))
{
const plLocation& newLoc = ICreateLocation(age, page, sequenceNumber, itinerant);
pageNode = CreatePage(newLoc, age, page);
}
else
{
const plLocation& newLoc = ICreateLocation(age, page, itinerant);
pageNode = CreatePage(newLoc, age, page);
}
// Still preload textures on this guy. This should be a no-op for this page since it's new, but won't be
// for the shared textures page
IPreLoadTextures(pageNode, sequenceNumber);
}
else if (!pageNode->IsNewPage())
{
// Node's already in our registry (i.e. already stored somewhere), so make sure it loads so
// we can update from that
LoadPageKeys(pageNode);
// Now clear out all the unwanted keys.
IPreLoadTextures(pageNode, sequenceNumber);
}
return pageNode;
}
//// plCommonKeyDistributor //////////////////////////////////////////////////
// Iterator that takes the keys in a common page and distributes them to
// whichever commonObjectLibs are interested in them.
class plCommonKeyDistributor : public plRegistryKeyIterator
{
plPluginResManager* fMgr;
public:
plCommonKeyDistributor(plPluginResManager* mgr) : fMgr(mgr) {}
virtual hsBool EatKey(const plKey& key)
{
UInt32 count = plCommonObjLib::GetNumLibs();
for (UInt32 i = 0; i < count; i++)
{
plCommonObjLib* lib = plCommonObjLib::GetLib(i);
if (lib->IsInteresting(key))
{
// Lib wants this guy, so load the object and add it
// Note: we want to switch to passive mode here, so any keys read in
// will NOT force a load on whichever page those keys belong to. Otherwise,
// we'd have to load that entire page and ref all the objects all over
// again and I just really don't want to do that...
plResMgrSettings::Get().SetPassiveKeyRead(true);
hsKeyedObject* object = key->VerifyLoaded();
plResMgrSettings::Get().SetPassiveKeyRead(false);
lib->AddObject(object);
break;
}
}
return true;
}
};
//// IPreLoadTextures ////////////////////////////////////////////////////////
// Given a page of loaded keys, culls through them and make sure all our
// registered commonObjectLibs get them as if we had just converted them.
// Note: Broken out in a separate function 5.31.2002 mcn to facilitate
// pre-loading textures exported to our special textures page.
void plPluginResManager::IPreLoadTextures(plRegistryPageNode* pageNode, Int32 origSeqNumber)
{
// For common pages, we want to kinda-maybe-load all the objects so they don't get wiped when we
// re-export them. However, we don't have a good way of telling whether a page is a common page,
// which is where this hack comes in
bool common = false;
for (int i = 0; i < plAgeDescription::kNumCommonPages; i++)
{
if (hsStrCaseEQ(plAgeDescription::GetCommonPage(i), pageNode->GetPageInfo().GetPage()))
{
common = true;
break;
}
}
if (common)
{
// Iterate through all the keys in our page, scattering them to various objectLibs if they're
// interested. If nobody likes them, they get unreffed and disappear.
plCommonKeyDistributor distributor(this);
pageNode->IterateKeys(&distributor);
}
// Clear out all the unwanted keys in the page we just loaded (by implication; they won't clear if we already
// stored the keys via our objectLibs above)
{
class plEmptyIterator : public plRegistryKeyIterator
{
public:
virtual hsBool EatKey(const plKey& key) { return true; }
} empty;
pageNode->IterateKeys(&empty);
}
// We've loaded anything we needed from this page now, so set it as new so
// that we won't try loading again
pageNode->SetNewPage();
// Get our texture page now, if we're not a texture page
if (!common)
{
// Make sure it's not a global page we're handling either
if (!pageNode->GetPageInfo().GetLocation().IsReserved())
{
Int32 texSeqNum = -1;
if (origSeqNumber != -1)
texSeqNum = plPageInfoUtils::GetCommonSeqNumFromNormal(origSeqNumber, plAgeDescription::kTextures);
// Note: INameToPage will turn around and call us again, so no need to do the call twice
plRegistryPageNode* texturePage = INameToPage(pageNode->GetPageInfo().GetAge(),
plAgeDescription::GetCommonPage(plAgeDescription::kTextures), texSeqNum);
hsAssert(texturePage != nil, "Unable to get or create the shared textures page? Shouldn't be possible.");
// Do the other one
Int32 commonSeqNum = -1;
if (origSeqNumber != -1)
commonSeqNum = plPageInfoUtils::GetCommonSeqNumFromNormal(origSeqNumber, plAgeDescription::kGlobal);
// Note: INameToPage will turn around and call us again, so no need to do the call twice
plRegistryPageNode* commonPage = INameToPage(pageNode->GetPageInfo().GetAge(),
plAgeDescription::GetCommonPage(plAgeDescription::kGlobal),
commonSeqNum);
hsAssert(commonPage != nil, "Unable to get or create the shared built-in page? Shouldn't be possible.");
}
}
}
//// GetCommonPage ///////////////////////////////////////////////////////////
// Given a plLocation, finds the texture page that's in the same age and
// returns its location.
const plLocation& plPluginResManager::GetCommonPage(const plLocation &sisterPage, int whichPage)
{
if (sisterPage.IsReserved())
return sisterPage; // Reserved pages have no common pages
plRegistryPageNode* page = FindPage(sisterPage);
if (page == nil)
{
hsAssert(false, "Trying to find the sister common page to a page that doesn't exist!");
return sisterPage;
}
// Find the common page in the same age as this one
plRegistryPageNode* commonPage = FindPage(page->GetPageInfo().GetAge(),
plAgeDescription::GetCommonPage(whichPage));
if (commonPage == nil)
{
hsAssert(false, "Unable to find sister common page to this page");
return sisterPage;
}
return commonPage->GetPageInfo().GetLocation();
}
//// IShutdown ///////////////////////////////////////////////////////////////
void plPluginResManager::IShutdown()
{
if (!fInited)
return;
// Loop through all the commonObjLibs and clear their object lists, just
// as a safety measure (the creators of the various libs should really
// be doing it)
for (UInt32 i = 0; i < plCommonObjLib::GetNumLibs(); i++)
plCommonObjLib::GetLib(i)->ClearObjectList();
plResManager::IShutdown();
}
// Little finder class to, erm, find unused location sequence numbers
class plSeqNumberFinder : public plRegistryPageIterator
{
protected:
Int32& fSeqNum;
hsBool fWillBeReserved;
public:
plSeqNumberFinder(Int32& seqNum, hsBool willBeReserved) : fSeqNum(seqNum), fWillBeReserved(willBeReserved) {}
virtual hsBool EatPage(plRegistryPageNode* page)
{
if (fSeqNum <= page->GetPageInfo().GetLocation().GetSequenceNumber() &&
fWillBeReserved == page->GetPageInfo().GetLocation().IsReserved())
fSeqNum = page->GetPageInfo().GetLocation().GetSequenceNumber() + 1;
return true;
}
};
plLocation plPluginResManager::ICreateLocation(const char* age, const char* page, hsBool itinerant)
{
Int32 seqNum = VerifySeqNumber(0, age, page);
return ICreateLocation(age, page, seqNum, itinerant);
}
plLocation plPluginResManager::ICreateLocation(const char* age, const char* page, Int32 seqNum, hsBool itinerant)
{
hsBool willBeReserved = hsStrCaseEQ(age, "global");
Int32 oldNum = seqNum;
seqNum = VerifySeqNumber(seqNum, age, page);
if (seqNum != oldNum)
{
hsAssert(false, "Conflicting page sequence number. Somebody called NameToLoc without verifying their seq# first!");
}
if (seqNum < 0)
{
willBeReserved = true;
seqNum = -seqNum;
}
plLocation newLoc;
if (willBeReserved)
newLoc = plLocation::MakeReserved(seqNum);
else
newLoc = plLocation::MakeNormal(seqNum);
// Flag common pages
for (int i = 0; i < plAgeDescription::kNumCommonPages; i++)
{
if (hsStrEQ(plAgeDescription::GetCommonPage(i), page))
{
newLoc.SetFlags(plLocation::kBuiltIn);
break;
}
}
// If we have an age description file for the age we're creating a location
// for, grab some extra flags from it
plAgeDescription* ageDesc = plPageInfoUtils::GetAgeDesc(age);
plAgePage* agePage = ageDesc ? ageDesc->FindPage(page) : nil;
if (agePage)
{
if (agePage->GetFlags() & plAgePage::kIsLocalOnly)
newLoc.SetFlags(plLocation::kLocalOnly);
if (agePage->GetFlags() & plAgePage::kIsVolatile)
newLoc.SetFlags(plLocation::kVolatile);
}
if (itinerant)
newLoc.SetFlags(plLocation::kItinerant);
delete ageDesc;
return newLoc;
}
class plWritePageIterator : public plRegistryPageIterator
{
public:
plWritePageIterator() {}
virtual hsBool EatPage(plRegistryPageNode *page)
{
if (page->GetPageInfo().GetLocation() != plLocation::kGlobalFixedLoc)
page->Write();
return true;
}
};
void plPluginResManager::WriteAllPages()
{
plWritePageIterator iter;
IteratePages(&iter);
}
//// EndExport ///////////////////////////////////////////////////////////////
// Called after export is done and pages are all written out. Cleans up
// by paging out all the sceneNodes we just created.
void plPluginResManager::EndExport()
{
for (int i = 0; i < fExportedNodes.GetCount(); i++)
{
if (fExportedNodes[i] != nil)
fExportedNodes[i]->GetKey()->UnRefObject();
}
fExportedNodes.Reset();
for( i = 0; i < fLooseEnds.GetCount(); i++ )
{
if( fLooseEnds[i] )
fLooseEnds[i]->UnRefObject();
}
fLooseEnds.Reset();
// Flush the message queue, so all the messages for paging out stuff actually get delivered
plgDispatch::Dispatch()->MsgQueueProcess();
}
void plPluginResManager::AddLooseEnd(plKey key)
{
if( key )
{
key->RefObject();
fLooseEnds.Append(key);
}
}
// Verifies that the given sequence number belongs to the given string combo and ONLY that combo. Returns a new, unique sequenceNumber if not
Int32 plPluginResManager::VerifySeqNumber(Int32 sequenceNumber, const char* age, const char* page)
{
hsBool negated = false, willBeReserved = hsStrCaseEQ(age, "global");
if (sequenceNumber < 0)
{
sequenceNumber = -sequenceNumber;
willBeReserved = negated = true;
}
fLastVerifyError = kNoVerifyError;
fLastVerifyPage = nil;
plLocation toCompareTo;
if (willBeReserved)
plLocation::MakeReserved(sequenceNumber);
else
plLocation::MakeNormal(sequenceNumber);
// Does the page already exist?
plRegistryPageNode* pageNode = FindPage(age, page);
if (pageNode != nil)
{
if (pageNode->GetPageInfo().GetLocation() == toCompareTo)
// Right page, right sequence #. Assume we're smart enough to already have it right
return negated ? -sequenceNumber : sequenceNumber;
// Right page, wrong seq #...tag our last error field so we can know this later on
fLastVerifyError = kErrRightPageWrongSeq;
}
// Page doesn't yet exist, check to make sure the seq # isn't used yet
if (sequenceNumber > 0)
{
pageNode = FindPage(toCompareTo);
if (pageNode == nil)
// Safe to use
return negated ? -sequenceNumber : sequenceNumber;
else
{
// If there is no error yet, set the error to "already taken"
if (fLastVerifyError == kNoVerifyError)
fLastVerifyError = kErrSeqAlreadyTaken;
fLastVerifyPage = &pageNode->GetPageInfo();
}
}
// Gotta find a good sequence number to use, so keep searching until we find one
// (but start at a good high number so we won't hopefully ever run into anybody else)
const int kTemporarySequenceStartPrefix = 100; // can't be larger then 0xFE, so well start out at 100 for kicks
sequenceNumber = plPageInfoUtils::CombineSeqNum(kTemporarySequenceStartPrefix, 0);
Int32 upperLimit = 0xFEFFFF; // largest legal sequence number is a prefix of FE and a suffix of FFFF
for(; sequenceNumber < upperLimit; sequenceNumber++)
{
if (willBeReserved)
toCompareTo = plLocation::MakeReserved(sequenceNumber);
else
toCompareTo = plLocation::MakeNormal(sequenceNumber);
pageNode = FindPage(toCompareTo);
if (pageNode == nil)
return negated ? -sequenceNumber : sequenceNumber;
}
hsAssert(false, "Unable to find a valid sequence number to use");
fLastVerifyError = kErrCantFindValid;
return 0;
}
//// NukeKeyAndObject ////////////////////////////////////////////////////////
// Given a key, will ref and unref the associated object so it goes away,
// then nukes the key and sets it to nil. The key's UOID should be safe to
// reuse at that point, unless someone else still has a ref, in which case
// this function returns false (returns true if successful).
bool plPluginResManager::NukeKeyAndObject(plKey& objectKey)
{
class plPublicRefKey : public plKeyImp
{
public:
UInt16 GetRefCount() const { return fRefCount; }
};
plKeyImp* keyData = (plKeyImp*)objectKey;
// Check the ref count on the object. Nobody should have a ref to it
// except the key
hsKeyedObject* object = objectKey->ObjectIsLoaded();
if (object != nil)
{
if (keyData->GetActiveRefs())
// Somebody still has a ref to this object, so we can't nuke it
return false;
}
// Nobody has a ref to the object, so we're clear to nuke
keyData->SetObjectPtr(nil);
// Check the key. The refcount should be 1 at this point, for the copy
// we're holding in this function. Nobody else should be holding the key
// now that the object is gone.
if (((plPublicRefKey*)keyData)->GetRefCount() > 1)
return false;
// Nuke out the key as well
objectKey = nil;
// All done!
return true;
}

View File

@ -0,0 +1,114 @@
/*==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==*/
#ifndef plPluginResManager_h_inc
#define plPluginResManager_h_inc
#include "../plResMgr/plResManager.h"
#include "../pnKeyedObject/plKey.h"
#include "hsTemplates.h"
class plPageInfo;
class plRegistryPageNode;
class plSceneNode;
class plPluginResManager : public plResManager
{
public:
static plPluginResManager* ResMgr() { return (plPluginResManager*)hsgResMgr::ResMgr(); }
//------------------------
// Location management
//------------------------
// Given a page string combo, returns the key of the sceneNode for that page. If the page does not exist, it creates one.
plKey NameToLoc(const char* age, const char* page, Int32 sequenceNumber, hsBool itinerant = false);
// Verifies that the given sequence number belongs to the given string combo and ONLY that combo. Returns a new, unique sequenceNumber if not
Int32 VerifySeqNumber(Int32 sequenceNumber, const char* age, const char* page);
enum VerifyErrors
{
kNoVerifyError,
kErrRightPageWrongSeq,
kErrSeqAlreadyTaken,
kErrCantFindValid
};
VerifyErrors GetLastVerifyError() const { return fLastVerifyError; }
const plPageInfo* GetLastVerifyPage() const { return fLastVerifyPage; }
// Write all pages. Duh.
void WriteAllPages();
// Given a location, returns the plLocation corresponding to the common page from the same age
const plLocation& GetCommonPage(const plLocation& sisterPage, int whichPage);
// If we have the key of an object that needs to get written out, but we're too lazy to set up
// a proper reference too (e.g. adding it to a scenenode), we can add it here. On add, it will be RefObject()'d,
// and then after we've written out everything, it will be UnRefObject()'d (at the same time we UnRef all
// our scenenodes in EndExport.
void AddLooseEnd(plKey key);
// Given a key, will ref and unref the associated object so it goes away, then nukes the key and sets it to nil.
// The key's UOID should be safe to reuse at that point, unless someone else still has a ref, in which case
// this function returns false (returns true if successful).
bool NukeKeyAndObject(plKey& objectKey);
// Flushes all the created scene nodes out
void EndExport();
protected:
plLocation ICreateLocation(const char* age, const char* page, hsBool itinerant);
plLocation ICreateLocation(const char* age, const char* page, Int32 seqNum, hsBool itinerant);
plRegistryPageNode* INameToPage(const char* age, const char* page, Int32 sequenceNumber, hsBool itinerant = false);
void IPreLoadTextures(plRegistryPageNode* pageNode, Int32 origSeqNumber);
void IShutdown();
VerifyErrors fLastVerifyError;
const plPageInfo* fLastVerifyPage;
hsTArray<plSceneNode*> fExportedNodes;
hsTArray<plKey> fLooseEnds;
};
#endif // plPluginResManager_h_inc

View File

@ -0,0 +1,650 @@
/*==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 "HeadSpin.h"
#include "plPythonMgr.h"
#include "../MaxComponent/plAutoUIBlock.h"
//#include "Python.h"
#include "plMaxCFGFile.h"
#include "../plFile/hsFiles.h"
#include "plgDispatch.h"
#include "../pfPython/cyPythonInterface.h"
#include "hsUtils.h"
plPythonMgr::plPythonMgr()
{
}
plPythonMgr& plPythonMgr::Instance()
{
static plPythonMgr theInstance;
return theInstance;
}
// Python wants char, not const char, LAME!
static char* kGetBlockID = "glue_getBlockID";
static char* kGetClassName = "glue_getClassName";
static char* kGetNumParams = "glue_getNumParams";
static char* kGetParam = "glue_getParam";
static char* kGetVersion = "glue_getVersion";
static char* kIsMultiModifier = "glue_isMultiModifier";
static char* kGetVisInfo = "glue_getVisInfo";
bool ICallVoidFunc(PyObject *dict, char *funcName, PyObject*& val)
{
PyObject *func = PyDict_GetItemString(dict, (char*)funcName);
if (func )
{
if (PyCallable_Check(func))
{
val = PyObject_CallFunction(func, NULL);
if (val)
{
// there might have been some message printed, so get it out to the log file
PythonInterface::getOutputAndReset();
return true;
}
// There was an error when calling the function
// get the error message
PyErr_Print();
PyErr_Clear();
PythonInterface::getOutputAndReset();
}
}
return false;
}
bool ICallIntFunc(PyObject *dict, char *funcName, int& val)
{
PyObject *obj;
if (ICallVoidFunc(dict, funcName, obj))
{
if (PyInt_Check(obj))
{
val = PyInt_AsLong(obj);
Py_DECREF(obj);
return true;
}
}
return false;
}
bool ICallStrFunc(PyObject *dict, char *funcName, char*& val)
{
PyObject *obj;
if (ICallVoidFunc(dict, funcName, obj))
{
if (PyString_Check(obj))
{
val = hsStrcpy(PyString_AsString(obj));
Py_DECREF(obj);
return true;
}
}
return false;
}
#include "../MaxComponent/plPythonFileComponent.h"
#include "hsUtils.h"
enum ParamTypes
{
// These numbers used in the python/plasma/glue.py code
kTypeUndefined, // 0
kTypeBool, // 1
kTypeInt, // 2
kTypeFloat, // 3
kTypeString, // 4
kTypeSceneObj, // 5
kTypeSceneObjList, // 6
kTypeActivatorList, // 7
kTypeActivator, // 8
kTypeResponder, // 9
kTypeResponderList, // 10
kTypeDynamicText, // 11
kTypeGUIDialog, // 12
kTypeExcludeRegion, // 13 (x-rude-oh legion-oh)
kTypeAnimation, // 14 (animation component)
kTypeAvatarBehavior, // 15 (avatar behaviors, such as one-shots or multistage behaviors)
kTypeMaterial, // 16 (material type)
kTypeGUIPopUpMenu, // 17 (GUI pop up menu)
kTypeGUISkin, // 18 (Guess)
kTypeWaterComponent, // 19
kTypeDropDownList, // 20
kTypeSwimCurrentInterface, // 21
kTypeClusterComponent, // 22
kTypeMaterialAnimation, // 23
kTypeGrassComponent, // 24
};
bool IGetTupleInt(PyObject *tuple, int pos, int& val)
{
PyObject *param = PyTuple_GetItem(tuple, pos);
if (param && PyInt_Check(param))
{
val = PyInt_AsLong(param);
return true;
}
return false;
}
bool IGetTupleFloat(PyObject *tuple, int pos, float& val)
{
PyObject *param = PyTuple_GetItem(tuple, pos);
if (param && PyFloat_Check(param))
{
val = (float)PyFloat_AsDouble(param);
return true;
}
return false;
}
bool IGetTupleString(PyObject *tuple, int pos, char*& val)
{
PyObject *param = PyTuple_GetItem(tuple, pos);
if (param && PyString_Check(param))
{
val = PyString_AsString(param);
return true;
}
return false;
}
void IExtractVisInfo(PyObject* tuple, int* id, std::vector<std::string>* vec)
{
PyObject* vid = PyTuple_GetItem(tuple, 0);
PyObject* vstates = PyTuple_GetItem(tuple, 1);
if (vid && PyInt_Check(vid))
{
*id = PyInt_AsLong(vid);
}
if (vstates && PyList_Check(vstates))
{
PyObject* element;
int lsize = PyList_Size(vstates);
for (int i = 0; i < lsize; i++)
{
element = PyList_GetItem(vstates, i);
if (element && PyString_Check(element))
{
std::string str = PyString_AsString(element);
vec->push_back(str);
}
}
}
}
bool plPythonMgr::IQueryPythonFile(char *fileName)
{
PyObject *module = PyImport_ImportModule(fileName);
if (module)
{
// attach the glue python code to the end
if ( !PythonInterface::RunString("execfile('.\\python\\plasma\\glue.py')", module) )
{
// display any output (NOTE: this would be disabled in production)
// get the messages
PythonInterface::getOutputAndReset();
return false; // if we can't create the instance then there is nothing to do here
}
// Get the dictionary for this module
PyObject *dict = PyModule_GetDict(module);
// set the name of the file for the glue.py code to find
PyObject* pfilename = PyString_FromString(fileName);
PyDict_SetItemString(dict, "glue_name", pfilename);
// Get the block ID
int blockID = 0;
if (!ICallIntFunc(dict, kGetBlockID, blockID))
{
Py_DECREF(module);
return false;
}
// Get the class name
char *className = nil;
if (!ICallStrFunc(dict, kGetClassName, className))
{
Py_DECREF(module);
return false;
}
// Get the number of parameters
int numParams = 0;
if (!ICallIntFunc(dict, kGetNumParams, numParams))
{
Py_DECREF(module);
return false;
}
// determine if this is a multimodifier
int isMulti = 0;
ICallIntFunc(dict, kIsMultiModifier, isMulti);
// Get the version
//======================
// Get version must be the last call that needs a pythonfile class instance
// ... because it delete the instance afterwards
// NOTE: get attribute params doesn't need the pythonfile class instance
int version = 0;
if (!ICallIntFunc(dict, kGetVersion, version))
{
Py_DECREF(module);
return false;
}
PyObject *getParamFunc = PyDict_GetItemString(dict, kGetParam);
PyObject *getVisInfoFunc = PyDict_GetItemString(dict, kGetVisInfo);
if (PyCallable_Check(getParamFunc))
{
plAutoUIBlock *autoUI = TRACKED_NEW plAutoUIBlock(PythonFile::GetClassDesc(), blockID, className, version);
// test to see if it is a multi-modifier type class
if (isMulti)
autoUI->SetMultiModifierFlag(true);
for (int i = numParams-1; i >= 0; i--)
{
PyObject *ret = PyObject_CallFunction(getParamFunc, "l", i);
PyObject *visinfo = nil;
int ddlParamID = -1;
std::vector<std::string> vec;
if (PyCallable_Check(getVisInfoFunc))
{
visinfo = PyObject_CallFunction(getVisInfoFunc, "l", i);
if (visinfo && PyTuple_Check(visinfo))
{
IExtractVisInfo(visinfo, &ddlParamID, &vec);
}
}
if (ret)
{
if (PyTuple_Check(ret))
{
int paramID = -1;
char *paramName = nil;
int paramType = kTypeUndefined;
// Get the param ID, name, and type
if (IGetTupleInt(ret, 0, paramID) &&
IGetTupleString(ret, 1, paramName) &&
IGetTupleInt(ret, 2, paramType))
{
// Get the type specific params and add the param to the AutoUI block
switch (paramType)
{
case kTypeInt:
IAddInt(autoUI, ret, paramName, paramID, ddlParamID, &vec);
break;
case kTypeFloat:
IAddFloat(autoUI, ret, paramName, paramID, ddlParamID, &vec);
break;
case kTypeString:
IAddString(autoUI, ret, paramName, paramID, ddlParamID, &vec);
break;
case kTypeBool:
IAddBool(autoUI, ret, paramName, paramID, ddlParamID, &vec);
break;
case kTypeSceneObj:
IAddSceneObj(autoUI, ret, paramName, paramID, ddlParamID, &vec);
break;
case kTypeSceneObjList:
IAddSceneObjList(autoUI, ret, paramName, paramID, ddlParamID, &vec);
break;
case kTypeActivator:
IAddActivator(autoUI, ret, paramName, paramID, ddlParamID, &vec);
break;
case kTypeActivatorList:
IAddActivatorList(autoUI, ret, paramName, paramID, ddlParamID, &vec);
break;
case kTypeResponder:
IAddResponder(autoUI, ret, paramName, paramID, ddlParamID, &vec);
break;
case kTypeResponderList:
IAddResponderList(autoUI, ret, paramName, paramID, ddlParamID, &vec);
break;
case kTypeDynamicText:
IAddDynamicText(autoUI, ret, paramName, paramID, ddlParamID, &vec);
break;
case kTypeGUIDialog:
IAddGUIDialog(autoUI, ret, paramName, paramID, ddlParamID, &vec);
break;
case kTypeExcludeRegion:
IAddExcludeRegion(autoUI, ret, paramName, paramID, ddlParamID, &vec);
break;
case kTypeAnimation:
IAddAnimation(autoUI, ret, paramName, paramID, ddlParamID, &vec);
break;
case kTypeAvatarBehavior:
IAddBehavior(autoUI, ret, paramName, paramID, ddlParamID, &vec);
break;
case kTypeMaterial:
IAddMaterial(autoUI, ret, paramName, paramID, ddlParamID, &vec);
break;
case kTypeGUIPopUpMenu:
IAddGUIPopUpMenu(autoUI, ret, paramName, paramID, ddlParamID, &vec);
break;
case kTypeGUISkin:
IAddGUISkin(autoUI, ret, paramName, paramID, ddlParamID, &vec);
break;
case kTypeWaterComponent:
IAddWaterComponent(autoUI, ret, paramName, paramID, ddlParamID, &vec);
break;
case kTypeSwimCurrentInterface:
IAddSwimCurrentInterface(autoUI, ret, paramName, paramID, ddlParamID, &vec);
break;
case kTypeDropDownList:
IAddDropDownList(autoUI, ret, paramName, paramID, ddlParamID, &vec);
break;
case kTypeClusterComponent:
IAddClusterComponent(autoUI, ret, paramName, paramID, ddlParamID, &vec);
break;
case kTypeMaterialAnimation:
IAddMaterialAnimation(autoUI, ret, paramName, paramID, ddlParamID, &vec);
break;
case kTypeGrassComponent:
IAddGrassComponent(autoUI, ret, paramName, paramID, ddlParamID, &vec);
break;
}
}
}
Py_DECREF(ret);
}
}
PythonFile::AddAutoUIBlock(autoUI);
}
delete [] className;
Py_DECREF(module);
}
else
{
// There was an error when importing the module
// get the error message and put it in the log
PyErr_Print();
PyErr_Clear();
PythonInterface::getOutputAndReset();
}
return false;
}
void plPythonMgr::IAddBool(plAutoUIBlock *autoUI, PyObject *tuple, char *paramName, int id, int vid, std::vector<std::string>* vstates)
{
hsBool def = false;
IGetTupleInt(tuple, 3, def);
autoUI->AddCheckBox(id, nil, paramName, vid, vstates, def);
}
void plPythonMgr::IAddInt(plAutoUIBlock *autoUI, PyObject *tuple, char *paramName, int id, int vid, std::vector<std::string>* vstates)
{
int def=0, min=0, max=100;
IGetTupleInt(tuple, 3, def);
PyObject *range = PyTuple_GetItem(tuple, 4);
if (range && PyTuple_Check(range))
{
IGetTupleInt(range, 0, min);
IGetTupleInt(range, 1, max);
}
autoUI->AddIntSpinner(id, nil, paramName, vid, vstates, def, min, max);
}
void plPythonMgr::IAddFloat(plAutoUIBlock *autoUI, PyObject *tuple, char *paramName, int id, int vid, std::vector<std::string>* vstates)
{
float def=0, min=0, max=1;
IGetTupleFloat(tuple, 3, def);
PyObject *range = PyTuple_GetItem(tuple, 4);
if (range && PyTuple_Check(range))
{
IGetTupleFloat(range, 0, min);
IGetTupleFloat(range, 1, max);
}
autoUI->AddFloatSpinner(id, nil, paramName, vid, vstates, def, min, max);
}
void plPythonMgr::IAddString(plAutoUIBlock *autoUI, PyObject *tuple, char *paramName, int id, int vid, std::vector<std::string>* vstates)
{
char *def = nil;
IGetTupleString(tuple, 3, def);
autoUI->AddEditBox(id, nil, paramName, vid, vstates, def);
}
void plPythonMgr::IAddSceneObj(plAutoUIBlock *autoUI, PyObject *tuple, char *paramName, int id, int vid, std::vector<std::string>* vstates)
{
autoUI->AddPickNodeButton(id, nil, paramName, vid, vstates);
}
void plPythonMgr::IAddSceneObjList(plAutoUIBlock *autoUI, PyObject *tuple, char *paramName, int id, int vid, std::vector<std::string>* vstates)
{
autoUI->AddPickNodeList(id, nil, paramName, vid, vstates);
}
void plPythonMgr::IAddActivator(plAutoUIBlock *autoUI, PyObject *tuple, char *paramName, int id, int vid, std::vector<std::string>* vstates)
{
autoUI->AddPickActivatorButton(id, nil, paramName, vid, vstates);
}
void plPythonMgr::IAddActivatorList(plAutoUIBlock *autoUI, PyObject *tuple, char *paramName, int id, int vid, std::vector<std::string>* vstates)
{
autoUI->AddPickActivatorList(id, nil, paramName, vid, vstates);
}
void plPythonMgr::IAddDynamicText(plAutoUIBlock *autoUI, PyObject *tuple, char *paramName, int id, int vid, std::vector<std::string>* vstates)
{
autoUI->AddPickDynamicTextButton(id, nil, paramName, vid, vstates);
}
void plPythonMgr::IAddGUIDialog(plAutoUIBlock *autoUI, PyObject *tuple, char *paramName, int id, int vid, std::vector<std::string>* vstates)
{
autoUI->AddPickGUIDialogButton(id, nil, paramName, vid, vstates);
}
void plPythonMgr::IAddExcludeRegion(plAutoUIBlock *autoUI, PyObject *tuple, char *paramName, int id, int vid, std::vector<std::string>* vstates)
{
autoUI->AddPickExcludeRegionButton(id, nil, paramName, vid, vstates);
}
void plPythonMgr::IAddWaterComponent(plAutoUIBlock *autoUI, PyObject *tuple, char *paramName, int id, int vid, std::vector<std::string>* vstates)
{
autoUI->AddPickWaterComponentButton(id, nil, paramName, vid, vstates);
}
void plPythonMgr::IAddSwimCurrentInterface(plAutoUIBlock *autoUI, PyObject *tuple, char *paramName, int id, int vid, std::vector<std::string>* vstates)
{
autoUI->AddPickSwimCurrentInterfaceButton(id, nil, paramName, vid, vstates);
}
void plPythonMgr::IAddClusterComponent(plAutoUIBlock *autoUI, PyObject *tuple, char *paramName, int id, int vid, std::vector<std::string>* vstates)
{
autoUI->AddPickClusterComponentButton(id, nil, paramName, vid, vstates);
}
void plPythonMgr::IAddAnimation(plAutoUIBlock *autoUI, PyObject *tuple, char *paramName, int id, int vid, std::vector<std::string>* vstates)
{
autoUI->AddPickAnimationButton(id, nil, paramName, vid, vstates);
}
void plPythonMgr::IAddBehavior(plAutoUIBlock *autoUI, PyObject *tuple, char *paramName, int id, int vid, std::vector<std::string>* vstates)
{
autoUI->AddPickBehaviorButton(id, nil, paramName, vid, vstates);
}
void plPythonMgr::IAddMaterial(plAutoUIBlock *autoUI, PyObject *tuple, char *paramName, int id, int vid, std::vector<std::string>* vstates)
{
autoUI->AddPickMaterialButton(id, nil, paramName, vid, vstates);
}
void plPythonMgr::IAddGUIPopUpMenu(plAutoUIBlock *autoUI, PyObject *tuple, char *paramName, int id, int vid, std::vector<std::string>* vstates)
{
autoUI->AddPickGUIPopUpMenuButton(id, nil, paramName, vid, vstates);
}
void plPythonMgr::IAddGUISkin(plAutoUIBlock *autoUI, PyObject *tuple, char *paramName, int id, int vid, std::vector<std::string>* vstates)
{
autoUI->AddPickGUISkinButton(id, nil, paramName, vid, vstates);
}
#include "../MaxComponent/plResponderComponent.h"
void plPythonMgr::IAddResponder(plAutoUIBlock *autoUI, PyObject *tuple, char *paramName, int id, int vid, std::vector<std::string>* vstates)
{
std::vector<Class_ID> cids;
cids.push_back(RESPONDER_CID);
autoUI->AddPickComponentButton(id, nil, paramName, vid, vstates, &cids, true);
}
void plPythonMgr::IAddResponderList(plAutoUIBlock *autoUI, PyObject *tuple, char *paramName, int id, int vid, std::vector<std::string>* vstates)
{
std::vector<Class_ID> cids;
cids.push_back(RESPONDER_CID);
autoUI->AddPickComponentList(id, nil, paramName, vid, vstates, &cids);
}
void plPythonMgr::IAddMaterialAnimation(plAutoUIBlock *autoUI, PyObject *tuple, char *paramName, int id, int vid, std::vector<std::string>* vstates)
{
autoUI->AddPickMaterialAnimationButton(id, nil, paramName, vid, vstates);
}
void plPythonMgr::IAddGrassComponent(plAutoUIBlock *autoUI, PyObject *objTuple, std::string paramName, int id, int vid, std::vector<std::string>* vstates)
{
autoUI->AddPickGrassComponentButton(id, nil, paramName.c_str(), vid, vstates);
}
#include <direct.h>
void plPythonMgr::LoadPythonFiles()
{
const char *clientPath = plMaxConfig::GetClientPath(false, true);
if (clientPath)
{
char oldCwd[MAX_PATH];
_getcwd(oldCwd, sizeof(oldCwd));
_chdir(clientPath);
// Get the path to the Python subdirectory of the client
char pythonPath[MAX_PATH];
strcpy(pythonPath, clientPath);
strcat(pythonPath, "Python");
PythonInterface::initPython();
// Iterate through all the Python files in the folder
hsFolderIterator folder(pythonPath);
while (folder.NextFileSuffix(".py"))
{
// Get the filename without the ".py" (module name)
const char *fullFileName = folder.GetFileName();
char fileName[_MAX_FNAME];
_splitpath(fullFileName, NULL, NULL, fileName, NULL);
IQueryPythonFile(fileName);
}
PythonInterface::finiPython();
_chdir(oldCwd);
}
}
void plPythonMgr::IAddDropDownList(plAutoUIBlock *autoUI, PyObject *tuple, char *paramName, int id, int vid, std::vector<std::string>* vstates)
{
PyObject *options = PyTuple_GetItem(tuple, 3);
if (options && PyTuple_Check(options))
{
int size = PyTuple_Size(options);
char* opt = nil;
std::vector<std::string> optionsVec;
for (int i = 0; i < size; i++)
{
IGetTupleString(options, i, opt);
std::string str = opt;
optionsVec.push_back(str);
}
autoUI->AddDropDownList(id, nil, paramName, vid, vstates, &optionsVec);
}
}

View File

@ -0,0 +1,84 @@
/*==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 "max.h"
#include "python.h"
#include <vector>
class plAutoUIBlock;
class plPythonMgr
{
protected:
plPythonMgr();
bool IQueryPythonFile(char *fileName);
void IAddBool(plAutoUIBlock *autoUI, PyObject *tuple, char *paramName, int id, int vid, std::vector<std::string>* vstates);
void IAddInt(plAutoUIBlock *autoUI, PyObject *tuple, char *paramName, int id, int vid, std::vector<std::string>* vstates);
void IAddFloat(plAutoUIBlock *autoUI, PyObject *tuple, char *paramName, int id, int vid, std::vector<std::string>* vstates);
void IAddString(plAutoUIBlock *autoUI, PyObject *tuple, char *paramName, int id, int vid, std::vector<std::string>* vstates);
void IAddSceneObj(plAutoUIBlock *autoUI, PyObject *tuple, char *paramName, int id, int vid, std::vector<std::string>* vstates);
void IAddSceneObjList(plAutoUIBlock *autoUI, PyObject *tuple, char *paramName, int id, int vid, std::vector<std::string>* vstates);
void IAddActivator(plAutoUIBlock *autoUI, PyObject *tuple, char *paramName, int id, int vid, std::vector<std::string>* vstates);
void IAddActivatorList(plAutoUIBlock *autoUI, PyObject *tuple, char *paramName, int id, int vid, std::vector<std::string>* vstates);
void IAddResponder(plAutoUIBlock *autoUI, PyObject *tuple, char *paramName, int id, int vid, std::vector<std::string>* vstates);
void IAddResponderList(plAutoUIBlock *autoUI, PyObject *tuple, char *paramName, int id, int vid, std::vector<std::string>* vstates);
void IAddDynamicText(plAutoUIBlock *autoUI, PyObject *tuple, char *paramName, int id, int vid, std::vector<std::string>* vstates);
void IAddGUIDialog(plAutoUIBlock *autoUI, PyObject *tuple, char *paramName, int id, int vid, std::vector<std::string>* vstates);
void IAddExcludeRegion(plAutoUIBlock *autoUI, PyObject *tuple, char *paramName, int id, int vid, std::vector<std::string>* vstates);
void IAddAnimation(plAutoUIBlock *autoUI, PyObject *tuple, char *paramName, int id, int vid, std::vector<std::string>* vstates);
void IAddBehavior(plAutoUIBlock *autoUI, PyObject *tuple, char *paramName, int id, int vid, std::vector<std::string>* vstates);
void IAddMaterial(plAutoUIBlock *autoUI, PyObject *tuple, char *paramName, int id, int vid, std::vector<std::string>* vstates);
void IAddGUIPopUpMenu(plAutoUIBlock *autoUI, PyObject *tuple, char *paramName, int id, int vid, std::vector<std::string>* vstates);
void IAddGUISkin(plAutoUIBlock *autoUI, PyObject *tuple, char *paramName, int id, int vid, std::vector<std::string>* vstates);
void IAddWaterComponent(plAutoUIBlock *autoUI, PyObject *tuple, char *paramName, int id, int vid, std::vector<std::string>* vstates);
void IAddSwimCurrentInterface(plAutoUIBlock *autoUI, PyObject *tuple, char *paramName, int id, int vid, std::vector<std::string>* vstates);
void IAddDropDownList(plAutoUIBlock *autoUI, PyObject *tuple, char *paramName, int id, int vid, std::vector<std::string>* vstates);
void IAddClusterComponent(plAutoUIBlock *autoUI, PyObject *tuple, char *paramName, int id, int vid, std::vector<std::string>* vstates);
void IAddMaterialAnimation(plAutoUIBlock *autoUI, PyObject *tuple, char *paramName, int id, int vid, std::vector<std::string>* vstates);
void IAddGrassComponent(plAutoUIBlock *autoUI, PyObject *objTuple, std::string paramName, int id, int vid, std::vector<std::string>* vstates);
public:
static plPythonMgr& Instance();
void LoadPythonFiles();
};

View File

@ -0,0 +1,108 @@
/*==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 "HeadSpin.h"
#include "plResCollector.h"
#include "plMtlCollector.h"
#include "max.h"
#include "../MaxExport/plExportProgressBar.h"
void plResCollector::Collect()
{
Interface *ip = GetCOREInterface();
// Get the directory to copy files to
char path[MAX_PATH];
ip->ChooseDirectory(ip->GetMAXHWnd(),
"Choose a folder to copy the resources to",
path,
NULL);
if (!strcmp(path, ""))
return;
// Make sure the directory ends with a slash
if (path[strlen(path)-1] != '\\' && path[strlen(path)-1] != '/')
strcat(path, "\\");
// Make a list of all the textures
TexNameSet texNames;
plMtlCollector::GetAllTextures(texNames);
plExportProgressBar bar;
bar.Start("Copy Files", texNames.size()+1);
// Copy each texture to the output directory
TexNameSet::iterator it = texNames.begin();
for (; it != texNames.end(); it++)
{
const char *texName = *it;
char outpath[MAX_PATH], name[_MAX_FNAME+_MAX_EXT], ext[_MAX_EXT];
_splitpath(texName, NULL, NULL, name, ext);
strcat(name, ext);
if (bar.Update(name))
return;
strcpy(outpath, path);
strcat(outpath, name);
CopyFile(texName, outpath, TRUE);
}
// Get the filename to save to
TSTR& maxFile = ip->GetCurFileName();
TSTR& filePath = ip->GetCurFilePath();
if (!strcmp(maxFile, ""))
return;
if (bar.Update(maxFile))
return;
// If we need to save, do it now
if (IsSaveRequired())
ip->SaveToFile(filePath);
// Copy the max file to the output directory
strcat(path, maxFile);
CopyFile(filePath, path, TRUE);
}

View File

@ -0,0 +1,45 @@
/*==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==*/
namespace plResCollector
{
void Collect();
};

View File

@ -0,0 +1,184 @@
/*==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 "HeadSpin.h"
#include "max.h"
#include "plResetXform.h"
#include "../MaxMain/plMaxNode.h"
#include "../MaxComponent/plComponent.h"
void plResetXform::ResetSelected() const
{
ResetSelectedRecur(GetCOREInterface()->GetRootNode());
}
void plResetXform::ResetSelectedRecur(INode* node) const
{
if( !node )
return;
if( node->Selected() )
{
IResetNode(node);
}
int i;
for( i = 0; i < node->NumberOfChildren(); i++ )
ResetSelectedRecur(node->GetChildNode(i));
}
void plResetXform::IResetNode(INode* node) const
{
const char* dbgNodeName = node->GetName();
BOOL deleteIt = false;
TriObject* oldObj = IGetTriObject(node, deleteIt);
if( !oldObj )
return;
Mesh& oldMesh = oldObj->mesh;
TimeValue t(0);
Matrix3 nodeTM = node->GetNodeTM(t);
Matrix3 objectTM = node->GetObjectTM(t);
Matrix3 otm = objectTM * Inverse(nodeTM);
Point3 u = nodeTM.GetRow(0);
Point3 v = nodeTM.GetRow(1);
Point3 w = CrossProd(u, v);
v = CrossProd(w, u);
u = Normalize(u);
v = Normalize(v);
w = Normalize(w);
Matrix3 newXform(u, v, w, nodeTM.GetTrans());
Matrix3 vtxXform = otm * nodeTM * Inverse(newXform) * Inverse(otm);
TriObject* newObj = CreateNewTriObject();
Mesh& newMesh = newObj->mesh;
newMesh = oldMesh;
int i;
for( i = 0; i < newMesh.getNumVerts(); i++ )
{
Point3 p = vtxXform * newMesh.getVert(i);
newMesh.getVert(i) = p;
}
if( nodeTM.Parity() )
{
for( i = 0; i < newMesh.getNumFaces(); i++ )
{
newMesh.FlipNormal(i);
}
}
node->SetObjectRef(newObj);
node->SetNodeTM(t, newXform);
if( deleteIt )
oldObj->DeleteThis();
}
TriObject* plResetXform::IGetTriObject(INode* node, BOOL& deleteIt) const
{
Object *obj = node->EvalWorldState(TimeValue(0)).obj;
if( !obj )
return NULL;
if( !obj->CanConvertToType( triObjectClassID ) )
return NULL;
// Convert to triMesh object
TriObject *meshObj = (TriObject*)obj->ConvertToType(TimeValue(0), triObjectClassID);
if( !meshObj )
return NULL;
deleteIt = meshObj != obj;
return meshObj;
}
void plSelectNonRenderables::ICollectNonDrawablesRecur(plMaxNode* node, INodeTab& nodeTab) const
{
plComponentBase* comp = node->ConvertToComponent();
if( comp )
comp->CollectNonDrawables(nodeTab);
int i;
for( i = 0; i < node->NumberOfChildren(); i++ )
ICollectNonDrawablesRecur((plMaxNode*)node->GetChildNode(i), nodeTab);
}
void plSelectNonRenderables::SelectNonRenderables() const
{
INodeTab nodeTab;
ICollectNonDrawablesRecur((plMaxNode*)GetCOREInterface()->GetRootNode(), nodeTab);
INodeTab unhidden;
int i;
for( i = 0; i < nodeTab.Count(); i++ )
{
INode* node = nodeTab[i];
if( !node->IsHidden() )
unhidden.Append(1, &node);
}
theHold.Begin();
TSTR undostr;
undostr.printf("SelNonRend");
GetCOREInterface()->SelectNodeTab(unhidden, true, true);
theHold.Accept(undostr);
}

View File

@ -0,0 +1,71 @@
/*==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==*/
#ifndef plResetXform_inc
#define plResetXform_inc
class Interface;
class INode;
class TriObject;
class plMaxNode;
class INodeTab;
class plResetXform
{
public:
void ResetSelected() const;
protected:
void ResetSelectedRecur(INode* node) const;
void IResetNode(INode* node) const;
TriObject* IGetTriObject(INode* node, BOOL& deleteIt) const;
};
class plSelectNonRenderables
{
public:
void SelectNonRenderables() const;
protected:
void ICollectNonDrawablesRecur(plMaxNode* node, INodeTab& nodeTab) const;
};
#endif // plResetXform_inc

View File

@ -0,0 +1,333 @@
/*==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 "HeadSpin.h"
#include "max.h"
#include "notify.h"
#include "../MaxComponent/plComponent.h"
#include <vector>
#include "plMaxNode.h"
bool IIsNodeInTab(INodeTab &tab, INode *node)
{
for (int i = 0; i < tab.Count(); i++)
if (tab[i] == node)
return true;
return false;
}
class ComponentRefs
{
public:
plComponentBase *comp;
INodeTab refs;
};
void plSaveSelected()
{
Interface *ip = GetCOREInterface();
// Get the Max filename to save to
char buf[256];
memset(&buf, 0, sizeof(buf));
OPENFILENAME ofn = {0};
ofn.lStructSize = sizeof(OPENFILENAME);
ofn.hwndOwner = ip->GetMAXHWnd();
ofn.lpstrFilter = "3ds max (*.max)\0*.max\0\0";
ofn.nFilterIndex = 1;
ofn.lpstrFile = buf;
ofn.nMaxFile = sizeof(buf);
// ofn.lpstrInitialDir = ip->GetDir(APP_SCENE_DIR);
ofn.Flags = OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT;
ofn.lpstrDefExt = "max";
if (GetSaveFileName(&ofn))
{
int count = ip->GetSelNodeCount();
int i;
// Put all the selected nodes in a list
INodeTab selected;
for (i = 0; i < count; i++)
{
plMaxNode *node = (plMaxNode*)ip->GetSelNode(i);
selected.Append(1, (INode**)&node);
}
// Put all the components attached to those nodes in a list
INodeTab components;
for (i = 0; i < count; i++)
{
plMaxNode *node = (plMaxNode*)ip->GetSelNode(i);
UInt32 compCount = node->NumAttachedComponents();
for (int j = 0; j < compCount; j++)
{
INode *compNode = node->GetAttachedComponent(j)->GetINode();//Node(j);
if (!IIsNodeInTab(components, compNode))
components.Append(1, &compNode);
}
}
// Find the objects that the components are reffing that are not part of the selection.
// Back them up, and delete them out of the components ref list so they won't be saved too.
std::vector<ComponentRefs> out;
for (i = 0; i < components.Count(); i++)
{
plComponentBase *comp = ((plMaxNode*)components[i])->ConvertToComponent();
for (int j = comp->NumTargets() - 1; j >= 0; --j)
{
plMaxNodeBase *node = comp->GetTarget(j);
if (!node)
continue;
const char *t1 = components[i]->GetName();
const char *t2 = node->GetName();
if (!IIsNodeInTab(selected, node))
{
UInt32 idx = -1;
for (UInt32 k = 0; k < out.size(); k++)
{
if (out[k].comp == comp)
idx = k;
}
if (idx == -1)
{
idx = out.size();
out.resize(idx+1);
out[idx].comp = comp;
}
out[idx].refs.Append(1, (INode**)&node);
comp->DeleteTarget(node);
}
}
}
// Save the selected objects and their components
INodeTab allNodes;
allNodes.Append(selected.Count(), &selected[0]);
allNodes.Append(components.Count(), &components[0]);
ip->FileSaveNodes(&allNodes, buf);
// Restore the component refs to objects that weren't selected
for (i = 0; i < out.size(); i++)
{
for (int j = 0; j < out[i].refs.Count(); j++)
out[i].comp->AddTarget((plMaxNode*)out[i].refs[j]);
}
}
}
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
void IFindComponentsRecur(plMaxNode *node, std::vector<plComponentBase*> &components)
{
if (node->IsComponent())
components.push_back(node->ConvertToComponent());
for (int i = 0; i < node->NumberOfChildren(); i++)
IFindComponentsRecur((plMaxNode*)node->GetChildNode(i), components);
}
void IMergeComponents(plComponentBase *to, plComponentBase *from)
{
for (int i = 0; i < from->NumTargets(); i++)
to->AddTarget(from->GetTarget(i));
// Delete the component from the scene
theHold.Begin();
GetCOREInterface()->DeleteNode(from->GetINode());
theHold.Accept(_T("Delete Component"));
}
plMaxNode *IFindComponentRecur(plMaxNode *node, const char *name)
{
if (!strcmp(node->GetName(), name))
{
if (node->IsComponent())
return node;
}
for (int i = 0; i < node->NumberOfChildren(); i++)
{
plMaxNode *ret = IFindComponentRecur((plMaxNode*)node->GetChildNode(i), name);
if (ret)
return ret;
}
return nil;
}
void plMerge()
{
Interface *ip = GetCOREInterface();
// Get the Max filename to merge
char file[MAX_PATH];
memset(&file, 0, sizeof(file));
OPENFILENAME ofn = {0};
ofn.lStructSize = sizeof(OPENFILENAME);
ofn.hwndOwner = ip->GetMAXHWnd();
ofn.lpstrFilter = "3ds max (*.max)\0*.max\0\0";
ofn.nFilterIndex = 1;
ofn.lpstrFile = file;
ofn.nMaxFile = sizeof(file);
// ofn.lpstrInitialDir = ip->GetDir(APP_SCENE_DIR);
ofn.Flags = OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT;
ofn.lpstrTitle = "Merge";
if (!GetOpenFileName(&ofn))
return;
// Don't actually merge yet, just get the names of every node in the file
NameTab nodeNames;
ip->MergeFromFile(file, TRUE, FALSE, FALSE, MERGE_LIST_NAMES, &nodeNames);
// For each node name, search the current scene for a component with the same name.
// If one is found, append "Merged" to it so its name won't cause a conflict during
// the actual merge.
std::vector<plMaxNode*> renamedNodes;
int i;
for (i = 0; i < nodeNames.Count(); i++)
{
plMaxNode *node = IFindComponentRecur((plMaxNode*)ip->GetRootNode(), nodeNames[i]);
if (node)
{
char buf[256];
strcpy(buf, node->GetName());
strcat(buf, "Merged");
node->SetName(buf);
renamedNodes.push_back(node);
}
}
// Do the merge
ip->MergeFromFile(file);
// Rename the components back to their original names
for (i = 0; i < renamedNodes.size(); i++)
{
char buf[256];
strcpy(buf, renamedNodes[i]->GetName());
buf[strlen(buf)-6] = '\0';
renamedNodes[i]->SetName(buf);
}
// Put all the components in the scene in a list
std::vector<plComponentBase*> components;
IFindComponentsRecur((plMaxNode*)ip->GetRootNode(), components);
nodeNames.ZeroCount();
// For each component, search the scene for any other components with the same
// name and type. If there are any, merge their target lists and delete one.
for (i = 0; i < renamedNodes.size(); i++)
{
if (!renamedNodes[i])
continue;
plComponentBase *oldComp = renamedNodes[i]->ConvertToComponent();
char *oldCompName = oldComp->GetINode()->GetName();
for (int j = 0; j < components.size(); j++)
{
plComponentBase *comp = components[j];
if (oldComp == comp)
components[j] = nil;
else if (comp)
{
const char *temp = comp->GetINode()->GetName();
if (!strcmp(oldCompName, comp->GetINode()->GetName()) &&
comp->ClassID() == comp->ClassID())
{
IMergeComponents(comp, oldComp);
nodeNames.AddName(oldCompName);
continue;
}
}
}
}
// Send out merge notifications again, so that the component dialog will be updated
BroadcastNotification(NOTIFY_FILE_PRE_MERGE);
BroadcastNotification(NOTIFY_FILE_POST_MERGE);
#if 0
if (nodeNames.Count() == 0)
return;
// Actually calculate the size of all the merged component names, because
// a static buffer could be too small in large merges
UInt32 size = 0;
for (i = 0; i < nodeNames.Count(); i++)
size += strlen(nodeNames[i]) + 1;
// Put all the component names in a list and show it to the user
char *buf = TRACKED_NEW char[size+25];
strcpy(buf, "Components Merged:\n\n");
for (i = 0; i < nodeNames.Count(); i++)
{
strcat(buf, nodeNames[i]);
strcat(buf, "\n");
}
MessageBox(ip->GetMAXHWnd(), buf, "Components Merged", MB_OK);
delete [] buf;
#endif
}

View File

@ -0,0 +1,43 @@
/*==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==*/
void plSaveSelected();
void plMerge();

View File

@ -0,0 +1,271 @@
/*==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==*/
//////////////////////////////////////////////////////////////////////////////
// //
// plTextureExportLog - Lil' utility class for collating and writing out //
// a log of all textures exported, or rather, in the //
// resManager, or rather, the ones passed in to this //
// sucker. //
// //
//////////////////////////////////////////////////////////////////////////////
#include "HeadSpin.h"
#include "hsTypes.h"
#include "hsWindows.h"
#include "plTextureExportLog.h"
#include "../plGImage/plCubicEnvironmap.h"
#include "../plGImage/plMipmap.h"
#include "../plGImage/plDynamicTextMap.h"
#include "../plPipeline/plRenderTarget.h"
#include "../plPipeline/plCubicRenderTarget.h"
#include "../pnKeyedObject/plKey.h"
#include "hsUtils.h"
#include "hsStream.h"
//// Constructor/Destructor //////////////////////////////////////////////////
plTextureExportLog::plTextureExportLog( const char *fileName )
{
fFileName = hsStrcpy( fileName );
fNodeList = nil;
}
plTextureExportLog::~plTextureExportLog()
{
plBMapNode *node;
if( fFileName != nil )
{
Write();
delete [] fFileName;
}
while( fNodeList != nil )
{
node = fNodeList->fNextNode;
delete fNodeList;
fNodeList = node;
}
}
//// Other Ones //////////////////////////////////////////////////////////////
void plTextureExportLog::IAddBMapNode( UInt32 rank, plBitmap *bMap )
{
plBMapNode *node = TRACKED_NEW plBMapNode, **nodeHdl;
node->fBitmap = bMap;
node->fRank = rank;
for( nodeHdl = &fNodeList; *nodeHdl != nil; )
{
if( (*nodeHdl)->fRank < rank )
break;
nodeHdl = &( (*nodeHdl)->fNextNode );
}
node->fNextNode = *nodeHdl;
*nodeHdl = node;
}
void plTextureExportLog::AddTexture( plBitmap *texture )
{
// Rank based on size written to disk
IAddBMapNode( texture->GetTotalSize(), texture );
}
void plTextureExportLog::Write( void )
{
plBMapNode *node;
hsUNIXStream *stream = TRACKED_NEW hsUNIXStream;
char str[ 128 ];
UInt32 size;
stream->Open( fFileName, "wt" );
stream->WriteString( "------------------------------------------------------------\n" );
stream->WriteString( "- Texture Export Data Log -\n" );
stream->WriteString( "------------------------------------------------------------\n" );
stream->WriteString( "\n" );
IWriteTabbedString( stream, "Name", 4 );
IWriteTabbedString( stream, "Size", 3 );
IWriteTabbedString( stream, "Type", 4 );
stream->WriteString( "\n" );
stream->WriteString( "------------------------------------------------------------\n" );
for( node = fNodeList; node != nil; node = node->fNextNode )
{
plMipmap *mip = plMipmap::ConvertNoRef( node->fBitmap );
plDynamicTextMap *dynText = plDynamicTextMap::ConvertNoRef( node->fBitmap );
plCubicEnvironmap *cubic = plCubicEnvironmap::ConvertNoRef( node->fBitmap );
plCubicRenderTarget* cubeRend = plCubicRenderTarget::ConvertNoRef( node->fBitmap );
plRenderTarget* rend = plRenderTarget::ConvertNoRef( node->fBitmap );
// Name
IWriteTabbedString( stream, node->fBitmap->GetKeyName(), dynText != nil ? 8 : 4 );
// Size, formatted
size = node->fBitmap->GetTotalSize();
if( size < 1024 )
{
sprintf( str, "%d bytes", size );
IWriteTabbedString( stream, str, 2 );
}
else if( size < 1024 * 1024 )
{
sprintf( str, "%4.1f kb", size / 1024.f );
IWriteTabbedString( stream, str, 2 );
}
else
{
sprintf( str, "%4.1f Mb", size / ( 1024.f * 1024.f ) );
IWriteTabbedString( stream, str, 2 );
}
if( dynText != nil )
{
IWriteTabbedString( stream, "Dynamic text map", 3 );
// Dimensions
sprintf( str, "%d by %d", dynText->GetVisibleWidth(), dynText->GetVisibleHeight() );
IWriteTabbedString( stream, str, 2 );
sprintf( str, "%d bpp", dynText->GetPixelSize() );
IWriteTabbedString( stream, str, 1 );
IWriteTabbedString( stream, dynText->IsCompressed()
? "Compressed"
: dynText->fCompressionType == plBitmap::kJPEGCompression
? "JPEG"
: "Uncompressed", 2 );
}
else if( cubic != nil )
{
IWriteTabbedString( stream, "Cubic EnvironMap", 3 );
sprintf( str, "%d pixels square", cubic->GetFace( 0 )->GetWidth() );
IWriteTabbedString( stream, str, 2 );
sprintf( str, "%d bpp", cubic->GetPixelSize() );
IWriteTabbedString( stream, str, 1 );
IWriteTabbedString( stream, cubic->IsCompressed()
? "Compressed"
: cubic->fCompressionType == plBitmap::kJPEGCompression
? "JPEG"
: "Uncompressed", 2 );
}
else if( mip != nil )
{
IWriteTabbedString( stream, "Mipmap", 3 );
// Dimensions & num mip levels
sprintf( str, "%d by %d", mip->GetWidth(), mip->GetHeight() );
IWriteTabbedString( stream, str, 2 );
sprintf( str, "%d bpp", mip->GetPixelSize() );
IWriteTabbedString( stream, str, 1 );
sprintf( str, "%d levels", mip->GetNumLevels() );
IWriteTabbedString( stream, str, 2 );
IWriteTabbedString( stream, mip->IsCompressed()
? "Compressed"
: mip->fCompressionType == plBitmap::kJPEGCompression
? "JPEG"
: "Uncompressed", 2 );
}
else if( cubeRend )
{
IWriteTabbedString( stream, "CubicRenderTarget", 3 );
// Dimensions & num mip levels
sprintf( str, "%d by %d", cubeRend->GetWidth(), cubeRend->GetHeight() );
IWriteTabbedString( stream, str, 2 );
}
else if( rend )
{
IWriteTabbedString( stream, "RenderTarget", 3 );
// Dimensions & num mip levels
sprintf( str, "%d by %d", rend->GetWidth(), rend->GetHeight() );
IWriteTabbedString( stream, str, 2 );
}
else
{
IWriteTabbedString( stream, "Unknown", 3 );
}
stream->WriteString( "\n" );
}
stream->Close();
delete stream;
// HACK: Prevent the destructor from writing out now
delete [] fFileName;
fFileName = nil;
}
void plTextureExportLog::IWriteTabbedString( hsStream *stream, const char *string, Int8 numTabs )
{
static char tabs[ 64 ];
int i;
stream->WriteString( string );
// Assumes 8 spaces per tab
numTabs -= strlen( string ) / 8;
if( numTabs < 1 )
numTabs = 1;
for( i = 0; i < numTabs; i++ )
tabs[ i ] = '\t';
tabs[ i ] = 0;
stream->WriteString( tabs );
}

View File

@ -0,0 +1,91 @@
/*==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==*/
//////////////////////////////////////////////////////////////////////////////
// //
// plTextureExportLog - Lil' utility class for collating and writing out //
// a log of all textures exported, or rather, in the //
// resManager, or rather, the ones passed in to this //
// sucker. //
// //
//////////////////////////////////////////////////////////////////////////////
#ifndef _plTextureExportLog_h
#define _plTextureExportLog_h
//// Class Definition ////////////////////////////////////////////////////////
class plBitmap;
class hsStream;
class plTextureExportLog
{
protected:
char *fFileName;
// Tiny linked list helper
class plBMapNode
{
public:
UInt32 fRank; // Sort with biggest first
plBitmap *fBitmap;
plBMapNode *fNextNode;
};
plBMapNode *fNodeList;
void IAddBMapNode( UInt32 rank, plBitmap *bMap );
void IWriteTabbedString( hsStream *stream, const char *string, Int8 numTabs );
public:
plTextureExportLog( const char *fileName );
~plTextureExportLog();
void AddTexture( plBitmap *texture );
void Write( void );
};
#endif //_plTextureExportLog_h

View File

@ -0,0 +1,390 @@
/*==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 "HeadSpin.h"
#include "plTextureSearch.h"
#include "resource.h"
#include "hsUtils.h"
#define PB2Export __declspec( dllexport ) // Because I don't feel like including all the paramblock crap
#include "pbbitmap.h"
#include "bmmlib.h"
#include "IMtlEdit.h"
#include "plMtlCollector.h"
#include "plMaxAccelerators.h"
#include "../MaxPlasmaMtls/Layers/plPlasmaMAXLayer.h"
#include "../../AssetMan/PublicInterface/MaxAssInterface.h"
// Not a class member so we don't have to make everyone who uses this know about AssetMan
static jvUniqueId gAssetID;
plTextureSearch::plTextureSearch() : fDlg(NULL)
{
gAssetID.SetEmpty();
memset(fFileName, 0, sizeof(fFileName));
}
plTextureSearch& plTextureSearch::Instance()
{
static plTextureSearch theInstance;
return theInstance;
}
void plTextureSearch::Toggle()
{
if (!fDlg)
{
fDlg = CreateDialog(hInstance,
MAKEINTRESOURCE(IDD_FIND_TEXTURE),
GetCOREInterface()->GetMAXHWnd(),
ForwardDlgProc);
HWND hList = GetDlgItem(fDlg, IDC_TEXTURE_LIST);
LVCOLUMN lvc;
lvc.mask = LVCF_TEXT;
lvc.pszText = "Material";
ListView_InsertColumn(hList, 0, &lvc);
lvc.pszText = "Layer";
ListView_InsertColumn(hList, 1, &lvc);
lvc.pszText = "Texture";
ListView_InsertColumn(hList, 2, &lvc);
IUpdateTextures(kUpdateLoadList);
GetCOREInterface()->RegisterDlgWnd(fDlg);
ShowWindow(fDlg, SW_SHOW);
}
else
{
DestroyWindow(fDlg);
fDlg = NULL;
}
}
BOOL plTextureSearch::ForwardDlgProc(HWND hDlg, UINT msg, WPARAM wParam, LPARAM lParam)
{
return Instance().DlgProc(hDlg, msg, wParam, lParam);
}
BOOL plTextureSearch::DlgProc(HWND hDlg, UINT msg, WPARAM wParam, LPARAM lParam)
{
switch (msg)
{
case WM_ACTIVATE:
if (LOWORD(wParam) == WA_INACTIVE)
plMaxAccelerators::Enable();
else
plMaxAccelerators::Disable();
return TRUE;
case WM_COMMAND:
if (HIWORD(wParam) == BN_CLICKED)
{
int id = LOWORD(wParam);
if (id == IDCANCEL)
{
Toggle();
return TRUE;
}
else if (id == IDC_UPDATE_BUTTON)
{
IUpdateTextures(kUpdateLoadList);
return TRUE;
}
else if (id == IDC_REPLACE_ALL_BUTTON)
{
if (hsMessageBox("Are you sure?", "Confirmation", hsMessageBoxYesNo) == hsMBoxYes)
{
IUpdateTextures(kUpdateReplace);
}
return TRUE;
}
else if (id == IDC_SET_ALL_BUTTON)
{
if (hsMessageBox("Are you sure?", "Confirmation", hsMessageBoxYesNo) == hsMBoxYes)
{
IUpdateTextures(kUpdateSetSize);
}
return TRUE;
}
else if (id == IDC_REPLACE_BUTTON)
{
IPickReplaceTexture();
return TRUE;
}
}
else if (HIWORD(wParam) == EN_CHANGE && LOWORD(wParam) == IDC_FIND_EDIT)
{
bool findText = (SendDlgItemMessage(hDlg, IDC_FIND_EDIT, EM_LINELENGTH, 0, 0) > 0);
bool replace = (fFileName[0] != '\0');
EnableWindow(GetDlgItem(hDlg, IDC_REPLACE_BUTTON), findText);
EnableWindow(GetDlgItem(hDlg, IDC_REPLACE_ALL_BUTTON), findText && replace);
return TRUE;
}
break;
case WM_NOTIFY:
{
NMHDR* nmhdr = (NMHDR*)lParam;
// User double-clicked a material in the texture list
if (nmhdr->idFrom == IDC_TEXTURE_LIST && nmhdr->code == NM_DBLCLK)
{
NMITEMACTIVATE* itema = (NMITEMACTIVATE*)lParam;
if (itema->iItem != -1)
{
// Get the material the user clicked on
HWND hList = GetDlgItem(fDlg, IDC_TEXTURE_LIST);
LV_ITEM item;
item.iItem = itema->iItem;
item.mask = LVIF_PARAM;
ListView_GetItem(hList, &item);
Mtl* mtl = (Mtl*)item.lParam;
// Make sure the material is still in the scene (paranoid check)
MtlSet mtls;
plMtlCollector::GetMtls(&mtls, nil, plMtlCollector::kPlasmaOnly | plMtlCollector::kNoMultiMtl);
if (mtls.find(mtl) != mtls.end())
{
// Put the material in the current slot of the material editor
IMtlEditInterface* mtlInterface = GetMtlEditInterface();
int slot = mtlInterface->GetActiveMtlSlot();
mtlInterface->PutMtlToMtlEditor(mtl, slot);
}
}
return TRUE;
}
}
break;
}
return FALSE;
}
static int FloorPow2(int value)
{
int v;
for (v = 1; v <= value; v <<= 1);
return v >> 1;
}
void plTextureSearch::IUpdateTextures(plTextureSearch::Update update)
{
MtlSet mtls;
plMtlCollector::GetMtls(&mtls, nil, plMtlCollector::kPlasmaOnly | plMtlCollector::kNoMultiMtl);
char searchStr[256];
GetDlgItemText(fDlg, IDC_FIND_EDIT, searchStr, sizeof(searchStr));
strlwr(searchStr);
HWND hList = GetDlgItem(fDlg, IDC_TEXTURE_LIST);
ListView_DeleteAllItems(hList);
int sizeX = -1, sizeY = -1;
HWND hCombo = GetDlgItem(fDlg, IDC_SIZE_COMBO);
// If we're updating the size, get whatever the user selected
if (update == kUpdateSetSize)
{
int sel = ComboBox_GetCurSel(hCombo);
UInt32 data = ComboBox_GetItemData(hCombo, sel);
sizeX = LOWORD(data);
sizeY = HIWORD(data);
}
MtlSet::iterator it = mtls.begin();
for (; it != mtls.end(); it++)
{
Mtl *mtl = (*it);
LayerSet layers;
plMtlCollector::GetMtlLayers(mtl, layers);
LayerSet::iterator layerIt = layers.begin();
for (; layerIt != layers.end(); layerIt++)
{
plPlasmaMAXLayer *layer = (*layerIt);
int numBitmaps = layer->GetNumBitmaps();
for (int i = 0; i < numBitmaps; i++)
{
PBBitmap *pbbm = layer->GetPBBitmap(i);
if (pbbm)
{
const char *name = pbbm->bi.Filename();
if (name && *name != '\0')
{
char buf[256];
strncpy(buf, name, sizeof(buf));
strlwr(buf);
// If we don't have a search string, or we do and it was
// found in the texture name, add the texture to the list.
if (searchStr[0] == '\0' || strstr(buf, searchStr))
{
if (update == kUpdateLoadList)
{
LVITEM item = {0};
item.mask = LVIF_TEXT | LVIF_PARAM;
item.pszText = mtl->GetName();
item.lParam = (LPARAM)mtl; // A little dangerous, since the user could delete this
int idx = ListView_InsertItem(hList, &item);
ListView_SetItemText(hList, idx, 1, layer->GetName());
ListView_SetItemText(hList, idx, 2, (char*)name);
// If size is uninitialized or the same as the last, keep size
if ((sizeX == -1 && sizeY == -1) || (sizeX == pbbm->bi.Width() && sizeY == pbbm->bi.Height()))
{
sizeX = pbbm->bi.Width();
sizeY = pbbm->bi.Height();
}
// Otherwise clear it
else
{
sizeX = sizeY = 0;
}
}
else if (update == kUpdateReplace)
{
layer->SetBitmapAssetId(gAssetID, i);
BitmapInfo info;
info.SetName(fFileName);
layer->SetBitmap(&info, i);
}
else if (update == kUpdateSetSize)
{
layer->SetExportSize(sizeX, sizeY);
}
}
}
}
}
}
}
if (update == kUpdateLoadList)
{
HWND hButton = GetDlgItem(fDlg, IDC_SET_ALL_BUTTON);
ComboBox_ResetContent(hCombo);
// If all bitmaps are the same size, enable resizing
if (sizeX != -1 && sizeX != 0)
{
sizeX = FloorPow2(sizeX);
sizeY = FloorPow2(sizeY);
char buf[256];
while (sizeX >= 4 && sizeY >= 4)
{
sprintf(buf, "%d x %d", sizeX, sizeY);
int idx = ComboBox_AddString(hCombo, buf);
ComboBox_SetItemData(hCombo, idx, MAKELPARAM(sizeX, sizeY));
sizeX >>= 1;
sizeY >>= 1;
}
ComboBox_SetCurSel(hCombo, 0);
EnableWindow(hCombo, TRUE);
EnableWindow(hButton, TRUE);
}
else
{
EnableWindow(hCombo, FALSE);
EnableWindow(hButton, FALSE);
}
}
int autoSizeType = LVSCW_AUTOSIZE;
if (ListView_GetItemCount(hList) == 0)
autoSizeType = LVSCW_AUTOSIZE_USEHEADER;
ListView_SetColumnWidth(hList, 0, autoSizeType);
ListView_SetColumnWidth(hList, 1, autoSizeType);
ListView_SetColumnWidth(hList, 2, autoSizeType);
}
void plTextureSearch::IPickReplaceTexture()
{
fFileName[0] = '\0';
// if we have the assetman plug-in, then try to use it, unless shift is held down
MaxAssInterface* maxAssInterface = GetMaxAssInterface();
if (maxAssInterface && !(GetKeyState(VK_SHIFT) & 0x8000))
{
maxAssInterface->OpenBitmapDlg(gAssetID, fFileName, sizeof(fFileName));
}
else
{
gAssetID.SetEmpty();
BitmapInfo bi;
TheManager->SelectFileInput(&bi, GetCOREInterface()->GetMAXHWnd(), _T("Select Bitmap Image File"));
strcpy(fFileName, bi.Filename());
}
if (fFileName[0] == '\0')
{
SetDlgItemText(fDlg, IDC_REPLACE_BUTTON, "(none)");
EnableWindow(GetDlgItem(fDlg, IDC_REPLACE_ALL_BUTTON), FALSE);
}
else
{
char fname[_MAX_FNAME+_MAX_EXT], ext[_MAX_EXT];
_splitpath(fFileName, NULL, NULL, fname, ext);
strcat(fname, ext);
SetDlgItemText(fDlg, IDC_REPLACE_BUTTON, fname);
EnableWindow(GetDlgItem(fDlg, IDC_REPLACE_ALL_BUTTON), TRUE);
}
}

View File

@ -0,0 +1,63 @@
/*==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 "max.h"
class plTextureSearch
{
protected:
HWND fDlg;
char fFileName[MAX_PATH];
plTextureSearch();
public:
static plTextureSearch& Instance();
void Toggle();
protected:
enum Update { kUpdateLoadList, kUpdateReplace, kUpdateSetSize };
void IUpdateTextures(Update update);
void IPickReplaceTexture();
static BOOL CALLBACK ForwardDlgProc(HWND hDlg, UINT msg, WPARAM wParam, LPARAM lParam);
BOOL DlgProc(HWND hDlg, UINT msg, WPARAM wParam, LPARAM lParam);
};

View File

@ -0,0 +1,134 @@
//{{NO_DEPENDENCIES}}
// Microsoft Developer Studio generated include file.
// Used by SimpleExport.rc
//
#define IDS_ACT1_DESC 1
#define IDS_ACT1_NAME 2
#define IDS_ACT2_DESC 3
#define IDS_ACT2_NAME 4
#define IDS_ACT3_NAME 5
#define IDS_ACT4_NAME 6
#define IDS_ACT5_NAME 7
#define IDS_ACT6_NAME 8
#define IDS_ACT7_NAME 9
#define IDS_ACT8_DESC 10
#define IDS_ACT8_NAME 11
#define IDS_ACT9_DESC 12
#define IDS_ACT9_NAME 13
#define IDS_ACT10_NAME 14
#define IDS_PLASMA_EXPORT 15
#define IDS_ACT11_NAME 16
#define IDS_ACT11_DESC 17
#define IDS_ACT12_NAME 18
#define IDS_ACT12_DESC 19
#define IDS_ACT_CAT 30
#define IDD_COMP_PANEL 103
#define IDD_SCENEVIEWER 105
#define IDD_GET_LOCATION 106
#define IDD_COMP_MAIN 107
#define IDD_AGE_DESC 108
#define IDD_AGE_NAME 109
#define IDD_UTILS_RES 110
#define IDD_UTILS 111
#define IDB_CURSOR_UP 112
#define IDD_FIND_TEXTURE 112
#define IDB_CURSOR_DOWN 113
#define IDD_EXPORT 113
#define IDB_CURSOR_RIGHT 114
#define IDD_REF_BY 114
#define IDB_CURSOR_LEFT 115
#define IDB_CURSOR_OPEN 116
#define IDB_CURSOR_GRAB 117
#define IDB_CURSOR_CLICKED 118
#define IDB_CURSOR_POISED 119
#define IDR_COMP_MENU 120
#define IDD_AGE_SEQNUM 121
#define IDD_AGE_CHECKIN 122
#define IDD_AGE_SAVEYESNO 123
#define IDC_COMPLIST 1007
#define IDC_BACK 1009
#define IDC_FORWARD 1010
#define IDC_NUM_TARGS 1011
#define IDC_TREE 1014
#define IDC_ATTACH 1015
#define IDC_UPDATE 1017
#define IDC_SPINNER 1019
#define IDC_EDIT 1020
#define IDC_LIST_LOC 1021
#define IDC_CAP_EDIT 1021
#define IDC_CHECK_DEFAULT 1022
#define IDC_CAP_SPINNER 1022
#define IDC_PROMPT 1023
#define IDC_DIR 1024
#define IDC_BROWSE_EXPORT 1025
#define IDC_COMMENT_TEXT 1026
#define IDC_COMMENTS 1028
#define IDC_AGE_NEW 1030
#define IDC_PAGE_NEW 1032
#define IDC_PAGE_DEL 1033
#define IDC_DATE 1034
#define IDC_TIME 1035
#define IDC_AGE_NAME 1036
#define IDC_RESHADE 1037
#define IDC_DAYLEN_EDIT 1038
#define IDC_DAYLEN_SPINNER 1039
#define IDC_REG_TREE 1040
#define IDC_SEQPREFIX_EDIT 1040
#define IDC_RES 1041
#define IDC_SEQPREFIX_SPIN 1041
#define IDC_REFRESH 1042
#define IDC_CLIENT_PATH 1044
#define IDC_REUSE_DATA 1045
#define IDC_EXPORT_PATH 1045
#define IDC_EXE 1046
#define IDC_START 1047
#define IDC_PAGE_LIST 1048
#define IDC_FIND_EDIT 1049
#define IDC_UPDATE_BUTTON 1050
#define IDC_REPLACE_ALL_BUTTON 1052
#define IDC_TEXTURE_LIST 1053
#define IDC_SET_ALL_BUTTON 1054
#define IDC_REPLACE_BUTTON 1055
#define IDC_PRESHADE_CHECK 1056
#define IDC_PHYSICAL_CHECK 1057
#define IDC_EXPORT 1058
#define IDC_LAST_EXPORT 1059
#define IDC_PAGE_COMBO 1060
#define IDC_LIGHTMAP_CHECK 1061
#define IDC_REF_BY_BUTTON 1062
#define IDC_UV_CHECK 1062
#define IDC_REF_LIST 1063
#define IDC_CLOSE 1064
#define IDC_AGE_LIST 1065
#define IDC_RSVDCHECK 1066
#define IDC_EDITREG 1067
#define IDC_AGEMSG 1069
#define IDC_ADMMSG 1070
#define IDC_INFOMSG 1071
#define IDC_AGEDESC 1071
#define IDC_RADIO_FILE 1072
#define IDC_RADIO_DIR 1073
#define IDC_AGE_CHECKOUT 1074
#define IDC_AGE_CHECKIN 1075
#define IDC_AGE_UNDOCHECKOUT 1076
#define IDC_AGELIST_STATIC 1077
#define IDC_ADM_DONTLOAD 1078
#define IDC_ADM_LOADSDL 1079
#define IDC_SIZE_COMBO 1081
#define IDC_HIGH_SDL_CHECK 1082
#define IDC_BRANCHCOMBO 1083
#define IDC_ADM_LOCAL_ONLY 1084
#define IDC_ADM_VOLATILE 1085
#define ID_REFRESH 40002
#define ID_REMOVE_UNUSED 40003
// Next default values for new objects
//
#ifdef APSTUDIO_INVOKED
#ifndef APSTUDIO_READONLY_SYMBOLS
#define _APS_NEXT_RESOURCE_VALUE 123
#define _APS_NEXT_COMMAND_VALUE 40004
#define _APS_NEXT_CONTROL_VALUE 1086
#define _APS_NEXT_SYMED_VALUE 101
#endif
#endif