This commit is contained in:
romkazvo
2023-08-07 19:29:24 +08:00
commit 34d6c5d489
4832 changed files with 1389451 additions and 0 deletions

View File

@@ -0,0 +1,362 @@
////////////////////////////////////////////////////////////////////////////
//
// Crytek Engine Source File.
// Copyright (C), Crytek Studios, 2002.
// -------------------------------------------------------------------------
// File name: StatCGFCompiler.cpp
// Version: v1.00
// Created: 5/11/2002 by Vladimir Kajalin
// Compilers: Visual Studio.NET
// Description:
// -------------------------------------------------------------------------
// History:
//
////////////////////////////////////////////////////////////////////////////
#include "StdAfx.h"
#include <sys/types.h>
#include <sys/stat.h>
#include <time.h>
#include <DbgHelp.h>
#include "ConvertContext.h"
#include "iconfig.h"
#include "StatCGFCompiler.h"
#define ISystem IRCLog
#include "meshidx.h"
#include "statcgfshadvol.h"
CStatCFGCompiler::CStatCFGCompiler(void)
{
}
CStatCFGCompiler::~CStatCFGCompiler(void)
{
}
// function for creating this from outside (without including StatCGFCompiler.h)
IConvertor* NewStatCGFCompiler()
{
return new CStatCFGCompiler();
}
void CStatCFGCompiler::FindDependencies( CIndexedMesh * pIndexedMesh, ConvertContext &cc )
{
cc.pLog->Log("Finding dependencies");
for(int m=0; m<pIndexedMesh->m_lstMatTable.Count(); m++)
{
CMatInfo &ref=pIndexedMesh->m_lstMatTable[m];
const char *szMatName=ref.GetName();
const char *szScriptName=ref.sScriptMaterial;
CString sourceFile = cc.getSourcePath();
cc.pRC->AddDependencyMaterial(sourceFile.GetString(),szMatName,szScriptName); // material name
if(!ref.pMatEnt)continue;
// texture path names
#define ADD_MAP(MAP) if (ref.pMatEnt->map_##MAP.name[0]) cc.pRC->AddDependencyFile(sourceFile.GetString(),ref.pMatEnt->map_##MAP.name);
ADD_MAP(a);
ADD_MAP(d);
ADD_MAP(o);
ADD_MAP(b);
ADD_MAP(s);
ADD_MAP(g);
ADD_MAP(detail);
ADD_MAP(e);
ADD_MAP(subsurf);
ADD_MAP(displ);
#undef ADD_MAP
}
}
FILETIME UnixTimeToFileTime(time_t t)
{
// Note that LONGLONG is a 64-bit value
LONGLONG ll = Int32x32To64(t, 10000000) + 116444736000000000;
return (FILETIME&)ll;
}
// returns the file modification time
FILETIME GetModificationTime(FILE* hFile)
{
struct _stat st;
_fstat(_fileno(hFile), &st);
#ifdef _DEBUG
const char* szTest = ctime (&st.st_mtime);
#endif
return UnixTimeToFileTime (st.st_mtime);
}
bool CStatCFGCompiler::GetSourceFileTime(const char * szFileName, FILETIME & fileTime)
{
FILE* f = fopen (szFileName, "rb");
if (!f)
return false;
fileTime = GetModificationTime(f);
fclose (f);
return true;
}
void CStatCFGCompiler::GetFileParams( ConvertContext &cc, CString & sGeomName,
bool & bStripify, bool & bLoadAdditinalInfo, bool & bKeepInLocalSpace)
{
cc.config->Get("GeomName",sGeomName); // subobject name
cc.config->Get("Stripify",bStripify); // sort for vertex ceache
cc.config->Get("LoadAdditinalInfo",bLoadAdditinalInfo); // load geom names, helpers, lightsources
cc.config->Get("KeepInLocalSpace",bKeepInLocalSpace); // do not transform vertices by node matrix
}
bool CStatCFGCompiler::Process( ConvertContext &cc )
{
try
{
CString sGeomName;
bool bStripify=0, bLoadAdditinalInfo=0, bKeepInLocalSpace=0;
GetFileParams( cc, sGeomName, bStripify, bLoadAdditinalInfo, bKeepInLocalSpace);
if (!cc.bQuiet)
{
cc.pLog->Log("Conversion params:");
cc.pLog->Log(" GeomName = %s", sGeomName[0] ? sGeomName : "None");
cc.pLog->Log(" Stripify = %s", bStripify ? "Yes" : "No");
cc.pLog->Log(" LoadAdditinalInfo = %s", bLoadAdditinalInfo ? "Yes" : "No");
cc.pLog->Log(" KeepInLocalSpace = %s", bKeepInLocalSpace ? "Yes" : "No");
}
CString sourceFile = cc.getSourcePath();
CString outputFile = cc.getOutputPath();
const char *sInFile = sourceFile.GetString();
FILETIME fileTime;
if(!GetSourceFileTime( sourceFile.GetString(), fileTime))
{
remove( outputFile.GetString() );
return false;
}
// Check if .cga.
if (stricmp(Path::GetExt(cc.sourceFile).GetString(),"cga") == 0)
{
// Load CGA.
ProcessCGA( cc,sourceFile,outputFile,fileTime,bStripify );
}
else
{
// Load Normal CGF.
ProcessCGF( cc,sourceFile,outputFile,fileTime,sGeomName,bStripify,bLoadAdditinalInfo,bKeepInLocalSpace );
}
}
catch(char*)
{
Beep(1000,1000);
return false;
}
return true;
}
//////////////////////////////////////////////////////////////////////////
void CStatCFGCompiler::ProcessCGA( ConvertContext &cc,CString &sourceFile,CString &outputFile,FILETIME fileTime,bool bStripify )
{
CString outputFileNoExt = Path::RemoveExtension(cc.sourceFile);
CString outputGeomFile;
int nLoadedTrisCount=0;
CIndexedMesh * pIndexedMesh = new CIndexedMesh( cc.pLog,sourceFile.GetString(),0,&nLoadedTrisCount,true,true );
if (pIndexedMesh)
{
for (int i = 0; i < (int)pIndexedMesh->m_lstGeomNames.size(); i++)
{
CString sOrgGeomName = pIndexedMesh->m_lstGeomNames[i];
CString sGeomName = sOrgGeomName;
sGeomName.Replace( '\\','_' );
sGeomName.Replace( '/','_' );
outputGeomFile.Format( "%s_%s_%d_%d_%d.ccgf",outputFileNoExt.GetString(), sGeomName.GetString(),(int)bStripify,1,1 );
cc.outputFile = outputGeomFile;
outputGeomFile = cc.getOutputPath();
const char *sgeom = outputGeomFile.GetString();
ProcessCGF( cc,sourceFile,outputGeomFile,fileTime,sOrgGeomName,bStripify,true,true );
}
}
delete pIndexedMesh;
}
//////////////////////////////////////////////////////////////////////////
void CStatCFGCompiler::ProcessCGF( ConvertContext &cc,CString &sourceFile,CString &outputFile,FILETIME fileTime,CString sGeomName,
bool bStripify, bool bLoadAdditinalInfo, bool bKeepInLocalSpace )
{
// load source cgf
int nLoadedTrisCount=0;
CIndexedMesh * pIndexedMesh = new CIndexedMesh( cc.pLog, sourceFile.GetString(), sGeomName[0] ? sGeomName.GetString() : 0,
&nLoadedTrisCount, bLoadAdditinalInfo, bKeepInLocalSpace);
pIndexedMesh->CalcTangentSpace();
// if geom name was specified - save empty file to let the engine know that this geom does not exits
// since passing wrong geom name is valid operation
if(!nLoadedTrisCount && !sGeomName[0])
cc.pLog->ThrowError(" No faces found");
// find dependencies (material names, texture path names)
FindDependencies( pIndexedMesh, cc );
// compile data
CSimpleStatObj StatObj( cc.pLog, pIndexedMesh, sourceFile.GetString() );
CSimpleLeafBuffer LeafBuffer(cc.pLog, pIndexedMesh, bStripify,
pIndexedMesh->m_lstGeomNames.Count()>0 && strstr(pIndexedMesh->m_lstGeomNames[0],"cloth")!=0);
CStatCGFShadVol StatCGFShadVol(cc.pLog, pIndexedMesh);
int nPos = 0;
// get data size
if(nLoadedTrisCount)
{
StatObj.Serialize(nPos, 0, true);
LeafBuffer.Serialize(nPos, 0, true, outputFile.GetString() );
StatCGFShadVol.Serialize(nPos, 0, true);
}
// allocate mem buffer
uchar * pData = new uchar[nPos+sizeof(CCGFHeader)];
// make header
CCGFHeader fileHeader;
fileHeader.nDataSize = nPos;
fileHeader.nFacesInCGFNum = nLoadedTrisCount;
fileHeader.SourceFileTime = fileTime;
fileHeader.vBoxMin = pIndexedMesh->m_vBoxMin;
fileHeader.vBoxMax = pIndexedMesh->m_vBoxMax;
strcpy(fileHeader.szVersion,CCGF_FILE_VERSION);
if(StatObj.IsPhysicsExist())
fileHeader.dwFlags |= CCGFHF_PHYSICS_EXIST;
memcpy(pData,&fileHeader,sizeof(CCGFHeader));
nPos = sizeof(fileHeader);
// save to new file
if(nLoadedTrisCount)
{
StatObj.Serialize(nPos, pData, true);
LeafBuffer.Serialize(nPos, pData, true, outputFile.GetString() );
StatCGFShadVol.Serialize(nPos, pData, true);
}
// create folder for object
CString srtDirName = cc.getOutputFolderPath();
int nFind = -1;
while(1)
{
nFind = srtDirName.Find('\\', nFind+1);
if(nFind<0)
break;
CString strSubDirName = srtDirName.Left(nFind);
CreateDirectory(strSubDirName.GetString(),NULL);
}
cc.pLog->Log("Writing CCGF: %s", outputFile.GetString() );
FILE * f = fopen(outputFile.GetString(),"wb");
if(f)
{
size_t nWriten = fwrite(pData,1,nPos,f);
fclose(f);
if(nWriten == nPos)
cc.pLog->Log(" %d bytes saved", nPos);
else
cc.pLog->ThrowError(" Error writing output file");
}
else
cc.pLog->ThrowError(" Error opening output file");
delete pIndexedMesh;
delete pData;
}
////////////////////////////////////////////////////////////
//
// !!! PLZ NEVER CHANGE THIS FILE WITHOUT ASKING VLAD !!!
//
////////////////////////////////////////////////////////////
bool CStatCFGCompiler::GetOutputFile( ConvertContext &cc )
{
bool bStripify=0, bLoadAdditinalInfo=0, bKeepInLocalSpace=0; CString sGeomName;
GetFileParams( cc, sGeomName, bStripify, bLoadAdditinalInfo, bKeepInLocalSpace);
CString outputFileNoExt = Path::ReplaceExtension( cc.sourceFile, "" );
char szCurDir[MAX_PATH]="";
GetCurrentDirectory(MAX_PATH,szCurDir);
CString curFolderName = szCurDir;
cc.outputFolder = cc.masterFolder + CString(CCGF_CACHE_DIR_NAME) + "\\" + cc.outputFolder;
//CString outputDirName=Path::ReplacePath(curFolderName, curFolderName + "\\" + CCGF_CACHE_DIR_NAME, outputFileNoExt);
char szOutputFileName[1024];
sprintf(szOutputFileName,
"%s_%s_%d_%d_%d.ccgf",
outputFileNoExt.GetString(), sGeomName.GetString(),
(int)bStripify, (int)bLoadAdditinalInfo, (int)bKeepInLocalSpace);
//specify output path
cc.outputFile = szOutputFileName;
return true;
}
//////////////////////////////////////////////////////////////////////////
int CStatCFGCompiler::GetNumPlatforms() const
{
return 4;
}
//////////////////////////////////////////////////////////////////////////
Platform CStatCFGCompiler::GetPlatform( int index ) const
{
switch (index)
{
case 0: return PLATFORM_PC;
case 1: return PLATFORM_XBOX;
//case 2: return PLATFORM_PS2;
//case 3: return PLATFORM_GAMECUBE;
};
//assert(0);
return PLATFORM_UNKNOWN;
}
DWORD CStatCFGCompiler::GetTimestamp() const
{
return GetTimestampForLoadedLibrary(g_hInst);
}
CStatCFGCompiler::Error::Error (const char* szFormat, ...)
{
char szBuffer[0x800];
va_list arg;
va_start(arg,szFormat);
_vsnprintf (szBuffer, sizeof(szBuffer), szFormat, arg);
va_end(arg);
this->m_strReason = szBuffer;
}
CStatCFGCompiler::Error::Error (int nCode)
{
char szBuffer[36];
sprintf (szBuffer, "Generic Error #%d", nCode);
this->m_strReason = szBuffer;
}
int CStatCFGCompiler::SetTexType(TextureMap3 *tm)
{
if (tm->type == TEXMAP_CUBIC)
return eTT_Cubemap;
else
if (tm->type == TEXMAP_AUTOCUBIC)
return eTT_AutoCubemap;
return eTT_Base;
}