Branan Purvine-Riley
11 years ago
21 changed files with 181 additions and 2789 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