Browse Source
So, yeah, this blows away MaxSceneViewer. We're never going to get around to fixing that. In exchange for this massive code explosion, you get a free MaxFileData stub type thing. It keeps all the data just so we don't blow up Cyan's plugins. This fixes the "Missing Dll" messages people keep whining about.
Adam Johnson
11 years ago
21 changed files with 162 additions and 2752 deletions
@ -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; } |
@ -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
|
Loading…
Reference in new issue