summaryrefslogtreecommitdiff
path: root/hammer/prefab3d.cpp
diff options
context:
space:
mode:
authorFluorescentCIAAfricanAmerican <[email protected]>2020-04-22 12:56:21 -0400
committerFluorescentCIAAfricanAmerican <[email protected]>2020-04-22 12:56:21 -0400
commit3bf9df6b2785fa6d951086978a3e66f49427166a (patch)
tree2c0f1f0c63c4832882bc93814ebd2c2b1c6224e5 /hammer/prefab3d.cpp
downloadarchived-source-engine-2018-hl2-src-master.tar.xz
archived-source-engine-2018-hl2-src-master.zip
Diffstat (limited to 'hammer/prefab3d.cpp')
-rw-r--r--hammer/prefab3d.cpp593
1 files changed, 593 insertions, 0 deletions
diff --git a/hammer/prefab3d.cpp b/hammer/prefab3d.cpp
new file mode 100644
index 0000000..109f0da
--- /dev/null
+++ b/hammer/prefab3d.cpp
@@ -0,0 +1,593 @@
+//========= Copyright Valve Corporation, All rights reserved. ============//
+//
+// Purpose:
+//
+// $NoKeywords: $
+//=============================================================================//
+
+#include "stdafx.h"
+#include <sys\types.h>
+#include <sys\stat.h>
+#include "ChunkFile.h"
+#include "Prefab3D.h"
+#include "Options.h"
+#include "History.h"
+#include "MapGroup.h"
+#include "MapWorld.h"
+#include "GlobalFunctions.h"
+
+// memdbgon must be the last include file in a .cpp file!!!
+#include <tier0/memdbgon.h>
+
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+CPrefab3D::CPrefab3D()
+{
+ m_pWorld = NULL;
+}
+
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+CPrefab3D::~CPrefab3D()
+{
+ FreeData();
+}
+
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+void CPrefab3D::FreeData()
+{
+ delete m_pWorld;
+ m_pWorld = NULL;
+}
+
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+CMapClass *CPrefab3D::Create(void)
+{
+ if (!IsLoaded() && (Load() == -1))
+ {
+ return(NULL);
+ }
+
+ CMapClass *pCopy;
+ CMapClass *pOriginal;
+
+ //
+ // Check for just one object - if only one, don't group it.
+ //
+ if (m_pWorld->GetChildCount() == 1)
+ {
+
+ pOriginal = m_pWorld->GetChildren()->Element(0);
+ pCopy = pOriginal->Copy(false);
+ }
+ else
+ {
+ // Original object is world
+ pOriginal = m_pWorld;
+
+ // New object is a new group
+ pCopy = (CMapClass *)new CMapGroup;
+ }
+
+ //
+ // Copy children from original (if any).
+ //
+ pCopy->CopyChildrenFrom(pOriginal, false);
+
+ // HACK: must calculate bounds here due to a hack in CMapClass::CopyChildrenFrom
+ pCopy->CalcBounds();
+
+ return(pCopy);
+}
+
+
+//-----------------------------------------------------------------------------
+// Purpose:
+// Input : point - Where to center the prefab.
+// Output : CMapClass
+//-----------------------------------------------------------------------------
+CMapClass *CPrefab3D::CreateAtPoint(const Vector &point)
+{
+ //
+ // Create the prefab object. It will either be a single object
+ // or a group containing the prefab objects.
+ //
+ CMapClass *pObject = Create();
+
+ if (pObject != NULL)
+ {
+ //
+ // Move the prefab center to match the given point.
+ //
+ Vector move = point;
+ Vector center;
+ pObject->GetBoundsCenter(center);
+ for (int i = 0; i < 3; i++)
+ {
+ move[i] -= center[i];
+ }
+
+ BOOL bOldLock = Options.SetLockingTextures(TRUE);
+ pObject->TransMove(move);
+ Options.SetLockingTextures(bOldLock);
+ }
+
+ return(pObject);
+}
+
+
+//-----------------------------------------------------------------------------
+// Purpose:
+// Input :
+// Output :
+//-----------------------------------------------------------------------------
+CMapClass *CPrefab3D::CreateAtPointAroundOrigin( Vector const &point )
+{
+ //
+ // Create the prefab object. It will either be a single object
+ // or a group containing the prefab objects.
+ //
+ CMapClass *pObject = Create();
+
+ if( !pObject )
+ return NULL;
+
+ Vector move = point;
+
+ BOOL bOldLock = Options.SetLockingTextures( TRUE );
+ pObject->TransMove( move );
+ Options.SetLockingTextures( bOldLock );
+
+ return ( pObject );
+}
+
+
+//-----------------------------------------------------------------------------
+// Purpose:
+// Input : pBox -
+// Output :
+//-----------------------------------------------------------------------------
+CMapClass *CPrefab3D::CreateInBox(BoundBox *pBox)
+{
+ //
+ // Create the prefab object. It will either be a single object
+ // or a group containing the prefab objects.
+ //
+ CMapClass *pObject = Create();
+
+ if (pObject != NULL)
+ {
+ //
+ // Scale the prefab to match the box bounds.
+ //
+ Vector NewSize;
+ pBox->GetBoundsSize(NewSize);
+
+ Vector CurSize;
+ pObject->GetBoundsSize(CurSize);
+
+ Vector scale;
+ for (int i = 0; i < 3; i++)
+ {
+ scale[i] = NewSize[i] / CurSize[i];
+ }
+
+ Vector zero(0, 0, 0);
+ pObject->TransScale(zero, scale);
+
+ //
+ // Move the prefab center to match the box center.
+ //
+ Vector move;
+ pBox->GetBoundsCenter(move);
+
+ Vector center;
+ pObject->GetBoundsCenter(center);
+ for (int i = 0; i < 3; i++)
+ {
+ move[i] -= center[i];
+ }
+
+ BOOL bOldLock = Options.SetLockingTextures(TRUE);
+ pObject->TransMove(move);
+ Options.SetLockingTextures(bOldLock);
+ }
+
+ return(pObject);
+}
+
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+void CPrefab3D::CenterOnZero()
+{
+ Vector ptCenter;
+ m_pWorld->GetBoundsCenter(ptCenter);
+ ptCenter[0] = -ptCenter[0];
+ ptCenter[1] = -ptCenter[1];
+ ptCenter[2] = -ptCenter[2];
+
+ BOOL bOldLock = Options.SetLockingTextures(TRUE);
+ m_pWorld->TransMove(ptCenter);
+ Options.SetLockingTextures(bOldLock);
+}
+
+
+//-----------------------------------------------------------------------------
+// Purpose: Returns true if the prefab data has been loaded from disk, false if not.
+//-----------------------------------------------------------------------------
+bool CPrefab3D::IsLoaded(void)
+{
+ return (m_pWorld != NULL);
+}
+
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+CPrefabRMF::CPrefabRMF()
+{
+}
+
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+CPrefabRMF::~CPrefabRMF()
+{
+}
+
+
+//-----------------------------------------------------------------------------
+// Purpose:
+// Input : file -
+// dwFlags -
+// Output : int
+//-----------------------------------------------------------------------------
+int CPrefabRMF::DoLoad(std::fstream& file, DWORD dwFlags)
+{
+ int iRvl;
+
+ GetHistory()->Pause();
+
+ AddMRU(this);
+
+ if(m_pWorld)
+ delete m_pWorld;
+ m_pWorld = new CMapWorld( NULL );
+
+ // read data
+ if(dwFlags & lsMAP)
+ iRvl = m_pWorld->SerializeMAP(file, FALSE);
+ else
+ iRvl = m_pWorld->SerializeRMF(file, FALSE);
+
+ // error?
+ if(iRvl == -1)
+ {
+ GetHistory()->Resume();
+ return iRvl;
+ }
+
+ m_pWorld->CalcBounds(TRUE);
+
+ GetHistory()->Resume();
+
+ return 1;
+}
+
+
+//-----------------------------------------------------------------------------
+// Purpose:
+// Input : file -
+// dwFlags -
+// Output : int
+//-----------------------------------------------------------------------------
+int CPrefabRMF::DoSave(std::fstream& file, DWORD dwFlags)
+{
+ // save world
+ if(dwFlags & lsMAP)
+ return m_pWorld->SerializeMAP(file, TRUE);
+
+ return m_pWorld->SerializeRMF(file, TRUE);
+}
+
+
+//-----------------------------------------------------------------------------
+// Purpose:
+// Input : dwFlags -
+// Output : int
+//-----------------------------------------------------------------------------
+int CPrefabRMF::Load(DWORD dwFlags)
+{
+ //
+ // Get parent library's file handle.
+ //
+ CPrefabLibraryRMF *pLibrary = dynamic_cast <CPrefabLibraryRMF *>(CPrefabLibrary::FindID(dwLibID));
+ if (!pLibrary)
+ {
+ return -1;
+ }
+
+ std::fstream &file = pLibrary->m_file;
+ file.seekg(dwFileOffset);
+
+ return(DoLoad(file, dwFlags));
+}
+
+
+//-----------------------------------------------------------------------------
+// Purpose:
+// Input : pszFilename -
+// bLoadNow -
+// dwFlags -
+// Output : int
+//-----------------------------------------------------------------------------
+int CPrefabRMF::Init(LPCTSTR pszFilename, BOOL bLoadNow, DWORD dwFlags)
+{
+ std::fstream file(pszFilename, std::ios::in | std::ios::binary);
+
+ // ensure we're named
+ memset(szName, 0, sizeof szName);
+ strncpy(szName, pszFilename, sizeof szName - 1);
+ return Init(file, bLoadNow, dwFlags);
+}
+
+
+//-----------------------------------------------------------------------------
+// Purpose:
+// Input : file -
+// bLoadNow -
+// dwFlags -
+// Output : int
+//-----------------------------------------------------------------------------
+int CPrefabRMF::Init(std::fstream &file, BOOL bLoadNow, DWORD dwFlags)
+{
+ int iRvl = 1; // start off ok
+
+ if(bLoadNow)
+ {
+ // do load now
+ iRvl = DoLoad(file, dwFlags);
+ }
+
+ if(!szName[0])
+ {
+ // ensure we're named
+ strcpy(szName, "Prefab");
+ }
+
+ return iRvl;
+}
+
+
+//-----------------------------------------------------------------------------
+// Purpose:
+// Input : pszFilename -
+// dwFlags -
+// Output : int
+//-----------------------------------------------------------------------------
+int CPrefabRMF::Save(LPCTSTR pszFilename, DWORD dwFlags)
+{
+ std::fstream file(pszFilename, std::ios::out | std::ios::binary);
+ return Save(file, dwFlags);
+}
+
+
+//-----------------------------------------------------------------------------
+// Purpose:
+// Input : file -
+// dwFlags -
+// Output : int
+//-----------------------------------------------------------------------------
+int CPrefabRMF::Save(std::fstream& file, DWORD dwFlags)
+{
+ if (!IsLoaded() && (Load() == -1))
+ {
+ AfxMessageBox("Couldn't Load prefab to Save it.");
+ return -1;
+ }
+
+ return DoSave(file, dwFlags);
+}
+
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+CPrefabVMF::CPrefabVMF()
+{
+}
+
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+CPrefabVMF::~CPrefabVMF()
+{
+}
+
+
+//-----------------------------------------------------------------------------
+// Purpose: Returns true if the prefab data has been loaded from disk, false if not.
+//-----------------------------------------------------------------------------
+bool CPrefabVMF::IsLoaded(void)
+{
+ if (m_pWorld == NULL)
+ {
+ return false;
+ }
+
+ //
+ // We have loaded this prefab at least once this session. Check the file date/time
+ // against our cached date/time to see if we need to reload it.
+ //
+ struct _stat info;
+ if (_stat(m_szFilename, &info) == 0)
+ {
+ if (info.st_mtime > m_nFileTime)
+ {
+ return false;
+ }
+ }
+
+ return true;
+}
+
+
+//-----------------------------------------------------------------------------
+// Purpose:
+// Input : dwFlags -
+// Output : int
+//-----------------------------------------------------------------------------
+int CPrefabVMF::Load(DWORD dwFlags)
+{
+ //
+ // Create a new world to hold the loaded objects.
+ //
+ if (m_pWorld != NULL)
+ {
+ delete m_pWorld;
+ }
+
+ m_pWorld = new CMapWorld( NULL );
+
+ //
+ // Open the file.
+ //
+ CChunkFile File;
+ ChunkFileResult_t eResult = File.Open(m_szFilename, ChunkFile_Read);
+
+ //
+ // Read the file.
+ //
+ if (eResult == ChunkFile_Ok)
+ {
+ //
+ // Set up handlers for the subchunks that we are interested in.
+ //
+ CChunkHandlerMap Handlers;
+ Handlers.AddHandler("world", (ChunkHandler_t)CPrefabVMF::LoadWorldCallback, this);
+ Handlers.AddHandler("entity", (ChunkHandler_t)CPrefabVMF::LoadEntityCallback, this);
+ // dvs: Handlers.SetErrorHandler((ChunkErrorHandler_t)CPrefabVMF::HandleLoadError, this);
+
+ File.PushHandlers(&Handlers);
+
+ //CMapDoc::SetLoadingMapDoc( this ); dvs: fix - without this, no displacements in prefabs
+
+ //
+ // Read the sub-chunks. We ignore keys in the root of the file, so we don't pass a
+ // key value callback to ReadChunk.
+ //
+ while (eResult == ChunkFile_Ok)
+ {
+ eResult = File.ReadChunk();
+ }
+
+ if (eResult == ChunkFile_EOF)
+ {
+ eResult = ChunkFile_Ok;
+ }
+
+ //CMapDoc::SetLoadingMapDoc( NULL );
+
+ File.PopHandlers();
+ }
+
+ if (eResult == ChunkFile_Ok)
+ {
+ m_pWorld->PostloadWorld();
+ m_pWorld->CalcBounds();
+
+ File.Close();
+
+ //
+ // Store the file modification time to use as a cache check.
+ //
+ struct _stat info;
+ if (_stat(m_szFilename, &info) == 0)
+ {
+ m_nFileTime = info.st_mtime;
+ }
+ }
+ else
+ {
+ //GetMainWnd()->MessageBox(File.GetErrorText(eResult), "Error loading prefab", MB_OK | MB_ICONEXCLAMATION);
+ }
+
+ return(eResult == ChunkFile_Ok);
+}
+
+
+//-----------------------------------------------------------------------------
+// Purpose:
+// Input : pFile -
+// pData -
+// Output : ChunkFileResult_t
+//-----------------------------------------------------------------------------
+ChunkFileResult_t CPrefabVMF::LoadEntityCallback(CChunkFile *pFile, CPrefabVMF *pPrefab)
+{
+ CMapEntity *pEntity = new CMapEntity;
+
+ ChunkFileResult_t eResult = pEntity->LoadVMF(pFile);
+
+ if (eResult == ChunkFile_Ok)
+ {
+ CMapWorld *pWorld = pPrefab->GetWorld();
+ pWorld->AddChild(pEntity);
+ }
+
+ return(ChunkFile_Ok);
+}
+
+
+//-----------------------------------------------------------------------------
+// Purpose:
+// Input : pFile -
+// pData -
+// Output : ChunkFileResult_t
+//-----------------------------------------------------------------------------
+ChunkFileResult_t CPrefabVMF::LoadWorldCallback(CChunkFile *pFile, CPrefabVMF *pPrefab)
+{
+ CMapWorld *pWorld = pPrefab->GetWorld();
+ ChunkFileResult_t eResult = pWorld->LoadVMF(pFile);
+ return(eResult);
+}
+
+
+//-----------------------------------------------------------------------------
+// Purpose:
+// Input : pszFilename -
+// dwFlags -
+// Output : int
+//-----------------------------------------------------------------------------
+int CPrefabVMF::Save(LPCTSTR pszFilename, DWORD dwFlags)
+{
+ return 1;
+}
+
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+void CPrefabVMF::SetFilename(const char *szFilename)
+{
+ //
+ // Extract the file name without the path or extension as the prefab name.
+ //
+ _splitpath(szFilename, NULL, NULL, szName, NULL);
+
+ strcpy(m_szFilename, szFilename);
+}
+