mirror of
https://foundry.openuru.org/gitblit/r/CWE-ou-minkata.git
synced 2025-07-18 11:19:10 +00:00
@ -10,12 +10,11 @@ endif()
|
|||||||
# Max Stuff goes below here...
|
# Max Stuff goes below here...
|
||||||
if(3dsm_BUILD_PLUGIN)
|
if(3dsm_BUILD_PLUGIN)
|
||||||
add_definitions(-DMAXPLUGINCODE)
|
add_definitions(-DMAXPLUGINCODE)
|
||||||
|
|
||||||
add_subdirectory(MaxComponent)
|
add_subdirectory(MaxComponent)
|
||||||
add_subdirectory(MaxConvert)
|
add_subdirectory(MaxConvert)
|
||||||
add_subdirectory(MaxExport)
|
add_subdirectory(MaxExport)
|
||||||
add_subdirectory(MaxMain)
|
add_subdirectory(MaxMain)
|
||||||
add_subdirectory(MaxPlasmaLights)
|
add_subdirectory(MaxPlasmaLights)
|
||||||
add_subdirectory(MaxPlasmaMtls)
|
add_subdirectory(MaxPlasmaMtls)
|
||||||
#add_subdirectory(MaxSceneViewer) # NOTE: Uses Plasma classes that do not exist
|
endif()
|
||||||
endif()
|
|
||||||
|
@ -62,6 +62,7 @@ set(MaxMain_SOURCES
|
|||||||
plGetLocationDlg.cpp
|
plGetLocationDlg.cpp
|
||||||
plMaxAccelerators.cpp
|
plMaxAccelerators.cpp
|
||||||
plMaxCFGFile.cpp
|
plMaxCFGFile.cpp
|
||||||
|
plMaxFileData.cpp
|
||||||
plMaxMenu.cpp
|
plMaxMenu.cpp
|
||||||
plMaxMeshExtractor.cpp
|
plMaxMeshExtractor.cpp
|
||||||
plMaxNode.cpp
|
plMaxNode.cpp
|
||||||
|
@ -52,12 +52,9 @@ You can contact Cyan Worlds, Inc. by email legal@cyan.com
|
|||||||
|
|
||||||
#include "GlobalUtility.h"
|
#include "GlobalUtility.h"
|
||||||
|
|
||||||
#include "MaxSceneViewer/SceneSync.h"
|
|
||||||
|
|
||||||
#include "MaxComponent/ComponentDummies.h"
|
#include "MaxComponent/ComponentDummies.h"
|
||||||
#include "plActionTableMgr.h"
|
#include "plActionTableMgr.h"
|
||||||
#include "plMaxMenu.h"
|
#include "plMaxMenu.h"
|
||||||
#include "MaxSceneViewer/plMaxFileData.h"
|
|
||||||
#include "pfPython/cyPythonInterface.h"
|
#include "pfPython/cyPythonInterface.h"
|
||||||
#include "MaxPlasmaMtls/Layers/plPlasmaMAXLayer.h"
|
#include "MaxPlasmaMtls/Layers/plPlasmaMAXLayer.h"
|
||||||
|
|
||||||
@ -65,6 +62,10 @@ You can contact Cyan Worlds, Inc. by email legal@cyan.com
|
|||||||
#include "pfLocalizationMgr/pfLocalizationMgr.h"
|
#include "pfLocalizationMgr/pfLocalizationMgr.h"
|
||||||
#include "plGImage/plFontCache.h"
|
#include "plGImage/plFontCache.h"
|
||||||
|
|
||||||
|
#include "plPythonMgr.h"
|
||||||
|
#include "plPluginResManager.h"
|
||||||
|
#include "plSDL/plSDL.h"
|
||||||
|
|
||||||
extern plActionTableMgr theActionTableMgr;
|
extern plActionTableMgr theActionTableMgr;
|
||||||
extern HINSTANCE hInstance;
|
extern HINSTANCE hInstance;
|
||||||
|
|
||||||
@ -172,7 +173,6 @@ DWORD PlasmaMax::Start()
|
|||||||
DummyCodeIncludeFuncClickDrag(); //Click-Draggable comp
|
DummyCodeIncludeFuncClickDrag(); //Click-Draggable comp
|
||||||
DummyCodeIncludeFuncInventStuff(); //Inventory Object comp
|
DummyCodeIncludeFuncInventStuff(); //Inventory Object comp
|
||||||
DummyCodeIncludeFuncVolumeGadget(); // inside/enter/exit phys volume activator
|
DummyCodeIncludeFuncVolumeGadget(); // inside/enter/exit phys volume activator
|
||||||
// DummyCodeIncludeFuncActivatorGadget(); // activator activator
|
|
||||||
DummyCodeIncludeFuncSoftVolume(); // Soft Volumes
|
DummyCodeIncludeFuncSoftVolume(); // Soft Volumes
|
||||||
DummyCodeIncludeFuncPhysConst(); // Phys Constraints
|
DummyCodeIncludeFuncPhysConst(); // Phys Constraints
|
||||||
DummyCodeIncludeFuncCameras(); // new camera code
|
DummyCodeIncludeFuncCameras(); // new camera code
|
||||||
@ -203,15 +203,6 @@ DWORD PlasmaMax::Start()
|
|||||||
DummyCodeIncludeFuncClimbTrigger();
|
DummyCodeIncludeFuncClimbTrigger();
|
||||||
DummyCodeIncludeFuncObjectFlocker();
|
DummyCodeIncludeFuncObjectFlocker();
|
||||||
DummyCodeIncludeFuncGrassShader();
|
DummyCodeIncludeFuncGrassShader();
|
||||||
|
|
||||||
// Register the SceneViewer with Max
|
|
||||||
#ifdef MAXSCENEVIEWER_ENABLED
|
|
||||||
SceneSync::Instance();
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef MAXSCENEVIEWER_ENABLED
|
|
||||||
InitMaxFileData();
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// Setup the localization mgr
|
// Setup the localization mgr
|
||||||
// Dirty hacks are because Cyan sucks...
|
// Dirty hacks are because Cyan sucks...
|
||||||
@ -223,6 +214,16 @@ DWORD PlasmaMax::Start()
|
|||||||
return GUPRESULT_NOKEEP;
|
return GUPRESULT_NOKEEP;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Load S-D-teh-Ls
|
||||||
|
plFileName oldCwd = plFileSystem::GetCWD();
|
||||||
|
plFileSystem::SetCWD(pathTemp);
|
||||||
|
plSDLMgr::GetInstance()->Init();
|
||||||
|
plFileSystem::SetCWD(oldCwd);
|
||||||
|
|
||||||
|
// Initialize the ResManager and Python
|
||||||
|
plPythonMgr::Instance().LoadPythonFiles();
|
||||||
|
hsgResMgr::Init(new plPluginResManager);
|
||||||
|
|
||||||
// Setup the doggone plugin
|
// Setup the doggone plugin
|
||||||
plComponentShow::Init();
|
plComponentShow::Init();
|
||||||
plCreateMenu();
|
plCreateMenu();
|
||||||
|
@ -57,14 +57,8 @@ You can contact Cyan Worlds, Inc. by email legal@cyan.com
|
|||||||
#pragma hdrstop
|
#pragma hdrstop
|
||||||
|
|
||||||
#include "MaxExport/SimpleExport.h"
|
#include "MaxExport/SimpleExport.h"
|
||||||
|
|
||||||
#include "MaxPlasmaMtls/plMtlImport.h"
|
#include "MaxPlasmaMtls/plMtlImport.h"
|
||||||
|
|
||||||
#include "plPythonMgr.h"
|
|
||||||
#include "plPluginResManager.h"
|
|
||||||
#include "plSDL/plSDL.h"
|
|
||||||
#include "plMaxCFGFile.h"
|
|
||||||
|
|
||||||
extern ClassDesc* GetGUPDesc();
|
extern ClassDesc* GetGUPDesc();
|
||||||
extern ClassDesc* GetComponentUtilDesc();
|
extern ClassDesc* GetComponentUtilDesc();
|
||||||
extern ClassDesc* GetComponentMgrDesc();
|
extern ClassDesc* GetComponentMgrDesc();
|
||||||
@ -72,7 +66,6 @@ extern ClassDesc* GetMaxFileDataDesc();
|
|||||||
extern ClassDesc* GetMaxUtilsDesc();
|
extern ClassDesc* GetMaxUtilsDesc();
|
||||||
|
|
||||||
static HSClassDesc2 HSDesc;
|
static HSClassDesc2 HSDesc;
|
||||||
static int controlsInit = FALSE;
|
|
||||||
HINSTANCE hInstance = NULL;
|
HINSTANCE hInstance = NULL;
|
||||||
|
|
||||||
/*inline*/ TCHAR *GetString(int id)
|
/*inline*/ TCHAR *GetString(int id)
|
||||||
@ -113,7 +106,7 @@ __declspec(dllexport) ClassDesc *LibClassDesc(int i)
|
|||||||
switch(i)
|
switch(i)
|
||||||
{
|
{
|
||||||
case 0:
|
case 0:
|
||||||
return &HSDesc;
|
return &HSDesc;
|
||||||
case 1:
|
case 1:
|
||||||
return GetGUPDesc();
|
return GetGUPDesc();
|
||||||
case 2:
|
case 2:
|
||||||
@ -123,11 +116,7 @@ __declspec(dllexport) ClassDesc *LibClassDesc(int i)
|
|||||||
case 4:
|
case 4:
|
||||||
return GetComponentMgrDesc();
|
return GetComponentMgrDesc();
|
||||||
case 5:
|
case 5:
|
||||||
#ifdef MAXSCENEVIEWER_ENABLED
|
|
||||||
return GetMaxFileDataDesc();
|
return GetMaxFileDataDesc();
|
||||||
#else
|
|
||||||
return 0;
|
|
||||||
#endif
|
|
||||||
case 6:
|
case 6:
|
||||||
return GetMaxUtilsDesc();
|
return GetMaxUtilsDesc();
|
||||||
default:
|
default:
|
||||||
@ -155,35 +144,10 @@ BOOL WINAPI DllMain(HINSTANCE hinstDLL,ULONG fdwReason,LPVOID lpvReserved)
|
|||||||
{
|
{
|
||||||
hInstance = hinstDLL;
|
hInstance = hinstDLL;
|
||||||
|
|
||||||
if (!controlsInit)
|
switch (fdwReason)
|
||||||
{
|
|
||||||
controlsInit = TRUE;
|
|
||||||
|
|
||||||
// jaguar controls
|
|
||||||
INIT_CUSTOM_CONTROLS(hInstance);
|
|
||||||
|
|
||||||
// initialize Chicago controls
|
|
||||||
InitCommonControls();
|
|
||||||
|
|
||||||
plPythonMgr::Instance().LoadPythonFiles();
|
|
||||||
|
|
||||||
plFileName clientPath = plMaxConfig::GetClientPath(false, true);
|
|
||||||
if (clientPath.IsValid())
|
|
||||||
{
|
|
||||||
plFileName oldCwd = plFileSystem::GetCWD();
|
|
||||||
plFileSystem::SetCWD(clientPath);
|
|
||||||
plSDLMgr::GetInstance()->Init();
|
|
||||||
plFileSystem::SetCWD(oldCwd);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Initialize the ResManager
|
|
||||||
plResManager* pRmgr = new plPluginResManager;
|
|
||||||
hsgResMgr::Init(pRmgr);
|
|
||||||
}
|
|
||||||
|
|
||||||
switch (fdwReason)
|
|
||||||
{
|
{
|
||||||
case DLL_PROCESS_ATTACH:
|
case DLL_PROCESS_ATTACH:
|
||||||
|
INIT_CUSTOM_CONTROLS(hInstance);
|
||||||
break;
|
break;
|
||||||
case DLL_THREAD_ATTACH:
|
case DLL_THREAD_ATTACH:
|
||||||
break;
|
break;
|
||||||
@ -192,7 +156,8 @@ BOOL WINAPI DllMain(HINSTANCE hinstDLL,ULONG fdwReason,LPVOID lpvReserved)
|
|||||||
case DLL_PROCESS_DETACH:
|
case DLL_PROCESS_DETACH:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
return(TRUE);
|
|
||||||
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////////////////
|
||||||
|
158
Sources/Tools/MaxMain/plMaxFileData.cpp
Normal file
158
Sources/Tools/MaxMain/plMaxFileData.cpp
Normal file
@ -0,0 +1,158 @@
|
|||||||
|
/*==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 "plString.h"
|
||||||
|
|
||||||
|
#include <max.h>
|
||||||
|
#pragma hdrstop
|
||||||
|
|
||||||
|
/** \file This file contains a stub implementation for the ClassDescs left behind by
|
||||||
|
* Cyan's SceneViewer crap. This just keeps new versions of 3ds Max from crashing on
|
||||||
|
* null ClassDescs returned by the GUP. It also silences that "Dll Missing" dialog that
|
||||||
|
* everyone evar wants to whine about even though it means absolutely nothing.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#define PLASMA_FILE_DATA_CID Class_ID(0x255a700a, 0x285279dc)
|
||||||
|
#define MAXFILE_DATA_CHUNK 1001
|
||||||
|
static const uint8_t kVersion = 1;
|
||||||
|
|
||||||
|
class plMaxFileDataControl : public StdControl
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
SYSTEMTIME fCodeBuildTime;
|
||||||
|
char fBranch[128];
|
||||||
|
|
||||||
|
plMaxFileDataControl()
|
||||||
|
{
|
||||||
|
memset(&fCodeBuildTime, 0, sizeof(SYSTEMTIME));
|
||||||
|
memset(&fBranch, 0, arrsize(fBranch));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Animatable
|
||||||
|
virtual void EditTrackParams(TimeValue t, ParamDimensionBase *dim, TCHAR *pname, HWND hParent, IObjParam *ip, DWORD flags) { }
|
||||||
|
int TrackParamsType() { return TRACKPARAMS_WHOLE; }
|
||||||
|
virtual void DeleteThis() { delete this; }
|
||||||
|
|
||||||
|
// ReferenceMaker
|
||||||
|
virtual RefResult NotifyRefChanged(Interval changeInt, RefTargetHandle hTarget, PartID& partID, RefMessage message)
|
||||||
|
{
|
||||||
|
return REF_DONTCARE;
|
||||||
|
}
|
||||||
|
|
||||||
|
Class_ID ClassID() { return PLASMA_FILE_DATA_CID; }
|
||||||
|
SClass_ID SuperClassID() { return CTRL_FLOAT_CLASS_ID; }
|
||||||
|
void GetClassName(TSTR& s) { s = "DEAD - SceneViewer"; }
|
||||||
|
|
||||||
|
// Control methods
|
||||||
|
RefTargetHandle Clone(RemapDir& remap) { return new plMaxFileDataControl(); }
|
||||||
|
void Copy(Control* from) { }
|
||||||
|
virtual BOOL IsReplaceable() { return FALSE; }
|
||||||
|
|
||||||
|
// StdControl methods
|
||||||
|
void GetValueLocalTime(TimeValue t, void* val, Interval& valid, GetSetMethod method = CTRL_ABSOLUTE) { }
|
||||||
|
void SetValueLocalTime(TimeValue t, void* val, int commit, GetSetMethod method) { }
|
||||||
|
void Extrapolate(Interval range, TimeValue t, void* val, Interval& valid, int type) { }
|
||||||
|
void *CreateTempValue() { return nullptr; }
|
||||||
|
void DeleteTempValue(void *val) { }
|
||||||
|
void ApplyValue(void* val, void* delta) { }
|
||||||
|
void MultiplyValue(void* val, float m) { }
|
||||||
|
|
||||||
|
// MyControl methods
|
||||||
|
IOResult Load(ILoad *iload);
|
||||||
|
IOResult Save(ISave *isave);
|
||||||
|
};
|
||||||
|
|
||||||
|
IOResult plMaxFileDataControl::Load(ILoad *iload)
|
||||||
|
{
|
||||||
|
ULONG nb;
|
||||||
|
IOResult res;
|
||||||
|
while (IO_OK==(res=iload->OpenChunk()))
|
||||||
|
{
|
||||||
|
if (iload->CurChunkID() == MAXFILE_DATA_CHUNK)
|
||||||
|
{
|
||||||
|
uint8_t version = 0;
|
||||||
|
res = iload->Read(&version, sizeof(uint8_t), &nb);
|
||||||
|
res = iload->Read(&fCodeBuildTime, sizeof(SYSTEMTIME), &nb);
|
||||||
|
|
||||||
|
int branchLen = 0;
|
||||||
|
iload->Read(&branchLen, sizeof(int), &nb);
|
||||||
|
iload->Read(&fBranch, branchLen, &nb);
|
||||||
|
}
|
||||||
|
|
||||||
|
iload->CloseChunk();
|
||||||
|
if (res != IO_OK)
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
return IO_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
IOResult plMaxFileDataControl::Save(ISave *isave)
|
||||||
|
{
|
||||||
|
ULONG nb;
|
||||||
|
isave->BeginChunk(MAXFILE_DATA_CHUNK);
|
||||||
|
|
||||||
|
isave->Write(&kVersion, sizeof(kVersion), &nb);
|
||||||
|
isave->Write(&fCodeBuildTime, sizeof(SYSTEMTIME), &nb);
|
||||||
|
|
||||||
|
int branchLen = strlen(fBranch)+1;
|
||||||
|
isave->Write(&branchLen, sizeof(int), &nb);
|
||||||
|
isave->Write(&fBranch, branchLen, &nb);
|
||||||
|
|
||||||
|
isave->EndChunk();
|
||||||
|
return IO_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
class MaxFileDataClassDesc : public ClassDesc
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
int IsPublic() { return FALSE; }
|
||||||
|
void* Create(BOOL loading) { return new plMaxFileDataControl; }
|
||||||
|
const TCHAR* ClassName() { return _T("MaxFileData"); }
|
||||||
|
SClass_ID SuperClassID() { return CTRL_FLOAT_CLASS_ID; }
|
||||||
|
Class_ID ClassID() { return PLASMA_FILE_DATA_CID; }
|
||||||
|
const TCHAR* Category() { return _T(""); }
|
||||||
|
};
|
||||||
|
|
||||||
|
MaxFileDataClassDesc gMaxFileDataClassDesc;
|
||||||
|
ClassDesc* GetMaxFileDataDesc() { return &gMaxFileDataClassDesc; }
|
@ -60,7 +60,6 @@ You can contact Cyan Worlds, Inc. by email legal@cyan.com
|
|||||||
#include "plMaxCFGFile.h"
|
#include "plMaxCFGFile.h"
|
||||||
#include "plResCollector.h"
|
#include "plResCollector.h"
|
||||||
#include "plAgeDescInterface.h"
|
#include "plAgeDescInterface.h"
|
||||||
#include "MaxSceneViewer/SceneViewer.h"
|
|
||||||
#include "plNodeLock.h"
|
#include "plNodeLock.h"
|
||||||
#include "plResetXform.h"
|
#include "plResetXform.h"
|
||||||
#include "plTextureSearch.h"
|
#include "plTextureSearch.h"
|
||||||
@ -81,7 +80,7 @@ enum
|
|||||||
kActionResCollect,
|
kActionResCollect,
|
||||||
kActionAgeDesc,
|
kActionAgeDesc,
|
||||||
kActionCompCopy,
|
kActionCompCopy,
|
||||||
kActionSceneViewer,
|
kActionSceneViewer, // DEAD. But I don't dare remove it--don't want to break stuff :/
|
||||||
kActionLock,
|
kActionLock,
|
||||||
kActionUnlock,
|
kActionUnlock,
|
||||||
kActionTexSearch,
|
kActionTexSearch,
|
||||||
@ -201,15 +200,6 @@ bool DoAction(int id)
|
|||||||
CopyComponents();
|
CopyComponents();
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
case kActionSceneViewer:
|
|
||||||
#ifdef MAXSCENEVIEWER_ENABLED
|
|
||||||
SceneViewer::Instance().Show();
|
|
||||||
return true;
|
|
||||||
#else
|
|
||||||
hsMessageBox("The SceneViewer has been disabled in this build", "Disabled", 0);
|
|
||||||
return true;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
case kActionLock:
|
case kActionLock:
|
||||||
plNodeLock().Lock();
|
plNodeLock().Lock();
|
||||||
return true;
|
return true;
|
||||||
@ -420,18 +410,6 @@ void plCreateMenu()
|
|||||||
pMenuItem->ActAsSeparator();
|
pMenuItem->ActAsSeparator();
|
||||||
pPlasmaMenu->AddItem(pMenuItem);
|
pPlasmaMenu->AddItem(pMenuItem);
|
||||||
|
|
||||||
#ifdef MAXSCENEVIEWER_ENABLED
|
|
||||||
// Add the SceneViewer to the menu
|
|
||||||
pMenuItem = GetIMenuItem();
|
|
||||||
pMenuItem->SetActionItem(pActionTable->GetAction(kActionSceneViewer));
|
|
||||||
pPlasmaMenu->AddItem(pMenuItem);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// Add a separator
|
|
||||||
pMenuItem = GetIMenuItem();
|
|
||||||
pMenuItem->ActAsSeparator();
|
|
||||||
pPlasmaMenu->AddItem(pMenuItem);
|
|
||||||
|
|
||||||
// Add the Lock Selected to the menu
|
// Add the Lock Selected to the menu
|
||||||
pMenuItem = GetIMenuItem();
|
pMenuItem = GetIMenuItem();
|
||||||
pMenuItem->SetActionItem(pActionTable->GetAction(kActionLock));
|
pMenuItem->SetActionItem(pActionTable->GetAction(kActionLock));
|
||||||
|
@ -1,35 +0,0 @@
|
|||||||
include_directories("../")
|
|
||||||
include_directories("../../Plasma/Apps")
|
|
||||||
include_directories("../../Plasma/CoreLib")
|
|
||||||
include_directories("../../Plasma/FeatureLib")
|
|
||||||
include_directories("../../Plasma/FeatureLib/inc")
|
|
||||||
include_directories("../../Plasma/NucleusLib")
|
|
||||||
include_directories("../../Plasma/NucleusLib/inc")
|
|
||||||
include_directories("../../Plasma/PubUtilLib")
|
|
||||||
include_directories("../../Plasma/PubUtilLib/inc")
|
|
||||||
include_directories(${3dsm_INCLUDE_DIR})
|
|
||||||
|
|
||||||
set(MaxSceneViewer_HEADERS
|
|
||||||
plKeyRefSort.h
|
|
||||||
plMaxFileData.h
|
|
||||||
plPluginApp.h
|
|
||||||
plPluginClient.h
|
|
||||||
SceneSync.h
|
|
||||||
SceneViewer.h
|
|
||||||
SceneWatcher.h
|
|
||||||
)
|
|
||||||
|
|
||||||
set(MaxSceneViewer_SOURCES
|
|
||||||
plKeyRefSort.cpp
|
|
||||||
plMaxFileData.cpp
|
|
||||||
plPluginApp.cpp
|
|
||||||
plPluginClient.cpp
|
|
||||||
SceneSync.cpp
|
|
||||||
SceneViewer.cpp
|
|
||||||
SceneWatcher.cpp
|
|
||||||
)
|
|
||||||
|
|
||||||
add_library(MaxSceneViewer STATIC ${MaxSceneViewer_HEADERS} ${MaxSceneViewer_SOURCES})
|
|
||||||
|
|
||||||
source_group("Header Files" FILES ${MaxSceneViewer_HEADERS})
|
|
||||||
source_group("Source Files" FILES ${MaxSceneViewer_SOURCES})
|
|
@ -1,678 +0,0 @@
|
|||||||
/*==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 "SceneSync.h"
|
|
||||||
#include "SceneWatcher.h"
|
|
||||||
|
|
||||||
#define MAXPLUGINCODE
|
|
||||||
|
|
||||||
#include "pnSceneObject/plSceneObject.h"
|
|
||||||
#include "MaxMain/plMaxNode.h"
|
|
||||||
#include "MaxMain/plPluginResManager.h"
|
|
||||||
#include "MaxConvert/plConvert.h"
|
|
||||||
#include "MaxConvert/hsMaterialConverter.h"
|
|
||||||
#include "MaxComponent/plComponent.h"
|
|
||||||
#include "hsThread.h"
|
|
||||||
#include "hsSTLStream.h"
|
|
||||||
#include "plClient/plClientUpdateFormat.h"
|
|
||||||
|
|
||||||
#include "plMaxFileData.h"
|
|
||||||
|
|
||||||
SceneSync& SceneSync::Instance()
|
|
||||||
{
|
|
||||||
static SceneSync theInstance;
|
|
||||||
return theInstance;
|
|
||||||
}
|
|
||||||
|
|
||||||
SceneSync::SceneSync() : fUpdateSignal(nil), fSceneWatcher(nil), fTimerID(0), fUpdateFreq(-1)
|
|
||||||
{
|
|
||||||
// Need to save the current state
|
|
||||||
RegisterNotification(INotify, 0, NOTIFY_SYSTEM_PRE_RESET);
|
|
||||||
RegisterNotification(INotify, 0, NOTIFY_SYSTEM_PRE_NEW);
|
|
||||||
RegisterNotification(INotify, 0, NOTIFY_FILE_PRE_OPEN);
|
|
||||||
RegisterNotification(INotify, 0, NOTIFY_PRE_EXPORT);
|
|
||||||
|
|
||||||
// Need to load the saved state
|
|
||||||
RegisterNotification(INotify, 0, NOTIFY_FILE_POST_OPEN);
|
|
||||||
RegisterNotification(INotify, 0, NOTIFY_POST_EXPORT);
|
|
||||||
RegisterNotification(INotify, 0, NOTIFY_EXPORT_FAILED);
|
|
||||||
|
|
||||||
// Need to save the current state and cleanup
|
|
||||||
RegisterNotification(INotify, 0, NOTIFY_SYSTEM_SHUTDOWN);
|
|
||||||
}
|
|
||||||
|
|
||||||
void SceneSync::IShutdown()
|
|
||||||
{
|
|
||||||
UnRegisterNotification(INotify, 0, NOTIFY_SYSTEM_PRE_RESET);
|
|
||||||
UnRegisterNotification(INotify, 0, NOTIFY_SYSTEM_PRE_NEW);
|
|
||||||
UnRegisterNotification(INotify, 0, NOTIFY_FILE_PRE_OPEN);
|
|
||||||
UnRegisterNotification(INotify, 0, NOTIFY_PRE_EXPORT);
|
|
||||||
|
|
||||||
UnRegisterNotification(INotify, 0, NOTIFY_FILE_POST_OPEN);
|
|
||||||
UnRegisterNotification(INotify, 0, NOTIFY_POST_EXPORT);
|
|
||||||
UnRegisterNotification(INotify, 0, NOTIFY_EXPORT_FAILED);
|
|
||||||
|
|
||||||
UnRegisterNotification(INotify, 0, NOTIFY_SYSTEM_SHUTDOWN);
|
|
||||||
|
|
||||||
delete fUpdateSignal;
|
|
||||||
fUpdateSignal = nil;
|
|
||||||
}
|
|
||||||
|
|
||||||
#include <shellapi.h>
|
|
||||||
#include "../MaxMain/plMaxCFGFile.h"
|
|
||||||
#include "../MaxExport/plExportErrorMsg.h"
|
|
||||||
|
|
||||||
// TEMP
|
|
||||||
#include <direct.h>
|
|
||||||
|
|
||||||
bool SceneSync::CreateClientData()
|
|
||||||
{
|
|
||||||
char path[MAX_PATH];
|
|
||||||
if (!GetOutputDir(path))
|
|
||||||
return false;
|
|
||||||
|
|
||||||
char datPath[MAX_PATH];
|
|
||||||
sprintf(datPath, "%sdat", path);
|
|
||||||
|
|
||||||
// Setup for the convert
|
|
||||||
plExportErrorMsg msg;
|
|
||||||
plConvertSettings settings;
|
|
||||||
settings.fSceneViewer = true;
|
|
||||||
plConvert::Instance().Init(GetCOREInterface(), &msg, &settings);
|
|
||||||
|
|
||||||
// Do the convert
|
|
||||||
plConvert::Instance().Convert();
|
|
||||||
|
|
||||||
// If convert failed, fail too
|
|
||||||
if (msg.IsBogus())
|
|
||||||
return false;
|
|
||||||
|
|
||||||
// Clear the dirty flags since everything is fresh
|
|
||||||
IClearDirtyRecur((plMaxNode*)GetCOREInterface()->GetRootNode());
|
|
||||||
|
|
||||||
//
|
|
||||||
// Write the converted data out and page out the objects
|
|
||||||
//
|
|
||||||
IDeletePath(path);
|
|
||||||
CreateDirectory(path, NULL);
|
|
||||||
CreateDirectory(datPath, NULL);
|
|
||||||
|
|
||||||
// TEMP
|
|
||||||
char oldCWD[MAX_PATH];
|
|
||||||
getcwd(oldCWD, MAX_PATH);
|
|
||||||
chdir(path);
|
|
||||||
|
|
||||||
hsAssert( false, "YOU NEED TO FIX ME" );
|
|
||||||
// hsgResMgr::ResMgr()->Write();
|
|
||||||
|
|
||||||
// TEMP
|
|
||||||
chdir(oldCWD);
|
|
||||||
|
|
||||||
IWriteNodeMap(path);
|
|
||||||
|
|
||||||
// TEMP
|
|
||||||
hsMaterialConverter::Instance().FreeMaterialCache(path);
|
|
||||||
|
|
||||||
hsAssert( false, "YOU NEED TO FIX ME" );
|
|
||||||
// hsgResMgr::ResMgr()->PageOutConverted();
|
|
||||||
hsgResMgr::Reset();
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool SceneSync::IsClientRunning()
|
|
||||||
{
|
|
||||||
return (fUpdateSignal != nil);
|
|
||||||
}
|
|
||||||
|
|
||||||
void SceneSync::IShutdownClient()
|
|
||||||
{
|
|
||||||
hsNamedPipeStream outStream(hsNamedPipeStream::kThrowOnError, 500);
|
|
||||||
try
|
|
||||||
{
|
|
||||||
if (outStream.Open(fPipeName, "w"))
|
|
||||||
{
|
|
||||||
// Signal the Client
|
|
||||||
fUpdateSignal->Signal();
|
|
||||||
|
|
||||||
if (outStream.WaitForClientConnect())
|
|
||||||
outStream.WriteByte(ClientUpdate::kShutdown);
|
|
||||||
|
|
||||||
outStream.Close();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
catch (hsNamedPipeStream*)
|
|
||||||
{
|
|
||||||
hsAssert(0, "Error writing to pipe");
|
|
||||||
outStream.Close();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void SceneSync::SetUpdateFreq(int freq)
|
|
||||||
{
|
|
||||||
fUpdateFreq = freq;
|
|
||||||
|
|
||||||
// If the client is running, change it's update freq
|
|
||||||
if (IsClientRunning())
|
|
||||||
{
|
|
||||||
// Kill the old timer
|
|
||||||
if (fTimerID != 0)
|
|
||||||
{
|
|
||||||
KillTimer(NULL, fTimerID);
|
|
||||||
fTimerID = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Create a new timer
|
|
||||||
if (fUpdateFreq != -1)
|
|
||||||
fTimerID = SetTimer(NULL, 0, fUpdateFreq, ITimerProc);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
bool SceneSync::BeginClientSync(const char *semaphoreName, const char *pipeName)
|
|
||||||
{
|
|
||||||
char path[MAX_PATH];
|
|
||||||
if (!GetOutputDir(path))
|
|
||||||
return false;
|
|
||||||
|
|
||||||
char datPath[MAX_PATH];
|
|
||||||
sprintf(datPath, "%sdat", path);
|
|
||||||
|
|
||||||
// Load the saved rooms and their keys (but not objects)
|
|
||||||
hsAssert( false, "YOU NEED TO FIX ME" );
|
|
||||||
// hsgResMgr::ResMgr()->ForceLoadDirectory(datPath, true/*false*/); // TEMP
|
|
||||||
|
|
||||||
// Set the keys in the plMaxNodes. Also, delete Plasma objects for any
|
|
||||||
// plMaxNodes that can't be found (must have been deleted).
|
|
||||||
IReadNodeMap(path);
|
|
||||||
|
|
||||||
if (!fSceneWatcher)
|
|
||||||
IStartWatching(true);
|
|
||||||
|
|
||||||
if (fUpdateFreq != -1)
|
|
||||||
fTimerID = SetTimer(NULL, 0, fUpdateFreq, ITimerProc);
|
|
||||||
|
|
||||||
// Update();
|
|
||||||
|
|
||||||
fUpdateSignal = new hsSemaphore(0, semaphoreName);
|
|
||||||
|
|
||||||
fPipeName = pipeName;
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
void SceneSync::EndClientSync(bool abort)
|
|
||||||
{
|
|
||||||
if (fTimerID != 0 || fUpdateSignal)
|
|
||||||
{
|
|
||||||
KillTimer(NULL, fTimerID);
|
|
||||||
fTimerID = 0;
|
|
||||||
|
|
||||||
if (!abort)
|
|
||||||
{
|
|
||||||
SaveResMgr();
|
|
||||||
IShutdownClient();
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// Delete files so we won't try to run with this possibly corrupted data
|
|
||||||
char path[MAX_PATH];
|
|
||||||
if (GetOutputDir(path))
|
|
||||||
IDeletePath(path);
|
|
||||||
}
|
|
||||||
|
|
||||||
delete fUpdateSignal;
|
|
||||||
fUpdateSignal = nil;
|
|
||||||
|
|
||||||
hsAssert( false, "YOU NEED TO FIX ME" );
|
|
||||||
// hsgResMgr::ResMgr()->PageOutConverted();
|
|
||||||
// hsgResMgr::Reset();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#include "../pnKeyedObject/plKey.h"
|
|
||||||
|
|
||||||
void SceneSync::IClearDirtyRecur(plMaxNode *node)
|
|
||||||
{
|
|
||||||
node->SetDirty(plMaxNode::kAllDirty, false);
|
|
||||||
|
|
||||||
for (int i = 0; i < node->NumberOfChildren(); i++)
|
|
||||||
IClearDirtyRecur((plMaxNode*)node->GetChildNode(i));
|
|
||||||
}
|
|
||||||
|
|
||||||
void SceneSync::IDeletePath(const char *path)
|
|
||||||
{
|
|
||||||
// Remove any files in the dat directory
|
|
||||||
char datPath[MAX_PATH];
|
|
||||||
sprintf(datPath, "%sdat\\", path);
|
|
||||||
hsFolderIterator folder(datPath);
|
|
||||||
while (folder.NextFile())
|
|
||||||
{
|
|
||||||
char file[MAX_PATH];
|
|
||||||
folder.GetPathAndName(file);
|
|
||||||
DeleteFile(file);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Remove the dat directory
|
|
||||||
// RemoveDirectory(datPath);
|
|
||||||
|
|
||||||
// Remove any files in the root dir
|
|
||||||
folder.SetPath(path);
|
|
||||||
while (folder.NextFile())
|
|
||||||
{
|
|
||||||
char file[MAX_PATH];
|
|
||||||
folder.GetPathAndName(file);
|
|
||||||
DeleteFile(file);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
bool SceneSync::SaveResMgr()
|
|
||||||
{
|
|
||||||
// Get the output directory for the current file
|
|
||||||
char path[MAX_PATH];
|
|
||||||
if (!GetOutputDir(path))
|
|
||||||
return false;
|
|
||||||
|
|
||||||
IWriteNodeMap(path);
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool SceneSync::GetOutputDir(char *buf)
|
|
||||||
{
|
|
||||||
const char *path = plMaxConfig::GetClientPath();
|
|
||||||
if (!path)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
const char *file = GetCOREInterface()->GetCurFileName();
|
|
||||||
if (!file || *file == '\0')
|
|
||||||
return false;
|
|
||||||
|
|
||||||
char filecpy[_MAX_FNAME];
|
|
||||||
_splitpath(file, nil, nil, filecpy, nil);
|
|
||||||
|
|
||||||
strcpy(buf, path);
|
|
||||||
strcat(buf, "SceneViewer\\");
|
|
||||||
|
|
||||||
// Make sure the SceneViewer directory is created (CreateDirectory sucks)
|
|
||||||
// CreateDirectory(buf, nil);
|
|
||||||
|
|
||||||
strcat(buf, filecpy);
|
|
||||||
strcat(buf, "\\");
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool SceneSync::IStartWatching(bool forceWatch)
|
|
||||||
{
|
|
||||||
IStopWatching();
|
|
||||||
|
|
||||||
// Ref all the nodes in the scene if:
|
|
||||||
// a) we are being forced to watch (starting SceneViewer)
|
|
||||||
// b) there is previously saved data for this scene (we need to keep up to date)
|
|
||||||
if (forceWatch || CanLoadOldResMgr())
|
|
||||||
{
|
|
||||||
fSceneWatcher = new SceneWatcher;
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool SceneSync::IStopWatching()
|
|
||||||
{
|
|
||||||
if (!fSceneWatcher)
|
|
||||||
return true;
|
|
||||||
|
|
||||||
delete fSceneWatcher;
|
|
||||||
fSceneWatcher = nil;
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
static const char *kKeysFile = "NodeMap.dat";
|
|
||||||
|
|
||||||
bool SceneSync::CanLoadOldResMgr()
|
|
||||||
{
|
|
||||||
char path[MAX_PATH];
|
|
||||||
if (!GetOutputDir(path))
|
|
||||||
return false;
|
|
||||||
strcat(path, kKeysFile);
|
|
||||||
|
|
||||||
hsUNIXStream s;
|
|
||||||
if (s.Open(path))
|
|
||||||
{
|
|
||||||
s.Close();
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void IGetNodes(std::vector<plMaxNode*>& nodes, plMaxNode *curNode=nil)
|
|
||||||
{
|
|
||||||
if (!curNode)
|
|
||||||
curNode = (plMaxNode*)GetCOREInterface()->GetRootNode();
|
|
||||||
else
|
|
||||||
nodes.push_back(curNode);
|
|
||||||
|
|
||||||
for (int i = 0; i < curNode->NumberOfChildren(); i++)
|
|
||||||
{
|
|
||||||
plMaxNode *childNode = (plMaxNode*)curNode->GetChildNode(i);
|
|
||||||
if (childNode)
|
|
||||||
IGetNodes(nodes, childNode);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
|
||||||
// The NodeMap is a mapping from unique node id's to Uoid's.
|
|
||||||
// It is used to figure out the plKey associated with a particular node, which
|
|
||||||
// will be needed if the node's data needs to be deleted out of the Plasma scene.
|
|
||||||
//
|
|
||||||
bool SceneSync::IWriteNodeMap(const char *dir)
|
|
||||||
{
|
|
||||||
char path[MAX_PATH];
|
|
||||||
strcpy(path, dir);
|
|
||||||
strcat(path, kKeysFile);
|
|
||||||
|
|
||||||
hsUNIXStream s;
|
|
||||||
if (!s.Open(path, "wb"))
|
|
||||||
return false;
|
|
||||||
|
|
||||||
int numWritten = 0;
|
|
||||||
s.WriteSwap32(numWritten);
|
|
||||||
|
|
||||||
std::vector<plMaxNode*> nodes;
|
|
||||||
IGetNodes(nodes);
|
|
||||||
|
|
||||||
int numNodes = nodes.size();
|
|
||||||
for (int i = 0; i < numNodes; i++)
|
|
||||||
{
|
|
||||||
plMaxNode *node = nodes[i];
|
|
||||||
|
|
||||||
if (node->GetKey())
|
|
||||||
{
|
|
||||||
s.WriteSwap32(node->GetHandle());
|
|
||||||
node->GetKey()->GetUoid().Write(&s);
|
|
||||||
|
|
||||||
numWritten++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
s.Rewind();
|
|
||||||
s.WriteSwap32(numWritten);
|
|
||||||
|
|
||||||
s.Close();
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
#include "../MaxMain/plMaxNodeData.h"
|
|
||||||
|
|
||||||
bool SceneSync::IReadNodeMap(const char *dir)
|
|
||||||
{
|
|
||||||
char path[MAX_PATH];
|
|
||||||
strcpy(path, dir);
|
|
||||||
strcat(path, kKeysFile);
|
|
||||||
|
|
||||||
hsUNIXStream s;
|
|
||||||
if (!s.Open(path, "rb"))
|
|
||||||
return false;
|
|
||||||
|
|
||||||
int numWritten = s.ReadSwap32();
|
|
||||||
|
|
||||||
for (int i = 0; i < numWritten; i++)
|
|
||||||
{
|
|
||||||
// Read in the node handle and get the actual node
|
|
||||||
ULONG handle = s.ReadSwap32();
|
|
||||||
plMaxNode *node = (plMaxNode*)GetCOREInterface()->GetINodeByHandle(handle);
|
|
||||||
|
|
||||||
// Read in the Uoid and get the key
|
|
||||||
plUoid uoid;
|
|
||||||
uoid.Read(&s);
|
|
||||||
plKey key = hsgResMgr::ResMgr()->FindKey(uoid);
|
|
||||||
|
|
||||||
// A node with that handle wasn't found, it must have been deleted.
|
|
||||||
// Delete it from the Plasma scene.
|
|
||||||
if (!node)
|
|
||||||
{
|
|
||||||
hsAssert( false, "YOU NEED TO FIX ME" );
|
|
||||||
// hsgResMgr::ResMgr()->RemoveObject(key);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// Save the node's key in the node data
|
|
||||||
plMaxNodeData *dat = node->GetMaxNodeData();
|
|
||||||
// Allocate the node data if it doesn't have any
|
|
||||||
if (!dat)
|
|
||||||
{
|
|
||||||
plMaxNodeData data;
|
|
||||||
node->SetMaxNodeData(&data);
|
|
||||||
dat = node->GetMaxNodeData();
|
|
||||||
}
|
|
||||||
dat->SetKey(key);
|
|
||||||
dat->SetSceneObject(plSceneObject::ConvertNoRef(key->GetObjectPtr()));
|
|
||||||
node->CanConvert();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
s.Close();
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
#include "plKeyRefSort.h"
|
|
||||||
|
|
||||||
bool SceneSync::Update()
|
|
||||||
{
|
|
||||||
// If there are no dirty nodes, and nothing was deleted, return now
|
|
||||||
if (!fSceneWatcher || (!fSceneWatcher->AnyDirty() && !fSceneWatcher->AnyDeleted()))
|
|
||||||
return false;
|
|
||||||
|
|
||||||
std::vector<plUoid> delUoids;
|
|
||||||
|
|
||||||
// If any nodes were deleted, remove them from the ResManager
|
|
||||||
if (fSceneWatcher->AnyDeleted())
|
|
||||||
{
|
|
||||||
SceneWatcher::KeyList& deleted = fSceneWatcher->GetDeleted();
|
|
||||||
|
|
||||||
for (int i = 0; i < deleted.size(); i++)
|
|
||||||
{
|
|
||||||
delUoids.push_back(deleted[i]->GetUoid());
|
|
||||||
hsAssert( false, "YOU NEED TO FIX ME" );
|
|
||||||
// hsgResMgr::ResMgr()->RemoveObject(deleted[i]);
|
|
||||||
}
|
|
||||||
|
|
||||||
deleted.clear();
|
|
||||||
}
|
|
||||||
|
|
||||||
hsAssert( false, "YOU NEED TO FIX ME" );
|
|
||||||
// hsgResMgr::ResMgr()->SaveNewKeys(true);
|
|
||||||
|
|
||||||
// If any nodes are dirty, reconvert them
|
|
||||||
if (fSceneWatcher->AnyDirty())
|
|
||||||
{
|
|
||||||
// Go through all the referenced nodes and put all the ones that need to be
|
|
||||||
// reconverted in a list
|
|
||||||
SceneWatcher::NodeSet dirtyNodes;
|
|
||||||
fSceneWatcher->GetDirty(dirtyNodes);
|
|
||||||
|
|
||||||
// Delete the SceneObjects for all the dirty nodes, and put them in a list
|
|
||||||
// that we can send to the converter
|
|
||||||
hsTArray<plMaxNode*> nodes;
|
|
||||||
for (SceneWatcher::NodeSet::iterator it = dirtyNodes.begin(); it != dirtyNodes.end(); it++)
|
|
||||||
{
|
|
||||||
// If the material is dirty, tell the material converter to release
|
|
||||||
// it's ref, so it will be recreated.
|
|
||||||
if ((*it)->GetDirty(plMaxNode::kMatDirty))
|
|
||||||
hsMaterialConverter::Instance().ClearDoneMaterials(*it);
|
|
||||||
|
|
||||||
plKey key = (*it)->GetKey();
|
|
||||||
if (key)
|
|
||||||
{
|
|
||||||
delUoids.push_back(key->GetUoid());
|
|
||||||
hsAssert( false, "YOU NEED TO FIX ME" );
|
|
||||||
// hsgResMgr::ResMgr()->RemoveObject(key);
|
|
||||||
}
|
|
||||||
|
|
||||||
nodes.Append(*it);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Convert
|
|
||||||
plExportErrorMsg msg;
|
|
||||||
plConvertSettings settings;
|
|
||||||
settings.fSceneViewer = true;
|
|
||||||
plConvert::Instance().Init(GetCOREInterface(), &msg, &settings);
|
|
||||||
bool ret = plConvert::Instance().Convert(nodes);
|
|
||||||
|
|
||||||
// REMOVE/FIX (COLIN)
|
|
||||||
hsMaterialConverter::Instance().FreeMaterialCache(nil);
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
|
||||||
// Sort the new keys
|
|
||||||
//
|
|
||||||
hsAssert( false, "YOU NEED TO FIX ME" );
|
|
||||||
// const plUpdatableResManager::KeyList& keys = hsgResMgr::ResMgr()->GetNewKeys();
|
|
||||||
std::vector<plKey> newKeys;// = keys;
|
|
||||||
plKeyRefSort::Sort(&newKeys);
|
|
||||||
|
|
||||||
#if 0
|
|
||||||
hsStatusMessage("New Keys (Sorted):\n");
|
|
||||||
for (int x = 0; x < newKeys.size(); x++)
|
|
||||||
{
|
|
||||||
hsStatusMessage(" ");
|
|
||||||
hsStatusMessage(newKeys[x]->GetName());
|
|
||||||
hsStatusMessage("\n");
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
//
|
|
||||||
// Write out the data to the client
|
|
||||||
//
|
|
||||||
hsNamedPipeStream outStream(hsNamedPipeStream::kThrowOnError);
|
|
||||||
try
|
|
||||||
{
|
|
||||||
if (outStream.Open(fPipeName, "w"))
|
|
||||||
{
|
|
||||||
// Signal the Client
|
|
||||||
fUpdateSignal->Signal();
|
|
||||||
|
|
||||||
if (outStream.WaitForClientConnect())
|
|
||||||
{
|
|
||||||
outStream.WriteByte(ClientUpdate::kUpdate);
|
|
||||||
|
|
||||||
int i;
|
|
||||||
|
|
||||||
// Write out the deleted Uoids
|
|
||||||
int numUoids = delUoids.size();
|
|
||||||
outStream.WriteSwap32(numUoids);
|
|
||||||
for (i = 0; i < numUoids; i++)
|
|
||||||
{
|
|
||||||
delUoids[i].Write(&outStream);
|
|
||||||
}
|
|
||||||
|
|
||||||
hsAssert( false, "NEED TO FIX ME!" );
|
|
||||||
// hsgResMgr::ResMgr()->WriteChangedSpans(&outStream);
|
|
||||||
|
|
||||||
// Write out the new keys (and objects)
|
|
||||||
int numKeys = newKeys.size();
|
|
||||||
outStream.WriteSwap32(numKeys);
|
|
||||||
for (i = 0; i < numKeys; i++)
|
|
||||||
{
|
|
||||||
plKey key = newKeys[i];
|
|
||||||
if (key && key->GetObjectPtr())
|
|
||||||
hsgResMgr::ResMgr()->WriteCreatable(&outStream, key->GetObjectPtr());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
outStream.Close();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
catch (...)
|
|
||||||
{
|
|
||||||
hsAssert(0, "Error writing to pipe");
|
|
||||||
outStream.Close();
|
|
||||||
|
|
||||||
EndClientSync(true);
|
|
||||||
}
|
|
||||||
|
|
||||||
hsAssert( false, "NEED TO FIX ME!" );
|
|
||||||
// hsgResMgr::ResMgr()->SaveNewKeys(false);
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
void SceneSync::INotify(void *param, NotifyInfo *info)
|
|
||||||
{
|
|
||||||
SceneSync &inst = SceneSync::Instance();
|
|
||||||
|
|
||||||
int code = info->intcode;
|
|
||||||
|
|
||||||
// Need to save the current state
|
|
||||||
if (code == NOTIFY_SYSTEM_PRE_RESET ||
|
|
||||||
code == NOTIFY_SYSTEM_PRE_NEW ||
|
|
||||||
code == NOTIFY_FILE_PRE_OPEN ||
|
|
||||||
code == NOTIFY_PRE_EXPORT)
|
|
||||||
{
|
|
||||||
inst.IStopWatching();
|
|
||||||
}
|
|
||||||
// Need to load the saved state
|
|
||||||
else if (code == NOTIFY_FILE_POST_OPEN ||
|
|
||||||
code == NOTIFY_POST_EXPORT ||
|
|
||||||
code == NOTIFY_EXPORT_FAILED)
|
|
||||||
{
|
|
||||||
inst.IStartWatching();
|
|
||||||
}
|
|
||||||
// Need to save the current state and cleanup
|
|
||||||
else if (code == NOTIFY_SYSTEM_SHUTDOWN)
|
|
||||||
{
|
|
||||||
inst.SaveResMgr();
|
|
||||||
inst.IStopWatching();
|
|
||||||
inst.IShutdown();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void CALLBACK SceneSync::ITimerProc(HWND hwnd, UINT uMsg, UINT_PTR idEvent, DWORD dwTime)
|
|
||||||
{
|
|
||||||
Instance().Update();
|
|
||||||
}
|
|
@ -1,118 +0,0 @@
|
|||||||
/*==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 SCENE_SYNC_H
|
|
||||||
#define SCENE_SYNC_H
|
|
||||||
|
|
||||||
#include "Max.h"
|
|
||||||
#include "notify.h"
|
|
||||||
|
|
||||||
#include <vector>
|
|
||||||
#include <set>
|
|
||||||
|
|
||||||
class plMaxNode;
|
|
||||||
class hsSemaphore;
|
|
||||||
class SceneWatcher;
|
|
||||||
class plSceneNode;
|
|
||||||
|
|
||||||
#include "pnKeyedObject/plUoid.h"
|
|
||||||
#include "pnKeyedObject/plKey.h"
|
|
||||||
|
|
||||||
class SceneSync
|
|
||||||
{
|
|
||||||
protected:
|
|
||||||
SceneWatcher *fSceneWatcher;
|
|
||||||
hsSemaphore *fUpdateSignal;
|
|
||||||
const char *fPipeName;
|
|
||||||
int fTimerID;
|
|
||||||
int fUpdateFreq;
|
|
||||||
|
|
||||||
SceneSync();
|
|
||||||
|
|
||||||
public:
|
|
||||||
static SceneSync& Instance();
|
|
||||||
|
|
||||||
// Get the path where the current Max file will be exported to (not including "dat")
|
|
||||||
bool GetOutputDir(char *buf);
|
|
||||||
|
|
||||||
bool IsClientRunning();
|
|
||||||
|
|
||||||
// Is there valid data on disk that we can load into the ResMgr or do we need to reconvert?
|
|
||||||
bool CanLoadOldResMgr();
|
|
||||||
|
|
||||||
// Create client data
|
|
||||||
bool CreateClientData();
|
|
||||||
|
|
||||||
void SetUpdateFreq(int freq); // In milliseconds
|
|
||||||
|
|
||||||
// Start updating the client
|
|
||||||
bool BeginClientSync(const char *semaphoreName, const char *pipeName);
|
|
||||||
// Stop updating the client. If abort is true, don't try saving, something went wrong
|
|
||||||
void EndClientSync(bool abort);
|
|
||||||
|
|
||||||
protected:
|
|
||||||
bool SaveResMgr();
|
|
||||||
|
|
||||||
void IShutdownClient();
|
|
||||||
|
|
||||||
// Reconvert any dirty nodes to sync the Plasma database and the Max one
|
|
||||||
bool Update();
|
|
||||||
|
|
||||||
void AddSceneNodes(std::set<plSceneNode*>& sceneNodes, std::vector<plUoid>& delUoids, std::vector<plKey>& newKeys);
|
|
||||||
|
|
||||||
bool IStartWatching(bool forceWatch=false);
|
|
||||||
bool IStopWatching();
|
|
||||||
|
|
||||||
// Called by open and close scene.
|
|
||||||
bool IReadNodeMap(const char *dir);
|
|
||||||
bool IWriteNodeMap(const char *dir);
|
|
||||||
|
|
||||||
void IShutdown();
|
|
||||||
|
|
||||||
void IDeletePath(const char *path);
|
|
||||||
void IClearDirtyRecur(plMaxNode *node);
|
|
||||||
|
|
||||||
static void INotify(void *param, NotifyInfo *info);
|
|
||||||
|
|
||||||
static void CALLBACK ITimerProc(HWND hwnd, UINT uMsg, UINT_PTR idEvent, DWORD dwTime);
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif //SCENE_SYNC_H
|
|
@ -1,296 +0,0 @@
|
|||||||
/*==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 "SceneViewer.h"
|
|
||||||
#include "SceneSync.h"
|
|
||||||
|
|
||||||
#include "MaxMain/plMaxCFGFile.h"
|
|
||||||
|
|
||||||
#include "MaxMain/resource.h"
|
|
||||||
|
|
||||||
// For ShellExecute
|
|
||||||
#include <shellapi.h>
|
|
||||||
|
|
||||||
static const char *kDebugClientExe = "plClient_dbg.exe";
|
|
||||||
static const char *kReleaseClientExe = "plClient.exe";
|
|
||||||
|
|
||||||
static const char *kSemaphoreName = "PlasmaSceneViewer";
|
|
||||||
static const char *kPipeName = "\\\\.\\pipe\\PlasmaSceneViewer";
|
|
||||||
|
|
||||||
SceneViewer::SceneViewer() : fhDlg(NULL)
|
|
||||||
{
|
|
||||||
// Get the plugin CFG dir
|
|
||||||
const char *plugFile = plMaxConfig::GetPluginIni();
|
|
||||||
|
|
||||||
fUpdate = (GetPrivateProfileInt("SceneViewer", "Update", 1, plugFile) != 0);
|
|
||||||
fUpdateFreq = GetPrivateProfileInt("SceneViewer", "UpdateFreq", 500, plugFile);
|
|
||||||
fLoadOld = (GetPrivateProfileInt("SceneViewer", "LoadOld", 0, plugFile) != 0);
|
|
||||||
fReleaseExe = (GetPrivateProfileInt("SceneViewer", "ReleaseExe", 1, plugFile) != 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
SceneViewer::~SceneViewer()
|
|
||||||
{
|
|
||||||
// Make sure the client is shut down
|
|
||||||
ISetRunning(false);
|
|
||||||
|
|
||||||
// Get the plugin CFG dir
|
|
||||||
const char *plugFile = plMaxConfig::GetPluginIni();
|
|
||||||
|
|
||||||
char buf[20];
|
|
||||||
WritePrivateProfileString("SceneViewer", "Update", fUpdate ? "1" : "0", plugFile);
|
|
||||||
WritePrivateProfileString("SceneViewer", "UpdateFreq", itoa(fUpdateFreq, buf, 10), plugFile);
|
|
||||||
WritePrivateProfileString("SceneViewer", "LoadOld", fLoadOld ? "1" : "0", plugFile);
|
|
||||||
WritePrivateProfileString("SceneViewer", "ReleaseExe", fReleaseExe ? "1" : "0", plugFile);
|
|
||||||
}
|
|
||||||
|
|
||||||
SceneViewer &SceneViewer::Instance()
|
|
||||||
{
|
|
||||||
static SceneViewer theInstance;
|
|
||||||
return theInstance;
|
|
||||||
}
|
|
||||||
|
|
||||||
void SceneViewer::Show()
|
|
||||||
{
|
|
||||||
// If the dialog is already created, make sure it is visible
|
|
||||||
if (fhDlg)
|
|
||||||
{
|
|
||||||
if (IsIconic(fhDlg))
|
|
||||||
ShowWindow(fhDlg, SW_RESTORE);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
fhDlg = CreateDialog(hInstance, MAKEINTRESOURCE(IDD_SCENEVIEWER), GetCOREInterface()->GetMAXHWnd(), ForwardDlgProc);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Toggles the client and SceneSync
|
|
||||||
bool SceneViewer::IToggleRunning()
|
|
||||||
{
|
|
||||||
fRunning = !fRunning;
|
|
||||||
return ISetRunning(fRunning);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Starts/Stops the client and SceneSync
|
|
||||||
bool SceneViewer::ISetRunning(bool running)
|
|
||||||
{
|
|
||||||
if (running)
|
|
||||||
{
|
|
||||||
// The client actually is running, hmmm
|
|
||||||
if (SceneSync::Instance().IsClientRunning())
|
|
||||||
return true;
|
|
||||||
|
|
||||||
// If we're not loading old data, or we are but it's not there, try to create some.
|
|
||||||
if (!fLoadOld || !SceneSync::Instance().CanLoadOldResMgr())
|
|
||||||
{
|
|
||||||
// If creation fails, fail
|
|
||||||
if (!SceneSync::Instance().CreateClientData())
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
char path[MAX_PATH];
|
|
||||||
SceneSync::Instance().GetOutputDir(path);
|
|
||||||
strcat(path, "dat\\");
|
|
||||||
|
|
||||||
// Start the client
|
|
||||||
char *options = new char[strlen(path)+2+strlen(kSemaphoreName)+strlen(kPipeName)+6];
|
|
||||||
sprintf(options, "-s %s %s \"%s\"", kSemaphoreName, kPipeName, path);
|
|
||||||
|
|
||||||
int ret = (int)ShellExecute(NULL,
|
|
||||||
"open",
|
|
||||||
fReleaseExe ? kReleaseClientExe : kDebugClientExe,
|
|
||||||
options,
|
|
||||||
plMaxConfig::GetClientPath(),
|
|
||||||
SW_SHOWNORMAL);
|
|
||||||
delete [] options;
|
|
||||||
|
|
||||||
// Client start failed
|
|
||||||
if (ret < 32)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
// Start client sync
|
|
||||||
SceneSync::Instance().SetUpdateFreq(fUpdateFreq);
|
|
||||||
SceneSync::Instance().BeginClientSync(kSemaphoreName, kPipeName);
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if (SceneSync::Instance().IsClientRunning())
|
|
||||||
SceneSync::Instance().EndClientSync(false);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
BOOL SceneViewer::ForwardDlgProc(HWND hDlg, UINT msg, WPARAM wParam, LPARAM lParam)
|
|
||||||
{
|
|
||||||
return Instance().DlgProc(hDlg, msg, wParam, lParam);
|
|
||||||
}
|
|
||||||
|
|
||||||
BOOL SceneViewer::DlgProc(HWND hDlg, UINT msg, WPARAM wParam, LPARAM lParam)
|
|
||||||
{
|
|
||||||
switch (msg)
|
|
||||||
{
|
|
||||||
case WM_INITDIALOG:
|
|
||||||
{
|
|
||||||
fhDlg = hDlg;
|
|
||||||
|
|
||||||
// Set the exe to use
|
|
||||||
HWND hExeCombo = GetDlgItem(hDlg, IDC_EXE);
|
|
||||||
ComboBox_AddString(hExeCombo, "Release");
|
|
||||||
ComboBox_AddString(hExeCombo, "Debug");
|
|
||||||
ComboBox_SetCurSel(hExeCombo, fReleaseExe ? 0 : 1);
|
|
||||||
|
|
||||||
// Set the client path
|
|
||||||
const char *path = plMaxConfig::GetClientPath(false, true);
|
|
||||||
ICustEdit *edit = GetICustEdit(GetDlgItem(hDlg, IDC_CLIENT_PATH));
|
|
||||||
edit->SetText((char*)path);
|
|
||||||
|
|
||||||
// Set the "Load old data" checkbox
|
|
||||||
HWND hLoadOld = GetDlgItem(hDlg, IDC_REUSE_DATA);
|
|
||||||
Button_SetCheck(hLoadOld, fLoadOld ? BST_CHECKED : BST_UNCHECKED);
|
|
||||||
Button_Enable(hLoadOld, SceneSync::Instance().CanLoadOldResMgr());
|
|
||||||
|
|
||||||
// Set the update controls
|
|
||||||
float val = float(fUpdateFreq) / 1000.f;
|
|
||||||
ISpinnerControl *spin = SetupFloatSpinner(hDlg, IDC_SPINNER, IDC_EDIT, 0.1, 1.f, val);
|
|
||||||
spin->Enable(fUpdate);
|
|
||||||
CheckDlgButton(hDlg, IDC_UPDATE, fUpdate ? BST_CHECKED : BST_UNCHECKED);
|
|
||||||
|
|
||||||
IEnableSetupControls(!SceneSync::Instance().IsClientRunning());
|
|
||||||
}
|
|
||||||
return TRUE;
|
|
||||||
|
|
||||||
case WM_COMMAND:
|
|
||||||
// Start/Stop SceneViewer
|
|
||||||
if (HIWORD(wParam) == BN_CLICKED && LOWORD(wParam) == IDC_START)
|
|
||||||
{
|
|
||||||
IToggleRunning();
|
|
||||||
IEnableSetupControls(!SceneSync::Instance().IsClientRunning());
|
|
||||||
return TRUE;
|
|
||||||
}
|
|
||||||
// Close dialog
|
|
||||||
else if (HIWORD(wParam) == BN_CLICKED && LOWORD(wParam) == IDCANCEL)
|
|
||||||
{
|
|
||||||
DestroyWindow(hDlg);
|
|
||||||
fhDlg = NULL;
|
|
||||||
return TRUE;
|
|
||||||
}
|
|
||||||
// Browse for directory
|
|
||||||
else if (HIWORD(wParam) == BN_CLICKED && LOWORD(wParam) == IDC_DIR)
|
|
||||||
{
|
|
||||||
const char *path = plMaxConfig::GetClientPath(true);
|
|
||||||
if (path)
|
|
||||||
{
|
|
||||||
ICustEdit *edit = GetICustEdit(GetDlgItem(hDlg, IDC_CLIENT_PATH));
|
|
||||||
edit->SetText((char*)path);
|
|
||||||
}
|
|
||||||
|
|
||||||
return TRUE;
|
|
||||||
}
|
|
||||||
// "Load old data" selection changed
|
|
||||||
else if (HIWORD(wParam) == BN_CLICKED && LOWORD(wParam) == IDC_REUSE_DATA)
|
|
||||||
{
|
|
||||||
fLoadOld = (Button_GetCheck((HWND)lParam) == BST_CHECKED);
|
|
||||||
return TRUE;
|
|
||||||
}
|
|
||||||
// Release/Debug exe selection changed
|
|
||||||
else if (HIWORD(wParam) == CBN_SELCHANGE && LOWORD(wParam) == IDC_EXE)
|
|
||||||
{
|
|
||||||
int sel = ComboBox_GetCurSel((HWND)lParam);
|
|
||||||
fReleaseExe = (sel == 0);
|
|
||||||
return TRUE;
|
|
||||||
}
|
|
||||||
else if (HIWORD(wParam) == BN_CLICKED && LOWORD(wParam) == IDC_UPDATE)
|
|
||||||
{
|
|
||||||
fUpdate = (SendMessage((HWND)lParam, BM_GETCHECK, 0, 0) == BST_CHECKED);
|
|
||||||
|
|
||||||
ISpinnerControl *spin = GetISpinner(GetDlgItem(hDlg, IDC_SPINNER));
|
|
||||||
spin->Enable(fUpdate);
|
|
||||||
ReleaseISpinner(spin);
|
|
||||||
|
|
||||||
// If update was turned on, send out an update message so any dirty objects
|
|
||||||
// will be reconverted right away
|
|
||||||
if (fUpdate)
|
|
||||||
SceneSync::Instance().SetUpdateFreq(fUpdateFreq);
|
|
||||||
|
|
||||||
return TRUE;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
// Update frequency changed
|
|
||||||
case CC_SPINNER_CHANGE:
|
|
||||||
if (LOWORD(wParam) == IDC_SPINNER)
|
|
||||||
{
|
|
||||||
ISpinnerControl *spin = (ISpinnerControl*)lParam;
|
|
||||||
float val = spin->GetFVal();
|
|
||||||
fUpdateFreq = int(val*1000.f);
|
|
||||||
SceneSync::Instance().SetUpdateFreq(fUpdateFreq);
|
|
||||||
}
|
|
||||||
return TRUE;
|
|
||||||
|
|
||||||
// Type in directory
|
|
||||||
case WM_CUSTEDIT_ENTER:
|
|
||||||
if (wParam == IDC_CLIENT_PATH)
|
|
||||||
{
|
|
||||||
ICustEdit *edit = GetICustEdit((HWND)lParam);
|
|
||||||
|
|
||||||
char path[MAX_PATH];
|
|
||||||
edit->GetText(path, sizeof(path));
|
|
||||||
plMaxConfig::SetClientPath(path);
|
|
||||||
}
|
|
||||||
return TRUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
void SceneViewer::IEnableSetupControls(bool enable)
|
|
||||||
{
|
|
||||||
ICustEdit *edit = GetICustEdit(GetDlgItem(fhDlg, IDC_CLIENT_PATH));
|
|
||||||
edit->Enable(enable);
|
|
||||||
|
|
||||||
EnableWindow(GetDlgItem(fhDlg, IDC_DIR), enable);
|
|
||||||
EnableWindow(GetDlgItem(fhDlg, IDC_EXE), enable);
|
|
||||||
EnableWindow(GetDlgItem(fhDlg, IDC_REUSE_DATA), enable);
|
|
||||||
|
|
||||||
SetWindowText(GetDlgItem(fhDlg, IDC_START), enable ? "Start" : "Stop");
|
|
||||||
}
|
|
@ -1,77 +0,0 @@
|
|||||||
/*==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 SceneViewer_h_inc
|
|
||||||
#define SceneViewer_h_inc
|
|
||||||
|
|
||||||
#include "HeadSpin.h"
|
|
||||||
|
|
||||||
// The dialog for setting up and starting the SceneViewer. Controls starting the client
|
|
||||||
// and SceneSync; SceneSync controls the updates though.
|
|
||||||
class SceneViewer
|
|
||||||
{
|
|
||||||
protected:
|
|
||||||
bool fUpdate;
|
|
||||||
int fUpdateFreq; // Update rate (ms), -1 for no update
|
|
||||||
bool fLoadOld; // Load old data if possible
|
|
||||||
bool fReleaseExe; // True for release exe, false for debug
|
|
||||||
bool fRunning; // Do we think the client is currently running (not sure since the
|
|
||||||
// client can terminate without us knowing).
|
|
||||||
HWND fhDlg; // Handle to the setup dialog
|
|
||||||
|
|
||||||
SceneViewer();
|
|
||||||
|
|
||||||
static BOOL CALLBACK ForwardDlgProc(HWND hDlg, UINT msg, WPARAM wParam, LPARAM lParam);
|
|
||||||
BOOL DlgProc(HWND hDlg, UINT msg, WPARAM wParam, LPARAM lParam);
|
|
||||||
|
|
||||||
void IEnableSetupControls(bool enable);
|
|
||||||
|
|
||||||
bool IToggleRunning();
|
|
||||||
bool ISetRunning(bool running);
|
|
||||||
|
|
||||||
public:
|
|
||||||
~SceneViewer();
|
|
||||||
static SceneViewer &Instance();
|
|
||||||
|
|
||||||
void Show();
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif // SceneViewer_h_inc
|
|
@ -1,368 +0,0 @@
|
|||||||
/*==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 "SceneWatcher.h"
|
|
||||||
|
|
||||||
#include "MaxMain/plMaxNode.h"
|
|
||||||
#include "MaxComponent/plComponent.h"
|
|
||||||
#include "MaxMain/plPlasmaRefMsgs.h"
|
|
||||||
|
|
||||||
#include "pnKeyedObject/plKey.h"
|
|
||||||
|
|
||||||
SceneWatcher::SceneWatcher() : fDirty(false)
|
|
||||||
{
|
|
||||||
RegisterNotification(INotify, this, NOTIFY_NODE_CREATED);
|
|
||||||
IAddNodeRecur((plMaxNode*)GetCOREInterface()->GetRootNode());
|
|
||||||
}
|
|
||||||
|
|
||||||
SceneWatcher::~SceneWatcher()
|
|
||||||
{
|
|
||||||
DeleteAllRefsFromMe();
|
|
||||||
UnRegisterNotification(INotify, this, NOTIFY_NODE_CREATED);
|
|
||||||
}
|
|
||||||
|
|
||||||
int SceneWatcher::NumRefs()
|
|
||||||
{
|
|
||||||
return fNodes.size();
|
|
||||||
}
|
|
||||||
|
|
||||||
RefTargetHandle SceneWatcher::GetReference(int i)
|
|
||||||
{
|
|
||||||
if (i < fNodes.size())
|
|
||||||
return fNodes[i];
|
|
||||||
|
|
||||||
hsAssert(0, "Index out of range");
|
|
||||||
return nil;
|
|
||||||
}
|
|
||||||
|
|
||||||
void SceneWatcher::SetReference(int i, RefTargetHandle rtarg)
|
|
||||||
{
|
|
||||||
if (i < fNodes.size())
|
|
||||||
fNodes[i] = (plMaxNode*)rtarg;
|
|
||||||
else
|
|
||||||
hsAssert(0, "Index out of range");
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
|
||||||
// Something in the scene has changed.
|
|
||||||
//
|
|
||||||
RefResult SceneWatcher::NotifyRefChanged(Interval changeInt, RefTargetHandle hTarget,
|
|
||||||
PartID& partID, RefMessage message)
|
|
||||||
{
|
|
||||||
plMaxNode *node = (plMaxNode *)hTarget;
|
|
||||||
|
|
||||||
#ifdef HS_DEBUGGING
|
|
||||||
char *tmp = node->GetName();
|
|
||||||
#endif
|
|
||||||
|
|
||||||
if (message == REFMSG_CHANGE)
|
|
||||||
{
|
|
||||||
// If the message is from a component, and was not generated locally (ie.
|
|
||||||
// it came from a ref parameter), ignore it. There is no way to tell if
|
|
||||||
// one of these messages is an actual change to the component or just a
|
|
||||||
// change to the referenced object. We'll catch the real changes with
|
|
||||||
// REFMSG_USER_COMP_REF_CHANGED below.
|
|
||||||
if (node->IsComponent())
|
|
||||||
{
|
|
||||||
plComponentBase *comp = node->ConvertToComponent();
|
|
||||||
if (!comp->IsCurMsgLocal())
|
|
||||||
return REF_SUCCEED;
|
|
||||||
}
|
|
||||||
|
|
||||||
// If this is a static light, ignore it
|
|
||||||
Object *obj = node->GetObjectRef();
|
|
||||||
if (obj && obj->SuperClassID() == LIGHT_CLASS_ID && !node->GetRunTimeLight())
|
|
||||||
return REF_SUCCEED;
|
|
||||||
|
|
||||||
node->SetDirty(plMaxNode::kGeomDirty, true);
|
|
||||||
ISetDirty();
|
|
||||||
}
|
|
||||||
else if (message == REFMSG_TARGET_DELETED)
|
|
||||||
{
|
|
||||||
// If the deleted node was a component, dirty everyone it was attached to
|
|
||||||
if (node->IsComponent())
|
|
||||||
{
|
|
||||||
plComponentBase *comp = node->ConvertToComponent();
|
|
||||||
for (uint32_t i = 0; i < comp->NumTargets(); i++)
|
|
||||||
{
|
|
||||||
if (comp->GetTarget(i))
|
|
||||||
comp->GetTarget(i)->SetDirty(plMaxNode::kGeomDirty, true);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fDeleted.push_back(node->GetKey());
|
|
||||||
|
|
||||||
IRemoveRef(node);
|
|
||||||
ISetDirty();
|
|
||||||
}
|
|
||||||
else if (message == REFMSG_NODE_MATERIAL_CHANGED ||
|
|
||||||
message == REFMSG_USER_MAT)
|
|
||||||
{
|
|
||||||
if (!node->IsComponent())
|
|
||||||
{
|
|
||||||
node->SetDirty(plMaxNode::kMatDirty, true);
|
|
||||||
ISetDirty();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// A node was added to the components target list
|
|
||||||
else if (message == REFMSG_USER_TARGET_ADD)
|
|
||||||
{
|
|
||||||
plMaxNode *target = (plMaxNode*)partID;
|
|
||||||
target->SetDirty(plMaxNode::kGeomDirty, true);
|
|
||||||
ISetDirty();
|
|
||||||
}
|
|
||||||
// A node was deleted from the components target list
|
|
||||||
else if (message == REFMSG_USER_TARGET_DELETE)
|
|
||||||
{
|
|
||||||
plMaxNode *target = (plMaxNode*)partID;
|
|
||||||
target->SetDirty(plMaxNode::kGeomDirty, true);
|
|
||||||
ISetDirty();
|
|
||||||
}
|
|
||||||
// A ref maintained by a component PB changed (not just a propagated message
|
|
||||||
// from the ref)
|
|
||||||
else if (message == REFMSG_USER_COMP_REF_CHANGED)
|
|
||||||
{
|
|
||||||
node->SetDirty(plMaxNode::kGeomDirty, true);
|
|
||||||
ISetDirty();
|
|
||||||
}
|
|
||||||
|
|
||||||
return REF_SUCCEED;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool SceneWatcher::AnyDeleted()
|
|
||||||
{
|
|
||||||
return !fDeleted.empty();
|
|
||||||
}
|
|
||||||
|
|
||||||
SceneWatcher::KeyList& SceneWatcher::GetDeleted()
|
|
||||||
{
|
|
||||||
return fDeleted;
|
|
||||||
}
|
|
||||||
|
|
||||||
const SceneWatcher::NodeList& SceneWatcher::GetWatchNodes()
|
|
||||||
{
|
|
||||||
return fNodes;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool SceneWatcher::AnyDirty()
|
|
||||||
{
|
|
||||||
return fDirty;
|
|
||||||
}
|
|
||||||
|
|
||||||
void SceneWatcher::GetDirty(NodeSet& dirtyNodes)
|
|
||||||
{
|
|
||||||
int size = fNodes.size();
|
|
||||||
for (int i = 0; i < size; i++)
|
|
||||||
{
|
|
||||||
plMaxNode *node = fNodes[i];
|
|
||||||
|
|
||||||
#ifdef HS_DEBUGGING
|
|
||||||
const char *tmp = node ? node->GetName() : nil;
|
|
||||||
#endif
|
|
||||||
// If any dirty flags are set, add to dirty list
|
|
||||||
if (node && node->GetDirty(plMaxNode::kAllDirty))
|
|
||||||
IGetDependents(node, dirtyNodes);
|
|
||||||
}
|
|
||||||
|
|
||||||
fDirty = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
void SceneWatcher::IAddRef(plMaxNode *node)
|
|
||||||
{
|
|
||||||
// Ensure that we don't already ref this node
|
|
||||||
if (FindRef(node) != -1)
|
|
||||||
return;
|
|
||||||
|
|
||||||
// Make a ref
|
|
||||||
int size = fNodes.size();
|
|
||||||
fNodes.resize(size+1);
|
|
||||||
MakeRefByID(FOREVER, size, node);
|
|
||||||
}
|
|
||||||
|
|
||||||
void SceneWatcher::IRemoveRef(plMaxNode *node)
|
|
||||||
{
|
|
||||||
// Delete the reference if it's in our list
|
|
||||||
int i = FindRef(node);
|
|
||||||
|
|
||||||
if (i != -1)
|
|
||||||
{
|
|
||||||
// Clear the node data, in case it is undeleted later
|
|
||||||
// (when it will be invalid)
|
|
||||||
node->ClearData(nil, nil);
|
|
||||||
node->SetDirty(plMaxNode::kAllDirty, true);
|
|
||||||
|
|
||||||
// We can never really delete this reference because the user may "undo"
|
|
||||||
// and cause it to come back, which just sets the reference again.
|
|
||||||
fNodes[i] = nil;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void SceneWatcher::IAddNodeRecur(plMaxNode *node)
|
|
||||||
{
|
|
||||||
IAddRef(node);
|
|
||||||
|
|
||||||
// If a node is dirty, make sure to set the dirty flag (since nodes may have
|
|
||||||
// been dirtied in a previous run but not reconverted yet).
|
|
||||||
if (node->GetDirty(plMaxNode::kAllDirty))
|
|
||||||
fDirty = true;
|
|
||||||
|
|
||||||
for (int i = 0; i < node->NumberOfChildren(); ++i)
|
|
||||||
{
|
|
||||||
plMaxNode *childNode = (plMaxNode*)node->GetChildNode(i);
|
|
||||||
IAddNodeRecur(childNode);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void SceneWatcher::INotify(void *param, NotifyInfo *info)
|
|
||||||
{
|
|
||||||
SceneWatcher *inst = (SceneWatcher*)param;
|
|
||||||
|
|
||||||
int code = info->intcode;
|
|
||||||
|
|
||||||
// New node was added to the scene, add it to our refs
|
|
||||||
if (code == NOTIFY_NODE_CREATED)
|
|
||||||
{
|
|
||||||
plMaxNode *node = (plMaxNode*)info->callParam;
|
|
||||||
|
|
||||||
// Add a ref to the node and set it to dirty
|
|
||||||
inst->IAddRef(node);
|
|
||||||
node->SetDirty(plMaxNodeBase::kAllDirty, true);
|
|
||||||
inst->ISetDirty();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void SceneWatcher::ISetDirty()
|
|
||||||
{
|
|
||||||
fDirty = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
#include "../MaxComponent/plMiscComponents.h"
|
|
||||||
|
|
||||||
#include "../MaxExport/plExportErrorMsg.h"
|
|
||||||
#include "../MaxExport/plExportProgressBar.h"
|
|
||||||
#include "../MaxComponent/plResponderComponent.h" // Just need the CID
|
|
||||||
|
|
||||||
void SceneWatcher::IGetLogicDependents(plMaxNode *node, NodeSet& nodes)
|
|
||||||
{
|
|
||||||
int attached = node->NumAttachedComponents();
|
|
||||||
for (int i = 0; i < attached; i++)
|
|
||||||
{
|
|
||||||
plComponentBase *comp = node->GetAttachedComponent(i);
|
|
||||||
/*
|
|
||||||
if (comp->ClassID() == ACTIVATOR_CID)
|
|
||||||
{
|
|
||||||
plMaxNodeBase *activatorNode = comp->GetINode();
|
|
||||||
int numResponders = activatorNode->NumAttachedComponents(true);
|
|
||||||
for (int i = 0; i < numResponders; i++)
|
|
||||||
{
|
|
||||||
plComponentBase *responderComp = activatorNode->GetAttachedComponent(i, true);
|
|
||||||
if (responderComp->ClassID() == RESPONDER_CID)
|
|
||||||
{
|
|
||||||
for (int j = 0; j < responderComp->NumTargets(); j++)
|
|
||||||
{
|
|
||||||
plMaxNode *targ = (plMaxNode*)responderComp->GetTarget(j);
|
|
||||||
if (targ && nodes.find(targ) == nodes.end())
|
|
||||||
{
|
|
||||||
nodes.insert(targ);
|
|
||||||
IGetLogicDependents(targ, nodes);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
*/
|
|
||||||
if (comp->ClassID() == RESPONDER_CID)
|
|
||||||
{
|
|
||||||
int activatorCnt = ResponderGetActivatorCount(comp);
|
|
||||||
for (int i = 0; i < activatorCnt; i++)
|
|
||||||
{
|
|
||||||
plComponentBase *activator = ResponderGetActivator(comp, i);
|
|
||||||
|
|
||||||
for (int j = 0; j < activator->NumTargets(); j++)
|
|
||||||
{
|
|
||||||
plMaxNode *targ = (plMaxNode*)activator->GetTarget(j);
|
|
||||||
if (targ && nodes.find(targ) == nodes.end())
|
|
||||||
{
|
|
||||||
nodes.insert(targ);
|
|
||||||
IGetLogicDependents(targ, nodes);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void SceneWatcher::IGetDependents(plMaxNode *node, NodeSet& nodes)
|
|
||||||
{
|
|
||||||
NodeSet dependents;
|
|
||||||
|
|
||||||
if (node->IsComponent())
|
|
||||||
{
|
|
||||||
plComponentBase *comp = node->ConvertToComponent();
|
|
||||||
|
|
||||||
if (comp->ClassID() == ROOM_CID || comp->ClassID() == PAGEINFO_CID)
|
|
||||||
return;
|
|
||||||
|
|
||||||
for (int i = 0; i < comp->NumTargets(); i++)
|
|
||||||
{
|
|
||||||
plMaxNode *targ = (plMaxNode*)comp->GetTarget(i);
|
|
||||||
if (targ)
|
|
||||||
{
|
|
||||||
dependents.insert(targ);
|
|
||||||
IGetLogicDependents(targ, dependents);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
dependents.insert(node);
|
|
||||||
|
|
||||||
IGetLogicDependents(node, dependents);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Bug in VC++?
|
|
||||||
// nodes.insert(dependents.begin(), dependents.end());
|
|
||||||
for (NodeSet::iterator i = dependents.begin(); i != dependents.end(); i++)
|
|
||||||
nodes.insert(*i);
|
|
||||||
}
|
|
@ -1,109 +0,0 @@
|
|||||||
/*==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 SCENE_WATCHER_H
|
|
||||||
#define SCENE_WATCHER_H
|
|
||||||
|
|
||||||
#include "Max.h"
|
|
||||||
#include "notify.h"
|
|
||||||
|
|
||||||
#include <vector>
|
|
||||||
#include <set>
|
|
||||||
|
|
||||||
#include "pnKeyedObject/plKey.h"
|
|
||||||
|
|
||||||
class plMaxNode;
|
|
||||||
|
|
||||||
class SceneWatcher : public ReferenceMaker
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
typedef std::vector<plMaxNode*> NodeList;
|
|
||||||
typedef std::set<plMaxNode*> NodeSet;
|
|
||||||
typedef std::vector<plKey> KeyList;
|
|
||||||
|
|
||||||
protected:
|
|
||||||
NodeList fNodes;
|
|
||||||
KeyList fDeleted;
|
|
||||||
|
|
||||||
bool fDirty;
|
|
||||||
|
|
||||||
public:
|
|
||||||
SceneWatcher();
|
|
||||||
~SceneWatcher();
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////
|
|
||||||
// ReferenceMaker functions
|
|
||||||
//
|
|
||||||
RefResult NotifyRefChanged(Interval changeInt, RefTargetHandle hTarget,
|
|
||||||
PartID& partID, RefMessage message);
|
|
||||||
|
|
||||||
int NumRefs();
|
|
||||||
RefTargetHandle GetReference(int i);
|
|
||||||
void SetReference(int i, RefTargetHandle rtarg);
|
|
||||||
|
|
||||||
BOOL IsRealDependency(ReferenceTarget *rtarg) { return FALSE; }
|
|
||||||
|
|
||||||
// Get all the nodes we're watching
|
|
||||||
const NodeList& GetWatchNodes();
|
|
||||||
|
|
||||||
// Get all the nodes that need to be reconverted
|
|
||||||
bool AnyDirty();
|
|
||||||
void GetDirty(NodeSet& dirtyNodes);
|
|
||||||
|
|
||||||
bool AnyDeleted();
|
|
||||||
KeyList& GetDeleted();
|
|
||||||
|
|
||||||
protected:
|
|
||||||
void IAddRef(plMaxNode *node);
|
|
||||||
void IRemoveRef(plMaxNode *node);
|
|
||||||
|
|
||||||
void IAddNodeRecur(plMaxNode *node);
|
|
||||||
|
|
||||||
// Helpers for GetDirtyNodes
|
|
||||||
void IGetDependents(plMaxNode *node, NodeSet& nodes);
|
|
||||||
void IGetLogicDependents(plMaxNode *node, NodeSet& nodes);
|
|
||||||
|
|
||||||
void ISetDirty();
|
|
||||||
|
|
||||||
static void INotify(void *param, NotifyInfo *info);
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif //SCENE_WATCHER_H
|
|
@ -1,103 +0,0 @@
|
|||||||
/*==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 "plKeyRefSort.h"
|
|
||||||
#include "pnKeyedObject/plKeyImp.h"
|
|
||||||
|
|
||||||
#include <algorithm>
|
|
||||||
|
|
||||||
std::vector<plKey>* plKeyRefSort::fKeys = nil;
|
|
||||||
std::vector<plKeyRefSort::KeyRefs> plKeyRefSort::fNumRefs;
|
|
||||||
|
|
||||||
int plKeyRefSort::CountRefsRecur(plKey key, std::vector<plKey>& traversedKeys)
|
|
||||||
{
|
|
||||||
int numRefs = 0;
|
|
||||||
|
|
||||||
if (std::find(traversedKeys.begin(), traversedKeys.end(), key) == traversedKeys.end())
|
|
||||||
{
|
|
||||||
traversedKeys.push_back(key);
|
|
||||||
|
|
||||||
plKeyImp* iKey = (plKeyImp*)key;
|
|
||||||
for (int i = 0; i < iKey->GetNumRefs(); i++)
|
|
||||||
{
|
|
||||||
plKey refKey = iKey->GetRef(i);
|
|
||||||
if (std::find(fKeys->begin(), fKeys->end(), refKey) != fKeys->end())
|
|
||||||
numRefs++;
|
|
||||||
|
|
||||||
numRefs += CountRefsRecur(refKey, traversedKeys);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return numRefs;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
class RefComp
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
bool operator() (plKey key1, plKey key2) const
|
|
||||||
{
|
|
||||||
std::vector<plKeyRefSort::KeyRefs>::iterator it1 = std::find(plKeyRefSort::fNumRefs.begin(), plKeyRefSort::fNumRefs.end(), key1);
|
|
||||||
std::vector<plKeyRefSort::KeyRefs>::iterator it2 = std::find(plKeyRefSort::fNumRefs.begin(), plKeyRefSort::fNumRefs.end(), key2);
|
|
||||||
|
|
||||||
return ((*it1).fNumRefs < (*it2).fNumRefs);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
void plKeyRefSort::Sort(std::vector<plKey>* keys)
|
|
||||||
{
|
|
||||||
fKeys = keys;
|
|
||||||
int numKeys = keys->size();
|
|
||||||
fNumRefs.resize(numKeys);
|
|
||||||
|
|
||||||
int i;
|
|
||||||
for (i = 0; i < numKeys; i++)
|
|
||||||
{
|
|
||||||
plKey curKey = (*keys)[i];
|
|
||||||
|
|
||||||
std::vector<plKey> traversedKeys;
|
|
||||||
int numRefs = CountRefsRecur(curKey, traversedKeys);
|
|
||||||
|
|
||||||
fNumRefs[i] = KeyRefs(curKey, numRefs);
|
|
||||||
}
|
|
||||||
|
|
||||||
std::sort(fKeys->begin(), fKeys->end(), RefComp());
|
|
||||||
}
|
|
@ -1,75 +0,0 @@
|
|||||||
/*==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 <vector>
|
|
||||||
#include "pnKeyedObject/plKey.h"
|
|
||||||
|
|
||||||
|
|
||||||
// A really crappy sort of a list of keys from the most referenced key to the least.
|
|
||||||
// This allows you to write out and read in the keys without having to worry about
|
|
||||||
// one referencing another that isn't loaded yet (ie, in the SceneViewer)
|
|
||||||
class plKeyRefSort
|
|
||||||
{
|
|
||||||
protected:
|
|
||||||
class KeyRefs
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
plKey fKey;
|
|
||||||
int fNumRefs;
|
|
||||||
KeyRefs() : fKey(nil), fNumRefs(-1) {}
|
|
||||||
KeyRefs(plKey key, int numRefs) : fKey(key), fNumRefs(numRefs) {}
|
|
||||||
bool operator== (const plKey key)
|
|
||||||
{
|
|
||||||
return (fKey == key);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
static std::vector<plKey>* fKeys;
|
|
||||||
static std::vector<KeyRefs> fNumRefs;
|
|
||||||
|
|
||||||
friend class RefComp;
|
|
||||||
|
|
||||||
static int CountRefsRecur(plKey key, std::vector<plKey>& traversedKeys);
|
|
||||||
|
|
||||||
public:
|
|
||||||
static void Sort(std::vector<plKey>* keys);
|
|
||||||
};
|
|
@ -1,293 +0,0 @@
|
|||||||
/*==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 "plMaxFileData.h"
|
|
||||||
#include "hsUtils.h"
|
|
||||||
|
|
||||||
#include "max.h"
|
|
||||||
#include "notify.h"
|
|
||||||
#include "tvnode.h"
|
|
||||||
|
|
||||||
#define PLASMA_FILE_DATA_CID Class_ID(0x255a700a, 0x285279dc)
|
|
||||||
|
|
||||||
// MyControl is derived from StdControl, but has no controller functionality. It simply has some
|
|
||||||
// membervariables and saves these by Load and Save.
|
|
||||||
// EditTrackParams and TrackParamsType are responsible for displaying a user interface (RightClick->Properties)
|
|
||||||
// on the controler. With these functions you can avoid it, having an interface !
|
|
||||||
// As you can see, most of these methods are stubbed. Only Load and Save are implemented
|
|
||||||
// and of course the methods, to access the membervariables.
|
|
||||||
class plMaxFileDataControl : public StdControl
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
SYSTEMTIME fCodeBuildTime;
|
|
||||||
char fBranch[128];
|
|
||||||
|
|
||||||
plMaxFileDataControl()
|
|
||||||
{
|
|
||||||
memset(&fCodeBuildTime, 0, sizeof(SYSTEMTIME));
|
|
||||||
memset(&fBranch, 0, sizeof(fBranch));
|
|
||||||
}
|
|
||||||
|
|
||||||
// Animatable
|
|
||||||
virtual void EditTrackParams(TimeValue t, ParamDimensionBase *dim,TCHAR *pname,HWND hParent, IObjParam *ip, DWORD flags){};
|
|
||||||
int TrackParamsType() { return TRACKPARAMS_WHOLE; }
|
|
||||||
virtual void DeleteThis() { delete this; }
|
|
||||||
|
|
||||||
// ReferenceMaker
|
|
||||||
virtual RefResult NotifyRefChanged(Interval changeInt, RefTargetHandle hTarget, PartID& partID,RefMessage message)
|
|
||||||
{return REF_DONTCARE;}
|
|
||||||
|
|
||||||
Class_ID ClassID() { return PLASMA_FILE_DATA_CID; }
|
|
||||||
SClass_ID SuperClassID() { return CTRL_FLOAT_CLASS_ID; }
|
|
||||||
void GetClassName(TSTR& s) {s = "blah";}
|
|
||||||
|
|
||||||
// Control methods
|
|
||||||
RefTargetHandle Clone(RemapDir& remap) { return new plMaxFileDataControl(); }
|
|
||||||
void Copy(Control *from) {}
|
|
||||||
virtual BOOL IsReplaceable() { return FALSE; }
|
|
||||||
|
|
||||||
// StdControl methods
|
|
||||||
void GetValueLocalTime(TimeValue t, void *val, Interval &valid, GetSetMethod method=CTRL_ABSOLUTE){}
|
|
||||||
void SetValueLocalTime(TimeValue t, void *val, int commit, GetSetMethod method) {}
|
|
||||||
void Extrapolate(Interval range,TimeValue t,void *val,Interval &valid,int type){}
|
|
||||||
void *CreateTempValue() {return NULL;}
|
|
||||||
void DeleteTempValue(void *val) {}
|
|
||||||
void ApplyValue(void *val, void *delta) {}
|
|
||||||
void MultiplyValue(void *val, float m) {}
|
|
||||||
|
|
||||||
// MyControl methods
|
|
||||||
IOResult Load(ILoad *iload);
|
|
||||||
IOResult Save(ISave *isave);
|
|
||||||
};
|
|
||||||
|
|
||||||
#define MAXFILE_DATA_CHUNK 1001
|
|
||||||
static const uint8_t kVersion = 1;
|
|
||||||
|
|
||||||
IOResult plMaxFileDataControl::Load(ILoad *iload)
|
|
||||||
{
|
|
||||||
ULONG nb;
|
|
||||||
IOResult res;
|
|
||||||
while (IO_OK==(res=iload->OpenChunk()))
|
|
||||||
{
|
|
||||||
if (iload->CurChunkID() == MAXFILE_DATA_CHUNK)
|
|
||||||
{
|
|
||||||
uint8_t version = 0;
|
|
||||||
res = iload->Read(&version, sizeof(uint8_t), &nb);
|
|
||||||
res = iload->Read(&fCodeBuildTime, sizeof(SYSTEMTIME), &nb);
|
|
||||||
|
|
||||||
int branchLen = 0;
|
|
||||||
iload->Read(&branchLen, sizeof(int), &nb);
|
|
||||||
iload->Read(&fBranch, branchLen, &nb);
|
|
||||||
}
|
|
||||||
|
|
||||||
iload->CloseChunk();
|
|
||||||
if (res != IO_OK)
|
|
||||||
return res;
|
|
||||||
}
|
|
||||||
|
|
||||||
return IO_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
IOResult plMaxFileDataControl::Save(ISave *isave)
|
|
||||||
{
|
|
||||||
ULONG nb;
|
|
||||||
isave->BeginChunk(MAXFILE_DATA_CHUNK);
|
|
||||||
|
|
||||||
isave->Write(&kVersion, sizeof(kVersion), &nb);
|
|
||||||
isave->Write(&fCodeBuildTime, sizeof(SYSTEMTIME), &nb);
|
|
||||||
|
|
||||||
int branchLen = strlen(fBranch)+1;
|
|
||||||
isave->Write(&branchLen, sizeof(int), &nb);
|
|
||||||
isave->Write(&fBranch, branchLen, &nb);
|
|
||||||
|
|
||||||
isave->EndChunk();
|
|
||||||
return IO_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
class MaxFileDataClassDesc : public ClassDesc
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
int IsPublic() { return FALSE; }
|
|
||||||
void* Create(BOOL loading) { return new plMaxFileDataControl; }
|
|
||||||
const TCHAR* ClassName() { return _T("MaxFileData"); }
|
|
||||||
SClass_ID SuperClassID() { return CTRL_FLOAT_CLASS_ID; }
|
|
||||||
Class_ID ClassID() { return PLASMA_FILE_DATA_CID; }
|
|
||||||
const TCHAR* Category() { return _T(""); }
|
|
||||||
};
|
|
||||||
MaxFileDataClassDesc gMaxFileDataClassDesc;
|
|
||||||
ClassDesc* GetMaxFileDataDesc() { return &gMaxFileDataClassDesc; }
|
|
||||||
|
|
||||||
// This functions searches for Trackviewnode and the Controller and creates one, if none is present.
|
|
||||||
plMaxFileDataControl *GetMaxFileData(bool& created)
|
|
||||||
{
|
|
||||||
plMaxFileDataControl *pCtrl = NULL;
|
|
||||||
ITrackViewNode *tvNode = NULL;
|
|
||||||
ITrackViewNode *tvRoot = GetCOREInterface()->GetTrackViewRootNode();
|
|
||||||
|
|
||||||
int i = tvRoot->FindItem(PLASMA_FILE_DATA_CID);
|
|
||||||
if (i < 0)
|
|
||||||
{
|
|
||||||
created = true;
|
|
||||||
|
|
||||||
tvNode = CreateITrackViewNode();
|
|
||||||
|
|
||||||
// This method adds the Node with the specific Title (e.g. "My Settings")
|
|
||||||
tvRoot->AddNode(tvNode, "Plasma Globals", PLASMA_FILE_DATA_CID);
|
|
||||||
pCtrl = (plMaxFileDataControl*)CreateInstance(CTRL_FLOAT_CLASS_ID, PLASMA_FILE_DATA_CID);
|
|
||||||
|
|
||||||
TSTR s;
|
|
||||||
pCtrl->GetClassName(s);
|
|
||||||
|
|
||||||
|
|
||||||
// This adds the controller
|
|
||||||
tvNode->AddController(pCtrl, s, PLASMA_FILE_DATA_CID);
|
|
||||||
tvNode->HideChildren(TRUE);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
created = false;
|
|
||||||
|
|
||||||
tvNode = tvRoot->GetNode(i);
|
|
||||||
pCtrl = (plMaxFileDataControl*)tvNode->GetController(PLASMA_FILE_DATA_CID);
|
|
||||||
}
|
|
||||||
|
|
||||||
return pCtrl;
|
|
||||||
}
|
|
||||||
|
|
||||||
static SYSTEMTIME gThisCodeBuildTime;
|
|
||||||
static char gThisBranch[128];
|
|
||||||
|
|
||||||
static void PrintTime(SYSTEMTIME& time, char* buf)
|
|
||||||
{
|
|
||||||
sprintf(buf, "%d/%d/%d %d:%02d %s", time.wMonth, time.wDay, time.wYear,
|
|
||||||
(time.wHour <= 12) ? time.wHour : time.wHour-12,
|
|
||||||
time.wMinute,
|
|
||||||
(time.wHour < 12 || time.wHour == 24) ? "AM" : "PM");
|
|
||||||
}
|
|
||||||
|
|
||||||
static void NotifyProc(void *param, NotifyInfo *info)
|
|
||||||
{
|
|
||||||
if (info->intcode == NOTIFY_FILE_POST_OPEN)
|
|
||||||
{
|
|
||||||
bool created;
|
|
||||||
plMaxFileDataControl* data = GetMaxFileData(created);
|
|
||||||
|
|
||||||
if (!created)
|
|
||||||
{
|
|
||||||
FILETIME fileTime, pluginTime;
|
|
||||||
SystemTimeToFileTime(&gThisCodeBuildTime, &pluginTime);
|
|
||||||
SystemTimeToFileTime(&data->fCodeBuildTime, &fileTime);
|
|
||||||
|
|
||||||
if (CompareFileTime(&fileTime, &pluginTime) > 0)
|
|
||||||
{
|
|
||||||
if (hsMessageBox_SuppressPrompts)
|
|
||||||
return;
|
|
||||||
|
|
||||||
char buf[1024];
|
|
||||||
|
|
||||||
strcpy(buf, "This file was last saved with plugins stamped:\n\n");
|
|
||||||
|
|
||||||
char timeBuf[128];
|
|
||||||
PrintTime(data->fCodeBuildTime, timeBuf);
|
|
||||||
strcat(buf, timeBuf);
|
|
||||||
strcat(buf, "\n");
|
|
||||||
strcat(buf, data->fBranch);
|
|
||||||
|
|
||||||
strcat(buf, "\n\nThese plugins are stamped:\n\n");
|
|
||||||
|
|
||||||
PrintTime(gThisCodeBuildTime, timeBuf);
|
|
||||||
strcat(buf, timeBuf);
|
|
||||||
strcat(buf, "\n");
|
|
||||||
strcat(buf, gThisBranch);
|
|
||||||
|
|
||||||
strcat(buf,
|
|
||||||
"\n\nNew features may have been added to the newer plugins,\n"
|
|
||||||
"so saving this file could cause data to be lost.");
|
|
||||||
|
|
||||||
MessageBox(GetCOREInterface()->GetMAXHWnd(), buf, "Plugin Warning", MB_OK | MB_ICONEXCLAMATION);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
strcpy(data->fBranch, gThisBranch);
|
|
||||||
memcpy(&data->fCodeBuildTime, &gThisCodeBuildTime, sizeof(SYSTEMTIME));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void IGetString(int resID, char *destBuffer, int size)
|
|
||||||
{
|
|
||||||
HRSRC rsrc = ::FindResource(hInstance, MAKEINTRESOURCE(resID), RT_RCDATA);
|
|
||||||
|
|
||||||
if (rsrc != NULL)
|
|
||||||
{
|
|
||||||
HGLOBAL handle = ::LoadResource(hInstance, rsrc);
|
|
||||||
|
|
||||||
if (handle != NULL)
|
|
||||||
{
|
|
||||||
char* str = (char*)::LockResource(handle);
|
|
||||||
strncpy(destBuffer, str, size);
|
|
||||||
UnlockResource(handle);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void InitMaxFileData()
|
|
||||||
{
|
|
||||||
memset(&gThisCodeBuildTime, 0, sizeof(SYSTEMTIME));
|
|
||||||
|
|
||||||
// Date
|
|
||||||
char buf[128];
|
|
||||||
IGetString(1000, buf, sizeof(buf) - 1);
|
|
||||||
sscanf(buf, "%hu/%hu/%hu", &gThisCodeBuildTime.wMonth, &gThisCodeBuildTime.wDay, &gThisCodeBuildTime.wYear);
|
|
||||||
|
|
||||||
// Time
|
|
||||||
IGetString(1001, buf, sizeof(buf) - 1);
|
|
||||||
sscanf(buf, "%hu:%hu", &gThisCodeBuildTime.wHour, &gThisCodeBuildTime.wMinute);
|
|
||||||
|
|
||||||
if (strstr(buf, "PM") != nil)
|
|
||||||
{
|
|
||||||
gThisCodeBuildTime.wHour += 12;
|
|
||||||
}
|
|
||||||
|
|
||||||
IGetString(1002, gThisBranch, sizeof(gThisBranch) - 1);
|
|
||||||
|
|
||||||
RegisterNotification(NotifyProc, 0, NOTIFY_FILE_POST_OPEN);
|
|
||||||
}
|
|
@ -1,44 +0,0 @@
|
|||||||
/*==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 InitMaxFileData();
|
|
||||||
ClassDesc* GetMaxFileDataDesc();
|
|
@ -1,67 +0,0 @@
|
|||||||
/*==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 "plPluginClient.h"
|
|
||||||
#include "plPluginApp.h"
|
|
||||||
#include "pnNetCommon/plNetApp.h"
|
|
||||||
|
|
||||||
plClient *plPluginApp::Startup(char *pCmdLine)
|
|
||||||
{
|
|
||||||
// Create the client
|
|
||||||
fClient = new plPluginClient;
|
|
||||||
|
|
||||||
// disable networking always
|
|
||||||
plNetClientApp::GetInstance()->SetFlagsBit(plNetClientApp::kDisabled);
|
|
||||||
// and set local triggers
|
|
||||||
plNetClientApp::GetInstance()->SetFlagsBit(plNetClientApp::kLocalTriggers);
|
|
||||||
|
|
||||||
return fClient;
|
|
||||||
}
|
|
||||||
|
|
||||||
void plPluginApp::Shutdown()
|
|
||||||
{
|
|
||||||
// Destroy the client
|
|
||||||
if (fClient)
|
|
||||||
{
|
|
||||||
fClient->Shutdown();
|
|
||||||
fClient = nil;
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,59 +0,0 @@
|
|||||||
/*==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 "plClient/plApp.h"
|
|
||||||
|
|
||||||
class plPluginClient;
|
|
||||||
|
|
||||||
//
|
|
||||||
// Plugin app class. Creates and destroys the client, leaves the resmanager
|
|
||||||
//
|
|
||||||
class plPluginApp : public plApp
|
|
||||||
{
|
|
||||||
protected:
|
|
||||||
plPluginClient *fClient;
|
|
||||||
|
|
||||||
public:
|
|
||||||
plPluginApp() : fClient(NULL) {}
|
|
||||||
|
|
||||||
virtual plClient *Startup(char *CmdLine);
|
|
||||||
virtual void Shutdown();
|
|
||||||
};
|
|
@ -1,307 +0,0 @@
|
|||||||
/*==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 "plPluginClient.h"
|
|
||||||
|
|
||||||
#include "plPipeline/hsG3DDeviceSelector.h"
|
|
||||||
|
|
||||||
#include "hsThread.h"
|
|
||||||
#include "hsSTLStream.h"
|
|
||||||
|
|
||||||
#include "pnKeyedObject/plUoid.h"
|
|
||||||
#include "plResMgr/plUpdatableResManager.h"
|
|
||||||
#include "plStatusLog/plStatusLog.h"
|
|
||||||
|
|
||||||
// Needed for IEnableProxies
|
|
||||||
#include "plPipeline.h"
|
|
||||||
#include "plDrawable/plDrawableSpans.h"
|
|
||||||
#include "pnMessage/plProxyDrawMsg.h"
|
|
||||||
#include "plgDispatch.h"
|
|
||||||
|
|
||||||
#define LOG_SCENEVIWER
|
|
||||||
|
|
||||||
static plUpdatableResManager *GetResMgr()
|
|
||||||
{
|
|
||||||
return (plUpdatableResManager*)hsgResMgr::ResMgr();
|
|
||||||
}
|
|
||||||
|
|
||||||
plUpdatableClient::plUpdatableClient() : fPipeName(nil), fUpdateSignal(nil), fDataPath(nil), fActive(true), fDirty(false)
|
|
||||||
{
|
|
||||||
#ifdef LOG_SCENEVIWER
|
|
||||||
fLog = plStatusLogMgr::GetInstance().CreateStatusLog(25, "SceneViewer",
|
|
||||||
plStatusLog::kDontWriteFile | plStatusLog::kFilledBackground | plStatusLog::kAlignToTop);
|
|
||||||
#endif // LOG_SCENEVIWER
|
|
||||||
}
|
|
||||||
|
|
||||||
plUpdatableClient::~plUpdatableClient()
|
|
||||||
{
|
|
||||||
if (fUpdateSignal)
|
|
||||||
{
|
|
||||||
delete fUpdateSignal;
|
|
||||||
fUpdateSignal = nil;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (fLog)
|
|
||||||
{
|
|
||||||
delete fLog;
|
|
||||||
fLog = nil;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void plUpdatableClient::InitUpdate(const char *semaphoreName, const char *pipeName, const char *dir)
|
|
||||||
{
|
|
||||||
fUpdateSignal = new hsSemaphore(0, semaphoreName);
|
|
||||||
fPipeName = pipeName;
|
|
||||||
fDataPath = dir;
|
|
||||||
}
|
|
||||||
|
|
||||||
hsG3DDeviceModeRecord plUpdatableClient::ILoadDevMode(const char* devModeFile)
|
|
||||||
{
|
|
||||||
// Get the usual devmode
|
|
||||||
hsG3DDeviceModeRecord dmr = plClient::ILoadDevMode(devModeFile);
|
|
||||||
|
|
||||||
// Override the mode with a windowed one
|
|
||||||
hsG3DDeviceMode *mode = (hsG3DDeviceMode*)dmr.GetMode();
|
|
||||||
mode->SetColorDepth(0);
|
|
||||||
|
|
||||||
return hsG3DDeviceModeRecord(*dmr.GetDevice(), *mode);
|
|
||||||
}
|
|
||||||
|
|
||||||
#include "../../../Plasma/Apps/plClient/plClientUpdateFormat.h"
|
|
||||||
#include "../pnKeyedObject/plKey.h"
|
|
||||||
|
|
||||||
void plUpdatableClient::IGetUpdate()
|
|
||||||
{
|
|
||||||
// If the semaphore is signaled an update is ready
|
|
||||||
if (fUpdateSignal && fUpdateSignal->Wait(0))
|
|
||||||
{
|
|
||||||
hsNamedPipeStream s;
|
|
||||||
s.Open(fPipeName, "r");
|
|
||||||
|
|
||||||
#ifdef LOG_SCENEVIWER
|
|
||||||
fLog->Clear();
|
|
||||||
static int numUpdates = 0;
|
|
||||||
numUpdates++;
|
|
||||||
fLog->AddLineF(plStatusLog::kBlue, "SceneViewer Update #%d", numUpdates);
|
|
||||||
#endif // LOG_SCENEVIWER
|
|
||||||
|
|
||||||
uint8_t type = s.ReadByte();
|
|
||||||
|
|
||||||
if (type == ClientUpdate::kShutdown)
|
|
||||||
{
|
|
||||||
#ifdef LOG_SCENEVIWER
|
|
||||||
fLog->AddLine("Client shutdown");
|
|
||||||
#endif // LOG_SCENEVIWER
|
|
||||||
|
|
||||||
PostMessage(GetWindowHandle(), WM_SYSCOMMAND, SC_CLOSE, 0);
|
|
||||||
}
|
|
||||||
else if (type == ClientUpdate::kUpdate)
|
|
||||||
{
|
|
||||||
fDirty = true;
|
|
||||||
|
|
||||||
IEnableProxies(false);
|
|
||||||
|
|
||||||
int i;
|
|
||||||
|
|
||||||
//
|
|
||||||
// Delete the deleted keys
|
|
||||||
//
|
|
||||||
int numDeleted = s.ReadSwap32();
|
|
||||||
std::vector<plKey*> delKeys;
|
|
||||||
delKeys.reserve(numDeleted);
|
|
||||||
|
|
||||||
for (i = 0; i < numDeleted; i++)
|
|
||||||
{
|
|
||||||
plUoid uoid;
|
|
||||||
uoid.Read(&s);
|
|
||||||
plKey *key = hsgResMgr::ResMgr()->FindKey(uoid);
|
|
||||||
hsAssert(key, "Key to delete not found");
|
|
||||||
if (key)
|
|
||||||
{
|
|
||||||
#ifdef LOG_SCENEVIWER
|
|
||||||
fLog->AddLineF("Remove: %s", key->GetName());
|
|
||||||
#endif // LOG_SCENEVIWER
|
|
||||||
|
|
||||||
GetResMgr()->RemoveObject(key, false);
|
|
||||||
delKeys.push_back(key);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
GetResMgr()->DelayLoad(true);
|
|
||||||
|
|
||||||
//
|
|
||||||
// Read in the changed spans
|
|
||||||
//
|
|
||||||
hsStatusMessage("ReadChangedSpans\n");
|
|
||||||
GetResMgr()->ReadChangedSpans(&s);
|
|
||||||
|
|
||||||
//
|
|
||||||
// Read in the new keys and objects
|
|
||||||
//
|
|
||||||
int numNew = s.ReadSwap32();
|
|
||||||
for (i = 0; i < numNew; i++)
|
|
||||||
{
|
|
||||||
plCreatable *cre = GetResMgr()->ReadCreatable(&s);
|
|
||||||
|
|
||||||
hsKeyedObject *ko = hsKeyedObject::ConvertNoRef(cre);
|
|
||||||
|
|
||||||
#ifdef LOG_SCENEVIWER
|
|
||||||
if (ko)
|
|
||||||
fLog->AddLineF("Read: %s", ko->GetKey()->GetName());
|
|
||||||
else
|
|
||||||
fLog->AddLine("Read: (null)");
|
|
||||||
#endif // LOG_SCENEVIWER
|
|
||||||
}
|
|
||||||
|
|
||||||
GetResMgr()->DelayLoad(false);
|
|
||||||
|
|
||||||
// Clear out any objects that were never reloaded (really deleted)
|
|
||||||
for (i = 0; i < delKeys.size(); i++)
|
|
||||||
{
|
|
||||||
plKey *key = delKeys[i];
|
|
||||||
if (!key->ObjectIsLoaded())
|
|
||||||
{
|
|
||||||
#ifdef LOG_SCENEVIWER
|
|
||||||
fLog->AddLineF("Key deleted: %s", key->GetName());
|
|
||||||
#endif // LOG_SCENEVIWER
|
|
||||||
|
|
||||||
GetResMgr()->RemoveObject(key);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
IEnableProxies(true);
|
|
||||||
}
|
|
||||||
|
|
||||||
s.Close();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
bool plUpdatableClient::Init()
|
|
||||||
{
|
|
||||||
if (plClient::Init())
|
|
||||||
{
|
|
||||||
GetResMgr()->ForceLoadDirectory(fDataPath, true);
|
|
||||||
// Page in the SceneViewer now that our key is ready
|
|
||||||
GetResMgr()->PageInSceneViewer();
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool plUpdatableClient::MainLoop()
|
|
||||||
{
|
|
||||||
IGetUpdate();
|
|
||||||
|
|
||||||
if (fActive)
|
|
||||||
return plClient::MainLoop();
|
|
||||||
else
|
|
||||||
{
|
|
||||||
Sleep(100);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#include <direct.h>
|
|
||||||
|
|
||||||
bool plUpdatableClient::Shutdown()
|
|
||||||
{
|
|
||||||
if (fDirty && fDataPath)
|
|
||||||
{
|
|
||||||
char oldCwd[MAX_PATH];
|
|
||||||
getcwd(oldCwd, sizeof(oldCwd));
|
|
||||||
|
|
||||||
// Even bigger hack
|
|
||||||
char tempCrap[MAX_PATH];
|
|
||||||
strcpy(tempCrap, fDataPath);
|
|
||||||
tempCrap[strlen(tempCrap)-strlen("dat\\")] = '\0';
|
|
||||||
chdir(tempCrap);
|
|
||||||
|
|
||||||
GetResMgr()->WriteSceneViewer();
|
|
||||||
|
|
||||||
chdir(oldCwd);
|
|
||||||
}
|
|
||||||
|
|
||||||
return plClient::Shutdown();
|
|
||||||
}
|
|
||||||
|
|
||||||
void plUpdatableClient::IEnableProxies(bool enable)
|
|
||||||
{
|
|
||||||
if (enable)
|
|
||||||
{
|
|
||||||
// switch back on any drawable proxies
|
|
||||||
if (fPipeline->GetDrawableTypeMask() & plDrawableSpans::kAudibleProxy)
|
|
||||||
{
|
|
||||||
plProxyDrawMsg* msg = new plProxyDrawMsg(plProxyDrawMsg::kAudible | plProxyDrawMsg::kCreate);
|
|
||||||
plgDispatch::MsgSend(msg);
|
|
||||||
}
|
|
||||||
if (fPipeline->GetDrawableTypeMask() & plDrawableSpans::kOccluderProxy)
|
|
||||||
{
|
|
||||||
plProxyDrawMsg* msg = new plProxyDrawMsg(plProxyDrawMsg::kOccluder | plProxyDrawMsg::kCreate);
|
|
||||||
plgDispatch::MsgSend(msg);
|
|
||||||
}
|
|
||||||
if (fPipeline->GetDrawableTypeMask() & plDrawableSpans::kPhysicalProxy)
|
|
||||||
{
|
|
||||||
plProxyDrawMsg* msg = new plProxyDrawMsg(plProxyDrawMsg::kPhysical | plProxyDrawMsg::kCreate);
|
|
||||||
plgDispatch::MsgSend(msg);
|
|
||||||
}
|
|
||||||
if (fPipeline->GetDrawableTypeMask() & plDrawableSpans::kLightProxy)
|
|
||||||
{
|
|
||||||
plProxyDrawMsg* msg = new plProxyDrawMsg(plProxyDrawMsg::kLight | plProxyDrawMsg::kCreate);
|
|
||||||
plgDispatch::MsgSend(msg);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// notify any and all drawable proxies to stop drawing...
|
|
||||||
plProxyDrawMsg* nuke = new plProxyDrawMsg(plProxyDrawMsg::kAudible
|
|
||||||
| plProxyDrawMsg::kOccluder
|
|
||||||
| plProxyDrawMsg::kPhysical
|
|
||||||
| plProxyDrawMsg::kLight
|
|
||||||
| plProxyDrawMsg::kDestroy);
|
|
||||||
plgDispatch::MsgSend(nuke);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void plUpdatableClient::WindowActivate(bool active)
|
|
||||||
{
|
|
||||||
fActive = active;
|
|
||||||
}
|
|
@ -1,81 +0,0 @@
|
|||||||
/*==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 plUpdatableClient_h_inc
|
|
||||||
#define plUpdatableClient_h_inc
|
|
||||||
|
|
||||||
#include "HeadSpin.h"
|
|
||||||
#include "plClient/plClient.h"
|
|
||||||
|
|
||||||
class hsSemaphore;
|
|
||||||
class plStatusLog;
|
|
||||||
|
|
||||||
class plUpdatableClient : public plClient
|
|
||||||
{
|
|
||||||
protected:
|
|
||||||
hsSemaphore *fUpdateSignal;
|
|
||||||
const char *fPipeName;
|
|
||||||
const char *fDataPath;
|
|
||||||
|
|
||||||
bool fActive;
|
|
||||||
bool fDirty;
|
|
||||||
|
|
||||||
plStatusLog *fLog;
|
|
||||||
|
|
||||||
void IEnableProxies(bool enable);
|
|
||||||
void IGetUpdate();
|
|
||||||
|
|
||||||
public:
|
|
||||||
plUpdatableClient();
|
|
||||||
virtual ~plUpdatableClient();
|
|
||||||
|
|
||||||
virtual hsG3DDeviceModeRecord ILoadDevMode(const char* devModeFile);
|
|
||||||
|
|
||||||
virtual bool Init();
|
|
||||||
virtual bool MainLoop();
|
|
||||||
virtual bool Shutdown();
|
|
||||||
|
|
||||||
void InitUpdate(const char *semaphoreName, const char *pipeName, const char *dir);
|
|
||||||
|
|
||||||
virtual void WindowActivate(bool active);
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif // plUpdatableClient_h_inc
|
|
Reference in New Issue
Block a user