123
This commit is contained in:
284
ResourceCompiler/CfgFile.cpp
Normal file
284
ResourceCompiler/CfgFile.cpp
Normal file
@@ -0,0 +1,284 @@
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Crytek Engine Source File.
|
||||
// Copyright (C), Crytek Studios, 2002.
|
||||
// -------------------------------------------------------------------------
|
||||
// File name: cfgfile.cpp
|
||||
// Version: v1.00
|
||||
// Created: 4/11/2002 by Timur.
|
||||
// Compilers: Visual Studio.NET
|
||||
// Description:
|
||||
// -------------------------------------------------------------------------
|
||||
// History:
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
//
|
||||
// Configuration file class.
|
||||
// Use format similar to windows .ini files.
|
||||
//
|
||||
#include "StdAfx.h"
|
||||
#include "cfgfile.h"
|
||||
#include "Config.h"
|
||||
#include "DebugLog.h"
|
||||
|
||||
//#define Log DebugLog
|
||||
#define Log while (false)
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Class CfgFile implementation.
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
CfgFile::CfgFile()
|
||||
{
|
||||
// Create IsEmpty section.
|
||||
Section section;
|
||||
section.name = "";
|
||||
m_sections.push_back( section );
|
||||
|
||||
m_modified = false;
|
||||
}
|
||||
|
||||
|
||||
CfgFile::CfgFile( const CString &fileName )
|
||||
{
|
||||
// Create IsEmpty section.
|
||||
Section section;
|
||||
section.name = "";
|
||||
m_sections.push_back( section );
|
||||
m_modified = false;
|
||||
|
||||
Load( fileName );
|
||||
}
|
||||
|
||||
CfgFile::CfgFile( const char *buf,int bufSize ) {
|
||||
// Create IsEmpty section.
|
||||
Section section;
|
||||
section.name = "";
|
||||
m_sections.push_back( section );
|
||||
m_modified = false;
|
||||
|
||||
LoadBuf( buf,bufSize );
|
||||
}
|
||||
|
||||
CfgFile::~CfgFile()
|
||||
{
|
||||
}
|
||||
|
||||
//!
|
||||
void CfgFile::SetFileName( const CString &fileName )
|
||||
{
|
||||
m_fileName = fileName;
|
||||
}
|
||||
|
||||
// Load configuration file.
|
||||
bool CfgFile::Load( const CString &fileName )
|
||||
{
|
||||
m_fileName = fileName;
|
||||
m_modified = false;
|
||||
|
||||
FILE *file = fopen( fileName.GetString(),"rb" );
|
||||
if (!file)
|
||||
{
|
||||
char szCWD[0x400];
|
||||
getcwd(szCWD, sizeof(szCWD));
|
||||
Log ("Can't open \"%s\"", fileName.GetString());
|
||||
Log ("CWD=%s", szCWD);
|
||||
return false;
|
||||
}
|
||||
|
||||
fseek( file,0,SEEK_END );
|
||||
int size = ftell(file);
|
||||
fseek( file,0,SEEK_SET );
|
||||
|
||||
// Read whole file to memory.
|
||||
char *s = (char*)malloc( size+1 );
|
||||
memset( s,0,size+1 );
|
||||
fread( s,1,size,file );
|
||||
LoadBuf( s,size );
|
||||
free(s);
|
||||
|
||||
fclose(file);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
// Save configuration file, with the stored name in m_fileName
|
||||
bool CfgFile::Save( void )
|
||||
{
|
||||
FILE *file = fopen(m_fileName.GetBuffer(),"wb");
|
||||
|
||||
if(!file)
|
||||
return(false);
|
||||
|
||||
// Loop on sections.
|
||||
for (std::vector<Section>::iterator si = m_sections.begin(); si != m_sections.end(); si++)
|
||||
{
|
||||
Section &sec =*si;
|
||||
|
||||
if(sec.name!="")
|
||||
fprintf(file,"[%s]\r\n",sec.name); // section
|
||||
|
||||
for (std::list<Entry>::iterator it = sec.entries.begin(); it != sec.entries.end(); ++it)
|
||||
{
|
||||
if((*it).key=="")
|
||||
fprintf(file,"%s\r\n",(*it).value.GetBuffer()); // comment
|
||||
else
|
||||
fprintf(file,"%s=%s\r\n",(*it).key.GetBuffer(),(*it).value.GetBuffer()); // key=value
|
||||
}
|
||||
}
|
||||
|
||||
fclose(file);
|
||||
return(true);
|
||||
}
|
||||
|
||||
|
||||
void CfgFile::UpdateOrCreateEntry( const char *inszSection, const char *inszKey, const char *inszValue )
|
||||
{
|
||||
Section *sec = FindSection( inszSection ); assert(sec);
|
||||
|
||||
for(std::list<Entry>::iterator it = sec->entries.begin(); it != sec->entries.end(); ++it)
|
||||
{
|
||||
if(stricmp(it->key.GetString(),inszKey) == 0) // Key found
|
||||
if(!it->IsComment()) // update key
|
||||
{
|
||||
if(it->value==inszValue)
|
||||
return;
|
||||
|
||||
it->value=inszValue;
|
||||
m_modified=true;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// Create new key
|
||||
Entry entry;
|
||||
entry.key = inszKey;
|
||||
entry.value = inszValue;
|
||||
|
||||
sec->entries.push_back(entry);
|
||||
m_modified=true;
|
||||
}
|
||||
|
||||
|
||||
|
||||
void CfgFile::LoadBuf( const char *buf,size_t bufSize )
|
||||
{
|
||||
|
||||
// Read entries from config CString buffer.
|
||||
Section *curr_section = &m_sections.front(); // Empty section.
|
||||
|
||||
const char *s = buf;
|
||||
size_t size = bufSize;
|
||||
|
||||
CString ss = s;
|
||||
|
||||
char str[4096];
|
||||
size_t i = 0;
|
||||
|
||||
while (i < size)
|
||||
{
|
||||
// while (j < size && s[j] != '\n') j++;
|
||||
|
||||
sscanf( &s[i],"%[^\n]s",str );
|
||||
|
||||
Log ("Parsing line: \"%s\"", str);
|
||||
|
||||
i+=strlen(str);
|
||||
if(s[i]==10)i++;
|
||||
|
||||
bool bComment=false;
|
||||
|
||||
// Is comment?
|
||||
Entry entry;
|
||||
entry.key = "";
|
||||
entry.value = str;
|
||||
|
||||
bComment=entry.IsComment();
|
||||
|
||||
if (bComment)
|
||||
Log ("It's a comment");
|
||||
|
||||
// Analyze entry CString, split on key and value and store in lists.
|
||||
CString entrystr = str;
|
||||
|
||||
if(!bComment)
|
||||
entrystr.Trim();
|
||||
|
||||
if(bComment || entrystr.IsEmpty())
|
||||
{
|
||||
Log ("Empty!");
|
||||
// Add this comment to current section.
|
||||
curr_section->entries.push_back( entry );
|
||||
continue;
|
||||
}
|
||||
|
||||
|
||||
{
|
||||
int splitter = entrystr.Find( '=' );
|
||||
Log ("found splitter at %d", splitter);
|
||||
|
||||
if (splitter > 0)
|
||||
{
|
||||
// Key found.
|
||||
entry.key = entrystr.Mid( 0,splitter ); // Before spliter is key name.
|
||||
Log ("Key: %s", entry.key.GetString());
|
||||
entry.value = entrystr.Mid( splitter+1 ); // Everything after splittes is value CString.
|
||||
Log ("Value: %s", entry.value.GetString());
|
||||
entry.key.Trim();
|
||||
entry.value.Trim();
|
||||
Log ("Key: %s, Value: %s", entry.key.GetString(), entry.value.GetString());
|
||||
|
||||
// Add this entry to current section.
|
||||
curr_section->entries.push_back( entry );
|
||||
}
|
||||
else
|
||||
{
|
||||
// If not key then probably section CString.
|
||||
if (entrystr[0] == '[' && entrystr[entrystr.GetLength()-1] == ']')
|
||||
{
|
||||
// World in bracets is section name.
|
||||
Section section;
|
||||
section.name = entrystr.Mid( 1,entrystr.GetLength()-2 ); // Remove bracets.
|
||||
Log ("Section! name: %s", section.name.GetString());
|
||||
m_sections.push_back( section );
|
||||
// Set current section.
|
||||
curr_section = &m_sections.back();
|
||||
}
|
||||
else
|
||||
{
|
||||
// Just IsEmpty key value.
|
||||
entry.key = "";
|
||||
entry.value = entrystr;
|
||||
|
||||
curr_section->entries.push_back( entry );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
CfgFile::Section* CfgFile::FindSection( const CString §ion )
|
||||
{
|
||||
return &m_sections[Find(section.GetString())];
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
bool CfgFile::SetConfig( const char *section, IConfig *config )
|
||||
{
|
||||
Section *sec = FindSection( section ); assert(sec);
|
||||
|
||||
for (std::list<Entry>::iterator it = sec->entries.begin(); it != sec->entries.end(); ++it)
|
||||
{
|
||||
if(!(*it).IsComment())
|
||||
config->Set( (*it).key.GetString(),(*it).value.GetString() );
|
||||
}
|
||||
return true;
|
||||
}
|
||||
125
ResourceCompiler/CfgFile.h
Normal file
125
ResourceCompiler/CfgFile.h
Normal file
@@ -0,0 +1,125 @@
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Crytek Engine Source File.
|
||||
// Copyright (C), Crytek Studios, 2002.
|
||||
// -------------------------------------------------------------------------
|
||||
// File name: cfgfile.h
|
||||
// Version: v1.00
|
||||
// Created: 4/11/2002 by Timur.
|
||||
// Compilers: Visual Studio.NET
|
||||
// Description:
|
||||
// -------------------------------------------------------------------------
|
||||
// History: 03/14/2003 MM added save support
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifndef __cfgfile_h__
|
||||
#define __cfgfile_h__
|
||||
#pragma once
|
||||
|
||||
#include "ICfgFile.h" // ICfgFile
|
||||
|
||||
class Config;
|
||||
|
||||
/** Configuration file class.
|
||||
Use format similar to windows .ini files.
|
||||
*/
|
||||
class CfgFile :public ICfgFile
|
||||
{
|
||||
public:
|
||||
// Config file entry structure, filled by readSection method.
|
||||
struct Entry
|
||||
{
|
||||
CString key; //!< keys (for comments this is "")
|
||||
CString value; //!< values and comments (with leading ; or //)
|
||||
|
||||
bool IsComment( void ) const
|
||||
{
|
||||
const char *pBegin=value.GetString();
|
||||
while(*pBegin==' ' || *pBegin=='\t')pBegin++;
|
||||
|
||||
// "//" (comment)
|
||||
if(pBegin[0]=='/' && pBegin[1]=='/')return(true);
|
||||
|
||||
// ';' (comment)
|
||||
if(pBegin[0] == ';')return(true);
|
||||
|
||||
// emptyline (comment)
|
||||
if(pBegin[0]==0)return(true);
|
||||
|
||||
return(false);
|
||||
}
|
||||
};
|
||||
|
||||
//! constructor
|
||||
CfgFile();
|
||||
|
||||
//! destructor
|
||||
~CfgFile();
|
||||
|
||||
//!
|
||||
void SetFileName( const CString &fileName );
|
||||
|
||||
//! Automatically load new config file.
|
||||
explicit CfgFile( const CString &fileName );
|
||||
|
||||
//! Load config from memory buffer.
|
||||
CfgFile( const char *buf, int bufSize );
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// interface ICfgFile - described in ICfgFile.h
|
||||
|
||||
virtual void Release() { delete(this); }
|
||||
virtual bool Load( const CString &fileName );
|
||||
virtual bool Save( void );
|
||||
virtual void UpdateOrCreateEntry( const char *inszSection, const char *inszKey, const char *inszValue );
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
//! Copy section keys to config.
|
||||
//! @return true if success, false if section not found.
|
||||
bool SetConfig( const char *section, IConfig *config );
|
||||
|
||||
private:
|
||||
|
||||
void LoadBuf( const char *buf,size_t bufSize );
|
||||
|
||||
struct Section
|
||||
{
|
||||
CString name; //!< Section name. (the first one has the name "" and is used if no section was specified)
|
||||
std::list<Entry> entries; //!< List of entries.
|
||||
};
|
||||
|
||||
// Private methods.
|
||||
|
||||
//! @return pointer to the section with the given name or pointer to the first unnamed section ""
|
||||
Section* FindSection( const CString §ion );
|
||||
|
||||
// Private fields.
|
||||
CString m_fileName; //!< Configuration file name.
|
||||
int m_modified; //!< Set to true if config file been modified.
|
||||
|
||||
std::vector<Section> m_sections; //!< List of sections in config file. (the first one has the name "" and is used if no section was specified)
|
||||
|
||||
public:
|
||||
|
||||
const char *GetSectionName(unsigned int n)
|
||||
{
|
||||
if(n>=m_sections.size())
|
||||
return(NULL);
|
||||
|
||||
return(m_sections[n].name.GetString());
|
||||
};
|
||||
|
||||
int Find(const char *sectionname)
|
||||
{
|
||||
for(std::vector<Section>::iterator it = m_sections.begin(); it!=m_sections.end(); ++it)
|
||||
{
|
||||
if (stricmp(it->name.GetString(), sectionname) == 0) return it-m_sections.begin();
|
||||
};
|
||||
return 0;
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
#endif // __cfgfile_h__
|
||||
542
ResourceCompiler/CgfUtils.cpp
Normal file
542
ResourceCompiler/CgfUtils.cpp
Normal file
@@ -0,0 +1,542 @@
|
||||
/////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Crytek Character Animation source code
|
||||
//
|
||||
// History:
|
||||
// Created by Sergiy Migdalskiy
|
||||
//
|
||||
/////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
#include "stdafx.h"
|
||||
#include "StringUtils.h"
|
||||
#include "CgfUtils.h"
|
||||
|
||||
using namespace CryStringUtils;
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// given the chunk, parses it and returns the array of pointers to the strings with the bone names
|
||||
// in the supplied array. Returns true when successful
|
||||
// PARAMETERS:
|
||||
// chunkHeader - the header of the chunk in the chunk table
|
||||
// pChunk - the raw chunk data in the file
|
||||
// nChunkSize - the size of the raw data piece in the file
|
||||
// arrNames - the array that will be resized according to the number of entries, and each element of this array
|
||||
// will be the pointer to the corresponding 0-terminated name string.
|
||||
bool LoadBoneNameList (const CHUNK_HEADER& chunkHeader, const void* pChunk, unsigned nChunkSize, std::vector<const char*>& arrNames)
|
||||
{
|
||||
switch (chunkHeader.ChunkVersion)
|
||||
{
|
||||
case BONENAMELIST_CHUNK_DESC_0744::VERSION:
|
||||
{
|
||||
// the old chunk version - fixed-size name list
|
||||
const BONENAMELIST_CHUNK_DESC_0744* pNameChunk = (const BONENAMELIST_CHUNK_DESC_0744*)(pChunk);
|
||||
|
||||
int nGeomBones = pNameChunk->nEntities;
|
||||
|
||||
// just fill in the pointers to the fixed-size string buffers
|
||||
const NAME_ENTITY* pGeomBoneNameTable = (const NAME_ENTITY*)(pNameChunk+1);
|
||||
if(nGeomBones < 0 || nGeomBones > 0x800)
|
||||
return false;
|
||||
arrNames.resize(nGeomBones);
|
||||
for (int i = 0; i < nGeomBones; ++i)
|
||||
arrNames[i] = pGeomBoneNameTable[i].name;
|
||||
}
|
||||
break;
|
||||
|
||||
case BONENAMELIST_CHUNK_DESC_0745::VERSION:
|
||||
{
|
||||
// the new memory-economizing chunk with variable-length packed strings following tightly each other
|
||||
const BONENAMELIST_CHUNK_DESC_0745* pNameChunk = (const BONENAMELIST_CHUNK_DESC_0745*)(pChunk);
|
||||
int nGeomBones = pNameChunk->numEntities;
|
||||
|
||||
// we know how many strings there are there; the whole bunch of strings may
|
||||
// be followed by pad zeros, to enable alignment
|
||||
arrNames.resize(nGeomBones, "");
|
||||
|
||||
// scan through all the strings, each string following immediately the 0 terminator of the previous one
|
||||
const char* pNameListEnd = ((const char*)pNameChunk) + nChunkSize;
|
||||
const char* pName = (const char*)(pNameChunk+1);
|
||||
int nName = 0;
|
||||
while (*pName && pName < pNameListEnd && nName < nGeomBones)
|
||||
{
|
||||
arrNames[nName] = pName;
|
||||
pName += strnlen(pName, pNameListEnd) + 1;
|
||||
++nName;
|
||||
}
|
||||
if (nName < nGeomBones)
|
||||
{
|
||||
// the chunk is truncated
|
||||
#ifdef _CRY_ANIMATION_BASE_HEADER_
|
||||
// if this is in the engine, log the error
|
||||
g_GetLog()->LogWarning ("\003inconsistent bone name list chunk: only %d out of %d bone names have been read.", nName, nGeomBones);
|
||||
#endif
|
||||
return false;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
|
||||
// Attempts to load the material from the given material chunk to the "me" structure
|
||||
MatChunkLoadErrorEnum LoadMatEntity (const CHUNK_HEADER& chunkHeader, const void* pChunkData, unsigned nChunkSize, MAT_ENTITY& me)
|
||||
{
|
||||
memset(&me, 0, sizeof(MAT_ENTITY));
|
||||
|
||||
switch (chunkHeader.ChunkVersion)
|
||||
{
|
||||
case MTL_CHUNK_DESC_0746::VERSION:
|
||||
{
|
||||
const MTL_CHUNK_DESC_0746* pMatChunk = (const MTL_CHUNK_DESC_0746*)pChunkData;
|
||||
|
||||
me.m_New = 2;
|
||||
strcpy(me.name, pMatChunk->name);
|
||||
switch (pMatChunk->MtlType)
|
||||
{
|
||||
case MTL_STANDARD:
|
||||
{
|
||||
me.IsStdMat = true;
|
||||
me.col_d = pMatChunk->col_d;
|
||||
me.col_a = pMatChunk->col_a;
|
||||
//me.col_a.g=0;
|
||||
//me.col_a.b=0;
|
||||
me.col_s = pMatChunk->col_s;
|
||||
|
||||
me.specLevel = pMatChunk->specLevel;
|
||||
me.specShininess = pMatChunk->specShininess*100;
|
||||
me.opacity = pMatChunk->opacity;
|
||||
me.selfIllum = pMatChunk->selfIllum;
|
||||
me.flags = pMatChunk->flags;
|
||||
|
||||
me.Dyn_Bounce = pMatChunk->Dyn_Bounce;
|
||||
me.Dyn_StaticFriction = pMatChunk->Dyn_StaticFriction;
|
||||
me.Dyn_SlidingFriction = pMatChunk->Dyn_SlidingFriction;
|
||||
/* //Timur[10/24/2001]
|
||||
strcpy(me.map_a, pMatChunk->tex_a.name);
|
||||
strcpy(me.map_d, pMatChunk->tex_d.name);
|
||||
strcpy(me.map_o, pMatChunk->tex_o.name);
|
||||
strcpy(me.map_b, pMatChunk->tex_b.name);
|
||||
strcpy(me.map_s, pMatChunk->tex_s.name);
|
||||
strcpy(me.map_g, pMatChunk->tex_g.name);
|
||||
strcpy(me.map_c, pMatChunk->tex_c.name);
|
||||
strcpy(me.map_e, pMatChunk->tex_rl.name);
|
||||
strcpy(me.map_rr, pMatChunk->tex_rr.name);
|
||||
strcpy(me.map_det, pMatChunk->tex_det.name);
|
||||
*/
|
||||
me.map_a = pMatChunk->tex_a;
|
||||
me.map_d = pMatChunk->tex_d;
|
||||
me.map_o = pMatChunk->tex_o;
|
||||
me.map_b = pMatChunk->tex_b;
|
||||
me.map_s = pMatChunk->tex_s;
|
||||
me.map_g = pMatChunk->tex_g;
|
||||
me.map_detail = pMatChunk->tex_fl;
|
||||
me.map_e = pMatChunk->tex_rl;
|
||||
me.map_subsurf = pMatChunk->tex_subsurf;
|
||||
me.map_displ = pMatChunk->tex_det;
|
||||
|
||||
me.nChildren = pMatChunk->nChildren;
|
||||
|
||||
me.alpharef = pMatChunk->alphaTest;
|
||||
}
|
||||
return MCLE_Success;
|
||||
|
||||
default:
|
||||
return MCLE_IgnoredType;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case MTL_CHUNK_DESC_0745::VERSION:
|
||||
{
|
||||
const MTL_CHUNK_DESC_0745* pMatChunk = (const MTL_CHUNK_DESC_0745*)pChunkData;
|
||||
|
||||
me.m_New = 1;
|
||||
strcpy(me.name, pMatChunk->name);
|
||||
switch (pMatChunk->MtlType)
|
||||
{
|
||||
case MTL_STANDARD:
|
||||
me.IsStdMat = true;
|
||||
me.col_d = pMatChunk->col_d;
|
||||
me.col_a = pMatChunk->col_a;
|
||||
//me.col_a.g=0;
|
||||
//me.col_a.b=0;
|
||||
me.col_s = pMatChunk->col_s;
|
||||
|
||||
me.specLevel = pMatChunk->specLevel;
|
||||
me.specShininess = pMatChunk->specShininess*100;
|
||||
me.opacity = pMatChunk->opacity;
|
||||
me.selfIllum = pMatChunk->selfIllum;
|
||||
me.flags = pMatChunk->flags;
|
||||
|
||||
me.Dyn_Bounce = pMatChunk->Dyn_Bounce;
|
||||
me.Dyn_StaticFriction = pMatChunk->Dyn_StaticFriction;
|
||||
me.Dyn_SlidingFriction = pMatChunk->Dyn_SlidingFriction;
|
||||
me.map_a = pMatChunk->tex_a;
|
||||
me.map_d = pMatChunk->tex_d;
|
||||
me.map_o = pMatChunk->tex_o;
|
||||
me.map_b = pMatChunk->tex_b;
|
||||
me.map_s = pMatChunk->tex_s;
|
||||
me.map_g = pMatChunk->tex_g;
|
||||
me.map_detail = pMatChunk->tex_c;
|
||||
me.map_e = pMatChunk->tex_rl;
|
||||
me.map_subsurf = pMatChunk->tex_subsurf;
|
||||
me.map_displ = pMatChunk->tex_det;
|
||||
|
||||
me.nChildren = pMatChunk->nChildren;
|
||||
|
||||
return MCLE_Success;
|
||||
|
||||
default:
|
||||
return MCLE_IgnoredType;
|
||||
}
|
||||
}
|
||||
break;
|
||||
default:
|
||||
return MCLE_UnknownVersion;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// if the given string is null, assigns the "" to the pointer
|
||||
void chkNullString (const char*&pszString)
|
||||
{
|
||||
if (!pszString)
|
||||
pszString = "";
|
||||
}
|
||||
|
||||
static void rtrim (char* szString)
|
||||
{
|
||||
for (char* p = szString + strlen (szString) - 1; p >= szString && isspace(*p); --p)
|
||||
*p = '\0';
|
||||
}
|
||||
|
||||
static void ltrim (const char*& szString)
|
||||
{
|
||||
while (*szString && isspace(*szString))
|
||||
++szString;
|
||||
}
|
||||
|
||||
|
||||
CMatEntityNameTokenizer::CMatEntityNameTokenizer ():
|
||||
m_szMtlName (NULL),
|
||||
szName (""),
|
||||
szTemplate (""),
|
||||
szPhysMtl (""),
|
||||
nSortValue (0),
|
||||
bInvert (false)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
void CMatEntityNameTokenizer::tokenize (const char* szMtlFullName)
|
||||
{
|
||||
if (m_szMtlName)
|
||||
{
|
||||
free (m_szMtlName);
|
||||
m_szMtlName = NULL;
|
||||
}
|
||||
if (!szMtlFullName)
|
||||
return;
|
||||
|
||||
int nLen = (int)strlen(szMtlFullName);
|
||||
m_szMtlName = (char*)malloc (nLen+1);
|
||||
memcpy (m_szMtlName, szMtlFullName, nLen + 1);
|
||||
|
||||
szName = NULL;
|
||||
szTemplate = NULL;
|
||||
szPhysMtl = NULL;
|
||||
nSortValue = 0;
|
||||
bInvert = false;
|
||||
|
||||
// the state machine will parse the whole string
|
||||
enum StateEnum
|
||||
{
|
||||
kUnknown,
|
||||
kName,
|
||||
kTemplate,
|
||||
kPhysMtl,
|
||||
kIndex
|
||||
};
|
||||
|
||||
StateEnum nState = kName; // by default, the string begins with name
|
||||
this->szName = m_szMtlName;
|
||||
|
||||
for (char* p = m_szMtlName; *p; ++p)
|
||||
{
|
||||
switch (*p)
|
||||
{
|
||||
case '(': // template name begins
|
||||
this->szTemplate = p+1;
|
||||
nState = kTemplate;
|
||||
*p = '\0';
|
||||
break;
|
||||
|
||||
case '[': // render priority number begins
|
||||
*p = '\0';
|
||||
nState = kIndex;
|
||||
break;
|
||||
|
||||
case '/':
|
||||
this->szPhysMtl = p+1;
|
||||
*p = '\0';
|
||||
nState = kPhysMtl;
|
||||
break;
|
||||
|
||||
default:
|
||||
switch (nState)
|
||||
{
|
||||
case kName:
|
||||
switch (*p)
|
||||
{
|
||||
/*case ' ': // there are no spaces in the name
|
||||
*p = '\0';
|
||||
break;*/
|
||||
|
||||
case ')':
|
||||
case ']':
|
||||
#ifdef _CRY_ANIMATION_BASE_HEADER_
|
||||
g_GetLog()->LogError ("Invalid material name (unexpected closing bracket) \"%s\"", szMtlFullName);
|
||||
#endif
|
||||
break;
|
||||
};
|
||||
break;
|
||||
|
||||
case kTemplate:
|
||||
switch (*p)
|
||||
{
|
||||
case ')':
|
||||
nState = kUnknown;
|
||||
*p = '\0';
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
case kIndex:
|
||||
{
|
||||
switch (*p)
|
||||
{
|
||||
case ']':
|
||||
nState = kUnknown;
|
||||
break;
|
||||
|
||||
case ' ':
|
||||
break;
|
||||
|
||||
case '0':
|
||||
case '1':
|
||||
case '2':
|
||||
case '3':
|
||||
case '4':
|
||||
case '5':
|
||||
case '6':
|
||||
case '7':
|
||||
case '8':
|
||||
case '9':
|
||||
this->nSortValue *= 10;
|
||||
this->nSortValue += *p - '0';
|
||||
break;
|
||||
|
||||
default:
|
||||
nState = kUnknown;
|
||||
#ifdef _CRY_ANIMATION_BASE_HEADER_
|
||||
g_GetLog()->LogError ("Invalid material name (unexpected symbol in index field) \"%s\"", szMtlFullName);
|
||||
#endif
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
};
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// take into account hte old form $s_... of setting the template name
|
||||
// if there was no () template, then use this one (after _)
|
||||
if ((!this->szTemplate || !this->szTemplate[0]) &&
|
||||
this->szName[0] == '$' && tolower(this->szName[1]) == 's' && this->szName[2] == '_')
|
||||
{
|
||||
this->szTemplate = this->szName + 3;
|
||||
}
|
||||
|
||||
// make sure all the strings get their pointers - if there's no name, then it will be an empty name
|
||||
chkNullString(this->szName);
|
||||
chkNullString(this->szTemplate);
|
||||
chkNullString(this->szPhysMtl);
|
||||
|
||||
// a special case (one more) - template name preceded by # means (or meant) the inverted template
|
||||
if (this->szTemplate[0] == '#')
|
||||
{
|
||||
this->szTemplate++;
|
||||
this->bInvert = true;
|
||||
}
|
||||
|
||||
// trim unneeded left and right leading spaces
|
||||
rtrim ((char*)this->szName);
|
||||
rtrim ((char*)this->szTemplate);
|
||||
rtrim ((char*)this->szPhysMtl);
|
||||
|
||||
ltrim (this->szName);
|
||||
ltrim (this->szTemplate);
|
||||
ltrim (this->szPhysMtl);
|
||||
}
|
||||
|
||||
CMatEntityNameTokenizer::~CMatEntityNameTokenizer ()
|
||||
{
|
||||
if (m_szMtlName)
|
||||
free (m_szMtlName);
|
||||
}
|
||||
|
||||
// operator that sorts the materials for rendering
|
||||
bool CMatEntityNameTokenizer::operator < (const CMatEntityNameTokenizer& right)const
|
||||
{
|
||||
if (this->nSortValue < right.nSortValue)
|
||||
return true;
|
||||
|
||||
if (this->nSortValue > right.nSortValue)
|
||||
return false;
|
||||
|
||||
int nComp = stricmp (this->szTemplate, right.szTemplate);
|
||||
|
||||
if (nComp < 0)
|
||||
return true;
|
||||
if (nComp > 0)
|
||||
return false;
|
||||
|
||||
nComp = stricmp (this->szName, right.szName);
|
||||
|
||||
if (nComp < 0)
|
||||
return true;
|
||||
if (nComp > 0)
|
||||
return false;
|
||||
|
||||
return false; // they're equal
|
||||
}
|
||||
|
||||
// given the in-permutation, constructs the inverse out-permutation, so that:
|
||||
// pOut[pIn[i]] == i
|
||||
// pIn[pOut[i]] == i
|
||||
void ConstructReversePermutation (const unsigned* pIn, unsigned* pOut, unsigned num)
|
||||
{
|
||||
unsigned i;
|
||||
#ifdef _DEBUG
|
||||
// we'll check the correctness of permutation by checking if there are duplicate entries in pIn
|
||||
// if there are no duplicate entries, according to Dirichle principle, there are no missed entries in pOut
|
||||
for (i = 0; i < num; ++i)
|
||||
pOut[i] = (unsigned)-1;
|
||||
#endif
|
||||
|
||||
for (i = 0; i < num; ++i)
|
||||
{
|
||||
assert (pIn[i] < num);
|
||||
assert ((int)pOut[pIn[i]] ==(unsigned)-1);
|
||||
pOut[pIn[i]] = i;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// Remaps the materials according to the given permutation
|
||||
// the permutation is perm[new index] == old index
|
||||
void RemapMatEntities (MAT_ENTITY* pMtls, unsigned numMtls, unsigned* pPerm)
|
||||
{
|
||||
MAT_ENTITY* pOldMtls = new MAT_ENTITY[numMtls];
|
||||
memcpy (pOldMtls, pMtls, sizeof(MAT_ENTITY)*numMtls);
|
||||
|
||||
for (unsigned nNewMtl = 0; nNewMtl < numMtls; ++nNewMtl)
|
||||
memcpy (pMtls + nNewMtl, pOldMtls + pPerm[nNewMtl], sizeof(MAT_ENTITY));
|
||||
|
||||
delete[]pOldMtls;
|
||||
}
|
||||
|
||||
// copies the matrix from SBoneInitPosMatrix to Matrix
|
||||
void copyMatrix (Matrix44& matDst, const SBoneInitPosMatrix& matSrc)
|
||||
{
|
||||
for (unsigned i = 0; i < 4; ++i)
|
||||
{
|
||||
matDst(i,0) = matSrc[i][0];
|
||||
matDst(i,1) = matSrc[i][1];
|
||||
matDst(i,2) = matSrc[i][2];
|
||||
}
|
||||
matDst(0,3) = 0;
|
||||
matDst(1,3) = 0;
|
||||
matDst(2,3) = 0;
|
||||
matDst(3,3) = 1;
|
||||
}
|
||||
|
||||
const char* getMtlType (unsigned nMtlType)
|
||||
{
|
||||
switch (nMtlType)
|
||||
{
|
||||
case MTL_UNKNOWN:
|
||||
return "UNKNOWN";
|
||||
case MTL_STANDARD:
|
||||
return "STANDARD";
|
||||
case MTL_MULTI:
|
||||
return "MULTI";
|
||||
case MTL_2SIDED:
|
||||
return "2SIDED";
|
||||
default:
|
||||
return "#Unknown#";
|
||||
}
|
||||
}
|
||||
|
||||
const char* getTexType (unsigned char nTexType)
|
||||
{
|
||||
switch (nTexType)
|
||||
{
|
||||
case TEXMAP_AUTOCUBIC:
|
||||
return "TEXMAP_AUTOCUBIC";
|
||||
case TEXMAP_CUBIC:
|
||||
return "TEXMAP_CUBIC";
|
||||
case TEXMAP_ENVIRONMENT:
|
||||
return "TEXMAP_ENVIRONMENT";
|
||||
case TEXMAP_SCREENENVIRONMENT:
|
||||
return "!TEXMAP_SCREENENVIRONMENT(unsupported)!";
|
||||
default:
|
||||
return "#Unknown#";
|
||||
}
|
||||
}
|
||||
|
||||
string getLightType (LightTypes nType)
|
||||
{
|
||||
switch (nType)
|
||||
{
|
||||
case LT_OMNI:
|
||||
return "Omni";
|
||||
case LT_SPOT:
|
||||
return "Spot";
|
||||
case LT_DIRECT:
|
||||
return "Direct";
|
||||
case LT_AMBIENT:
|
||||
return "Ambient";
|
||||
default:
|
||||
{
|
||||
char szBuffer[32];
|
||||
printf (szBuffer, "Unknown(%d)", nType);
|
||||
return szBuffer;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
string getMtlFlags (int nFlags)
|
||||
{
|
||||
string strResult;
|
||||
if (nFlags & MTLFLAG_WIRE)
|
||||
strResult += "MTLFLAG_WIRE|";
|
||||
if (nFlags & MTLFLAG_2SIDED)
|
||||
strResult += "MTLFLAG_2SIDED|";
|
||||
if (nFlags & MTLFLAG_FACEMAP)
|
||||
strResult += "MTLFLAG_FACEMAP|";
|
||||
if (nFlags & MTLFLAG_FACETED)
|
||||
strResult += "MTLFLAG_FACETED|";
|
||||
if (nFlags & MTLFLAG_ADDITIVE)
|
||||
strResult += "MTLFLAG_ADDITIVE|";
|
||||
if (nFlags & MTLFLAG_SUBTRACTIVE)
|
||||
strResult += "MTLFLAG_SUBTRACTIVE|";
|
||||
|
||||
if (!strResult.empty ())
|
||||
strResult.resize (strResult.length ()-1);
|
||||
|
||||
return strResult;
|
||||
}
|
||||
183
ResourceCompiler/CgfUtils.h
Normal file
183
ResourceCompiler/CgfUtils.h
Normal file
@@ -0,0 +1,183 @@
|
||||
/////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Crytek Character Animation source code
|
||||
//
|
||||
// History:
|
||||
// Created by Sergiy Migdalskiy
|
||||
//
|
||||
/////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
#ifndef _CGF_UTILS_HDR_
|
||||
#define _CGF_UTILS_HDR_
|
||||
|
||||
// prerequisities
|
||||
//#include <CryHeaders.h>
|
||||
//#include <StlDbgAlloc.h>
|
||||
|
||||
#ifndef M_PI
|
||||
#define M_PI 3.1415926535897932384626433832795
|
||||
#endif
|
||||
|
||||
// given the chunk, parses it and returns the array of pointers to the strings with the bone names
|
||||
// in the supplied array. Returns true when successful
|
||||
extern bool LoadBoneNameList (const CHUNK_HEADER& chunkHeader, const void* pChunk, unsigned nChunkSize, std::vector<const char*>& arrNames);
|
||||
|
||||
|
||||
|
||||
enum MatChunkLoadErrorEnum
|
||||
{
|
||||
MCLE_Success,
|
||||
MCLE_Truncated,
|
||||
MCLE_UnknownVersion,
|
||||
MCLE_IgnoredType // this material type should be ignored (multimaterial)
|
||||
};
|
||||
|
||||
|
||||
// Attempts to load the material from the given material chunk to the "me" structure
|
||||
extern MatChunkLoadErrorEnum LoadMatEntity (const CHUNK_HEADER& chunkHeader, const void* pChunkData, unsigned nChunkSize, MAT_ENTITY& me);
|
||||
|
||||
// material name parser.
|
||||
// In the CGF, the material has to have a complex name:
|
||||
// name_spec template_spec phys_mat_spec render_index_spec
|
||||
//
|
||||
// name_spec:
|
||||
// $s_* -- * means the template name; in this case, material name remains $s_*
|
||||
// * -- * means just the material name
|
||||
//
|
||||
// template_spec: -- not necessary
|
||||
// (*) -- * means the template; closing bracket may be absent
|
||||
//
|
||||
// phys_mat_spec: -- not necessary
|
||||
// /name
|
||||
//
|
||||
// render_index_spec: -- not necessary
|
||||
// [id]
|
||||
class CMatEntityNameTokenizer {
|
||||
|
||||
public:
|
||||
CMatEntityNameTokenizer ();
|
||||
~CMatEntityNameTokenizer ();
|
||||
|
||||
void tokenize(const char* szName);
|
||||
|
||||
// material name
|
||||
const char *szName;
|
||||
|
||||
// template name (NULL if no template)
|
||||
const char *szTemplate;
|
||||
|
||||
// physic material name
|
||||
const char *szPhysMtl;
|
||||
|
||||
// render index (0 if not specified)
|
||||
int nSortValue;
|
||||
|
||||
// true, if the template is to be inverted.. (# before the template name
|
||||
bool bInvert;
|
||||
|
||||
// operator that sorts the materials for rendering
|
||||
bool operator < (const CMatEntityNameTokenizer& right)const;
|
||||
protected:
|
||||
char* m_szMtlName;
|
||||
};
|
||||
|
||||
// this is sorting predicate that helps form a mapping of old-new mat ids
|
||||
// it's given an array of tokenizers to index into
|
||||
class CMatEntityIndexSort
|
||||
{
|
||||
public:
|
||||
// accepts the array of initialized tokenizers and their number
|
||||
CMatEntityIndexSort (const CMatEntityNameTokenizer* pTokenizers, unsigned numSize):
|
||||
m_pTokenizers (pTokenizers),
|
||||
m_numSize (numSize)
|
||||
{
|
||||
}
|
||||
|
||||
bool operator () (unsigned nLeft, unsigned nRight) const
|
||||
{
|
||||
assert (nLeft >= 0 && nLeft < m_numSize);
|
||||
assert (nRight >= 0 && nRight < m_numSize);
|
||||
return m_pTokenizers[nLeft ]<m_pTokenizers[nRight];
|
||||
}
|
||||
|
||||
protected:
|
||||
const CMatEntityNameTokenizer* m_pTokenizers;
|
||||
unsigned m_numSize;
|
||||
};
|
||||
|
||||
// given the in-permutation, constructs the inverse out-permutation, so that:
|
||||
// pOut[pIn[i]] == i
|
||||
// pIn[pOut[i]] == i
|
||||
void ConstructReversePermutation (const unsigned* pIn, unsigned* pOut, unsigned num);
|
||||
|
||||
// Remaps the materials according to the given permutation
|
||||
// the permutation is perm[new index] == old index
|
||||
void RemapMatEntities (MAT_ENTITY* pMtls, unsigned numMtls, unsigned* pPerm);
|
||||
|
||||
// copies the matrix from SBoneInitPosMatrix to Matrix
|
||||
extern void copyMatrix (Matrix44& matDst, const SBoneInitPosMatrix& matSrc);
|
||||
|
||||
struct SBasisProperties
|
||||
{
|
||||
#ifdef _LEAFBUFFER_H_
|
||||
SBasisProperties (const TangData& td)
|
||||
{
|
||||
init (td.tangent, td.binormal, td.tnormal);
|
||||
}
|
||||
#endif
|
||||
|
||||
SBasisProperties(const Vec3& vX, const Vec3& vY, const Vec3& vZ)
|
||||
{
|
||||
init (vX,vY,vZ);
|
||||
}
|
||||
|
||||
static double maxCosToErrorDeg(double f)
|
||||
{
|
||||
return 90 - fabs(acos(f)*180/M_PI);
|
||||
}
|
||||
|
||||
void init (const Vec3& vX, const Vec3& vY, const Vec3& vZ)
|
||||
{
|
||||
bMatrixDegraded = false;
|
||||
bLeftHanded = false;
|
||||
fErrorDeg = 0;
|
||||
// max of cosine between two vectors
|
||||
double fMaxCos = 0;
|
||||
float fXLength = vX.Length(), fYLength = vY.Length(), fZLength = vZ.Length();
|
||||
|
||||
if (fXLength < 1e-3 || fYLength < 1e-3 || fZLength < 1e-3)
|
||||
bMatrixDegraded = true;
|
||||
else
|
||||
{
|
||||
double fMaxCosXY = fabs(vX*vY)/(fXLength*fYLength);
|
||||
fMaxCos = max (fMaxCos, fMaxCosXY);
|
||||
double fMaxCosXZ = fabs(vX*vZ)/(fXLength*fZLength);
|
||||
fMaxCos = max (fMaxCos, fMaxCosXZ);
|
||||
double fMaxCosYZ = fabs(vY*vZ)/(fYLength*fZLength);
|
||||
fMaxCos = max (fMaxCos, fMaxCosYZ);
|
||||
|
||||
fErrorDeg = maxCosToErrorDeg(fMaxCos);
|
||||
fErrorDegTB = (float)maxCosToErrorDeg(fMaxCosXY);
|
||||
fErrorDegTN = (float)maxCosToErrorDeg(fMaxCosXZ);
|
||||
fErrorDegBN = (float)maxCosToErrorDeg(fMaxCosYZ);
|
||||
|
||||
bLeftHanded = (vX^vY)*vZ < 0;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
double fErrorDeg;
|
||||
// the error degrees between the tangent, binormal and normal by pair
|
||||
float fErrorDegTB, fErrorDegTN, fErrorDegBN;
|
||||
bool bMatrixDegraded;
|
||||
bool bLeftHanded;
|
||||
|
||||
bool isOrthogonal () const {return fErrorDeg < 0.5;}
|
||||
double getLeftHandednessPercentage () const {return (100-fErrorDeg*100/90);}
|
||||
};
|
||||
|
||||
extern const char* getMtlType (unsigned nMtlType);
|
||||
extern const char* getTexType (unsigned char nTexType);
|
||||
extern string getLightType (LightTypes nType);
|
||||
extern string getMtlFlags (int nFlags);
|
||||
|
||||
#endif
|
||||
205
ResourceCompiler/ChunkFileReader.cpp
Normal file
205
ResourceCompiler/ChunkFileReader.cpp
Normal file
@@ -0,0 +1,205 @@
|
||||
#include "StdAfx.h"
|
||||
#include "FileMapping.h"
|
||||
#include "chunkfilereader.h"
|
||||
|
||||
#ifdef _DEBUG
|
||||
#undef THIS_FILE
|
||||
static char THIS_FILE[] = __FILE__;
|
||||
#endif
|
||||
|
||||
const char* CChunkFileReader::gLastError = "";
|
||||
|
||||
CChunkFileReader::CChunkFileReader():
|
||||
m_pChunks(NULL)
|
||||
//,m_arrChunkSize ("CChunkFileReader.ChunkSize")
|
||||
{
|
||||
}
|
||||
|
||||
CChunkFileReader::~CChunkFileReader()
|
||||
{
|
||||
close();
|
||||
}
|
||||
|
||||
bool CChunkFileReader::open (const string& strFileName, unsigned nFlags)
|
||||
{
|
||||
return open (strFileName.c_str(), nFlags);
|
||||
}
|
||||
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// attaches the file mapping object to this file reader and checks
|
||||
// whether the file is a valid chunked file
|
||||
bool CChunkFileReader::open(CFileMapping* pFile)
|
||||
{
|
||||
close();
|
||||
m_pFile = pFile;
|
||||
|
||||
bool bSuccess = false;
|
||||
|
||||
if ( (m_pFile != (CFileMapping*)NULL) && (m_pFile->getData() != NULL) )
|
||||
{
|
||||
if (m_pFile->getSize() >= sizeof(FileHeader))
|
||||
{// the file must contain the header
|
||||
const FileHeader& fileHeader = getFileHeader();
|
||||
if (m_pFile->getSize() >= fileHeader.ChunkTableOffset + sizeof(int)
|
||||
&& (int)fileHeader.ChunkTableOffset > (int)sizeof(fileHeader)
|
||||
)
|
||||
{// there must be room for the chunk table header
|
||||
unsigned numChunks = *static_cast<const unsigned*>(m_pFile->getData(fileHeader.ChunkTableOffset));
|
||||
unsigned nChunk;
|
||||
if (m_pFile->getSize() >= fileHeader.ChunkTableOffset + sizeof(int) + numChunks*sizeof(ChunkHeader)
|
||||
&& numChunks <= (pFile->getSize () - fileHeader.ChunkTableOffset - sizeof(int)) / sizeof(ChunkHeader))
|
||||
{
|
||||
// the file must contain the full chunk table
|
||||
m_pChunks = (const ChunkHeader*)m_pFile->getData(fileHeader.ChunkTableOffset + sizeof(int));
|
||||
|
||||
bool bInvalidChunkOffsetsFound = false; // sets to true if there are chunks pointing outside the raw data section of the file
|
||||
|
||||
// step through all the chunks to fetch file offsets
|
||||
std::set<int> setOffsets;
|
||||
for (nChunk = 0; nChunk < numChunks; ++nChunk)
|
||||
{
|
||||
int nOffset = m_pChunks[nChunk].FileOffset;
|
||||
|
||||
if (nOffset < sizeof(FileHeader) || nOffset >= fileHeader.ChunkTableOffset)
|
||||
{
|
||||
gLastError = "CryFile is corrupted: chunk table is corrupted (invalid chunk offsets found)";
|
||||
bInvalidChunkOffsetsFound = true;
|
||||
}
|
||||
|
||||
setOffsets.insert(nOffset);
|
||||
}
|
||||
m_arrChunkSize.clear();
|
||||
m_arrChunkSize.resize (numChunks);
|
||||
for (nChunk = 0; nChunk < numChunks; ++nChunk)
|
||||
{
|
||||
int nOffset = m_pChunks[nChunk].FileOffset;
|
||||
int nSize = 0; // the size for invalid chunks (with invalid offsets)
|
||||
if (nOffset >= sizeof(FileHeader) && nOffset < fileHeader.ChunkTableOffset)
|
||||
{
|
||||
// find the next offset
|
||||
std::set<int>::const_iterator it = setOffsets.find (nOffset);
|
||||
assert (it != setOffsets.end());
|
||||
assert (*it == nOffset);
|
||||
++it;
|
||||
nSize = (it==setOffsets.end()?fileHeader.ChunkTableOffset:*it) - nOffset;
|
||||
}
|
||||
|
||||
assert (nSize >= 0);
|
||||
m_arrChunkSize[nChunk] = nSize;
|
||||
}
|
||||
|
||||
bSuccess = true;
|
||||
// don't let the files with invalid chunks..
|
||||
//bSuccess = !bInvalidChunkOffsetsFound;
|
||||
}
|
||||
else
|
||||
gLastError = "CryFile is corrupted: chunk table is corrupted or truncated (file too small)";
|
||||
}
|
||||
else
|
||||
gLastError = "CryFile is corrupted: chunk table is trucated (file header is probably corrupted)";
|
||||
}
|
||||
else
|
||||
gLastError = "CryFile is corrupted: header is truncated (file too small)";
|
||||
}
|
||||
else
|
||||
gLastError = "Invalid file mapping passed to CChunkFileReader::open";
|
||||
|
||||
|
||||
if (!bSuccess)
|
||||
close();
|
||||
|
||||
return bSuccess;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// attaches a new file mapping object to this file reader and checks
|
||||
// whether the file is a valid chunked file
|
||||
bool CChunkFileReader::open(const char* szFileName, unsigned nFlags)
|
||||
{
|
||||
CFileMapping_AutoPtr pFileMapping = new CFileMapping(szFileName, nFlags);
|
||||
if (!pFileMapping->getData())
|
||||
{
|
||||
gLastError = "Cannot open file";
|
||||
return false;
|
||||
}
|
||||
return open (pFileMapping);
|
||||
}
|
||||
|
||||
void CChunkFileReader::close()
|
||||
{
|
||||
m_arrChunkSize.clear();
|
||||
m_pFile = NULL;
|
||||
m_pChunks = NULL;
|
||||
}
|
||||
|
||||
// returns the raw data of the file from the given offset
|
||||
const void* CChunkFileReader::getRawData(unsigned nOffset)const
|
||||
{
|
||||
if ((m_pFile != (CFileMapping*)NULL) && m_pFile->getData())
|
||||
return ((char*)m_pFile->getData())+nOffset;
|
||||
else
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// retrieves the raw chunk header, as it appears in the file
|
||||
const CChunkFileReader::ChunkHeader& CChunkFileReader::getChunkHeader(int nChunkIdx)const
|
||||
{
|
||||
return m_pChunks[nChunkIdx];
|
||||
}
|
||||
|
||||
|
||||
// returns the raw data of the i-th chunk
|
||||
const void* CChunkFileReader::getChunkData(int nChunkIdx)const
|
||||
{
|
||||
if (nChunkIdx>= 0 && nChunkIdx < numChunks())
|
||||
{
|
||||
int nOffset = m_pChunks[nChunkIdx].FileOffset;
|
||||
if (nOffset < sizeof(FileHeader) || nOffset >= getFileHeader().ChunkTableOffset)
|
||||
return 0;
|
||||
else
|
||||
return m_pFile->getData(nOffset);
|
||||
}
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
||||
// number of chunks
|
||||
int CChunkFileReader::numChunks()const
|
||||
{
|
||||
return (int)m_arrChunkSize.size();
|
||||
}
|
||||
|
||||
// number of chunks of the specified type
|
||||
int CChunkFileReader::numChunksOfType (ChunkTypes nChunkType)const
|
||||
{
|
||||
int nResult = 0;
|
||||
for (int i = 0; i < numChunks(); ++i)
|
||||
{
|
||||
if (m_pChunks[i].ChunkType == nChunkType)
|
||||
++nResult;
|
||||
}
|
||||
return nResult;
|
||||
}
|
||||
|
||||
|
||||
// returns the file headers
|
||||
const CChunkFileReader::FileHeader& CChunkFileReader::getFileHeader() const
|
||||
{
|
||||
return m_pFile?*((const FileHeader*)(m_pFile->getData())):*(const FileHeader*)NULL;
|
||||
}
|
||||
|
||||
bool CChunkFileReader::isValid () const
|
||||
{
|
||||
return m_pFile != (CFileMapping*)NULL;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// calculates the chunk size, based on the very next chunk with greater offset
|
||||
// or the end of the raw data portion of the file
|
||||
int CChunkFileReader::getChunkSize(int nChunkIdx) const
|
||||
{
|
||||
assert (nChunkIdx >= 0 && nChunkIdx < numChunks());
|
||||
return m_arrChunkSize[nChunkIdx];
|
||||
}
|
||||
|
||||
186
ResourceCompiler/ChunkFileReader.h
Normal file
186
ResourceCompiler/ChunkFileReader.h
Normal file
@@ -0,0 +1,186 @@
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// CryEngine Source code
|
||||
//
|
||||
// File:ChunkFileReader.h
|
||||
// Declaration of class CChunkFileReader
|
||||
//
|
||||
// History:
|
||||
// 06/26/2002 :Created by Sergiy Migdalskiy <sergiy@crytek.de>
|
||||
//
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
#ifndef _CHUNK_FILE_READER_HDR_
|
||||
#define _CHUNK_FILE_READER_HDR_
|
||||
|
||||
#include "CryHeaders.h"
|
||||
#include "smartptr.h"
|
||||
|
||||
class CFileMapping;
|
||||
TYPEDEF_AUTOPTR(CFileMapping);
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
// Chunk file reader.
|
||||
// Accesses a chunked file structure through file mapping object.
|
||||
// Opens a chunk file and checks for its validity.
|
||||
// If it's invalid, closes it as if there was no open operation.
|
||||
// Error handling is performed through the return value of open: it must
|
||||
// be true for successfully open files
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
class CChunkFileReader:
|
||||
public _reference_target_t
|
||||
{
|
||||
public:
|
||||
typedef FILE_HEADER FileHeader;
|
||||
typedef CHUNK_HEADER ChunkHeader;
|
||||
|
||||
CChunkFileReader();
|
||||
~CChunkFileReader();
|
||||
|
||||
// attaches the file mapping object to this file reader and checks
|
||||
// whether the file is a valid chunked file
|
||||
bool open(CFileMapping* pFile);
|
||||
|
||||
// attaches a new file mapping object to this file reader and checks
|
||||
// whether the file is a valid chunked file
|
||||
bool open(const char* szFileName, unsigned nFlags = 0);
|
||||
|
||||
bool open (const string& strFileName, unsigned nFlags = 0);
|
||||
|
||||
// closes the file mapping object and thus detaches the file from this reader
|
||||
void close();
|
||||
|
||||
// returns the raw data of the file from the given offset
|
||||
const void* getRawData(unsigned nOffset)const;
|
||||
|
||||
// returns the raw data of the i-th chunk
|
||||
const void* getChunkData(int nChunkIdx)const;
|
||||
|
||||
// retrieves the raw chunk header, as it appears in the file
|
||||
const ChunkHeader& getChunkHeader(int nChunkIdx)const;
|
||||
|
||||
// calculates the chunk size, based on the very next chunk with greater offset
|
||||
// or the end of the raw data portion of the file
|
||||
int getChunkSize(int nChunkIdx) const;
|
||||
|
||||
// number of chunks
|
||||
int numChunks()const;
|
||||
|
||||
// number of chunks of the specified type
|
||||
int numChunksOfType (ChunkTypes nChunkType) const;
|
||||
|
||||
// returns the file headers
|
||||
const FileHeader& getFileHeader() const;
|
||||
|
||||
bool isValid () const;
|
||||
|
||||
const char* getLastError()const {return gLastError;}
|
||||
protected:
|
||||
// this variable contains the last error occured in this class
|
||||
static const char* gLastError;
|
||||
|
||||
CFileMapping_AutoPtr m_pFile;
|
||||
// array of offsets used by the chunks
|
||||
typedef std::vector<int> ChunkSizeArray;
|
||||
ChunkSizeArray m_arrChunkSize;
|
||||
// pointer to the array of chunks in the m_pFile
|
||||
const ChunkHeader* m_pChunks;
|
||||
};
|
||||
|
||||
TYPEDEF_AUTOPTR(CChunkFileReader);
|
||||
|
||||
// this function eats the given number of elements from the raw data pointer pRawData
|
||||
// and increments the pRawData to point to the end of data just eaten
|
||||
template <typename T>
|
||||
void EatRawData (T*pArray, unsigned nSize, const void*&pRawData)
|
||||
{
|
||||
memcpy (pArray, pRawData, sizeof(T)*nSize);
|
||||
pRawData = static_cast<const T*>(pRawData) + nSize;
|
||||
}
|
||||
|
||||
// this function eats the given number of elements from the raw data pointer pRawData
|
||||
// and increments the pRawData to point to the end of data just eaten
|
||||
// RETURNS:
|
||||
// false if failed to read the data
|
||||
template <typename T>
|
||||
bool EatRawData (T*pArray, unsigned nSize, const void*&pRawData, unsigned& nDataSize)
|
||||
{
|
||||
if (sizeof(T)*nSize <= nDataSize)
|
||||
{
|
||||
memcpy (pArray, pRawData, sizeof(T)*nSize);
|
||||
pRawData = static_cast <const T*> (pRawData) + nSize;
|
||||
nDataSize -= sizeof(T)*nSize;
|
||||
return true;
|
||||
}
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
bool EatRawData (T*pArray, unsigned nSize, const void*&pRawData, const void* pRawDataEnd)
|
||||
{
|
||||
if ((const char*)pRawData + sizeof(T)*nSize <= (const char*)pRawDataEnd)
|
||||
{
|
||||
memcpy (pArray, pRawData, sizeof(T)*nSize);
|
||||
pRawData = static_cast <const T*> (pRawData) + nSize;
|
||||
return true;
|
||||
}
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
// this function puts the pointer to the data to the given pointer, and moves
|
||||
// the raw data pointer further; if fails, nothing happens and false is returned
|
||||
// PARAMETERS:
|
||||
// pArray - reference to the (pointer) variable to which the pointer to the actual data will be stored
|
||||
// nSize - number of elements in the array (depending on this, the raw data pointer will be moved)
|
||||
// pRawData - reference to the actual raw data pointer, this will be incremented
|
||||
// nDataSize - reference to the data size counter, this will be decremented upon success
|
||||
// RETURNS:
|
||||
// false if failed to read the data
|
||||
template <typename T>
|
||||
bool EatRawDataPtr(const T*&pArray, unsigned nSize, const void*&pRawData, unsigned& nDataSize)
|
||||
{
|
||||
if (sizeof(T)*nSize <= nDataSize)
|
||||
{
|
||||
pArray = (const T*)pRawData;
|
||||
pRawData = static_cast <const T*> (pRawData) + nSize;
|
||||
nDataSize -= sizeof(T)*nSize;
|
||||
return true;
|
||||
}
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
bool EatRawDataPtr(const T*&pArray, unsigned nSize, const void*&pRawData, const void* pRawDataEnd)
|
||||
{
|
||||
if ((const char*)pRawData + sizeof(T)*nSize <= (const char*)pRawDataEnd)
|
||||
{
|
||||
pArray = (const T*)pRawData;
|
||||
pRawData = static_cast <const T*> (pRawData) + nSize;
|
||||
return true;
|
||||
}
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
// ... non-const version, this will hardly be ever needed
|
||||
/*
|
||||
template <typename T>
|
||||
bool EatRawDataPtr(T*&pArray, unsigned nSize, void*&pRawData, unsigned& nDataSize)
|
||||
{
|
||||
if (sizeof(T)*nSize <= nDataSize)
|
||||
{
|
||||
pArray = (const T*)pRawData;
|
||||
pRawData = static_cast <const T*> (pRawData) + nSize;
|
||||
nDataSize -= sizeof(T)*nSize;
|
||||
return true;
|
||||
}
|
||||
else
|
||||
return false;
|
||||
}
|
||||
*/
|
||||
|
||||
#endif
|
||||
79
ResourceCompiler/CmdLine.cpp
Normal file
79
ResourceCompiler/CmdLine.cpp
Normal file
@@ -0,0 +1,79 @@
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Crytek Engine Source File.
|
||||
// Copyright (C), Crytek Studios, 2002.
|
||||
// -------------------------------------------------------------------------
|
||||
// File name: cmdline.cpp
|
||||
// Version: v1.00
|
||||
// Created: 5/11/2002 by Timur.
|
||||
// Compilers: Visual Studio.NET
|
||||
// Description:
|
||||
// -------------------------------------------------------------------------
|
||||
// History:
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include "StdAfx.h"
|
||||
#include "CmdLine.h"
|
||||
#include "Config.h"
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
CmdLine::CmdLine()
|
||||
{
|
||||
m_bHelp = false;
|
||||
m_platform = PLATFORM_UNKNOWN;
|
||||
m_config = 0;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
void CmdLine::Parse( int argc, char **argv,Config *config )
|
||||
{
|
||||
m_config = config;
|
||||
for (int i = 1; i < argc; i++)
|
||||
{
|
||||
const char *param = argv[i];
|
||||
bool bFlag = false;
|
||||
bool bLast = ((i + 1) == argc);
|
||||
if (param[0] == '-' || param[0] == '/')
|
||||
{
|
||||
// remove flag specifier
|
||||
bFlag = true;
|
||||
++param;
|
||||
}
|
||||
ParseParam(param,bFlag,bLast);
|
||||
}
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
void CmdLine::ParseParam( const char* param, bool bFlag,bool bLast )
|
||||
{
|
||||
if (!bFlag)
|
||||
{
|
||||
if (m_fileSpec.IsEmpty())
|
||||
m_fileSpec = param;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Flag.
|
||||
// Split on key/value pair.
|
||||
if (stricmp("h",param) == 0)
|
||||
m_bHelp = true;
|
||||
else
|
||||
{
|
||||
CString prm = param;
|
||||
int splitter = prm.Find('=');
|
||||
if (splitter >= 0)
|
||||
{
|
||||
CString key = prm.Mid(0,splitter);
|
||||
CString value = prm.Mid(splitter+1);
|
||||
// Put key/value pair to config.
|
||||
if (!key.IsEmpty() && m_config)
|
||||
m_config->Set( key.GetString(),value.GetString() );
|
||||
}
|
||||
else
|
||||
{
|
||||
m_config->Set (prm.GetString(), "");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
38
ResourceCompiler/CmdLine.h
Normal file
38
ResourceCompiler/CmdLine.h
Normal file
@@ -0,0 +1,38 @@
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Crytek Engine Source File.
|
||||
// Copyright (C), Crytek Studios, 2002.
|
||||
// -------------------------------------------------------------------------
|
||||
// File name: cmdline.h
|
||||
// Version: v1.00
|
||||
// Created: 5/11/2002 by Timur.
|
||||
// Compilers: Visual Studio.NET
|
||||
// Description:
|
||||
// -------------------------------------------------------------------------
|
||||
// History:
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifndef __cmdline_h__
|
||||
#define __cmdline_h__
|
||||
#pragma once
|
||||
|
||||
class Config;
|
||||
|
||||
/** Command Line parser.
|
||||
*/
|
||||
class CmdLine
|
||||
{
|
||||
public:
|
||||
CmdLine();
|
||||
|
||||
void Parse ( int argc, char **argv,Config *config );
|
||||
void ParseParam ( const char *param,bool bFlag,bool bLast );
|
||||
|
||||
CString m_fileSpec;
|
||||
bool m_bHelp;
|
||||
Platform m_platform;
|
||||
Config* m_config;
|
||||
};
|
||||
|
||||
#endif // __cmdline_h__
|
||||
151
ResourceCompiler/Config.cpp
Normal file
151
ResourceCompiler/Config.cpp
Normal file
@@ -0,0 +1,151 @@
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Crytek Engine Source File.
|
||||
// Copyright (C), Crytek Studios, 2002.
|
||||
// -------------------------------------------------------------------------
|
||||
// File name: config.cpp
|
||||
// Version: v1.00
|
||||
// Created: 4/11/2002 by Timur.
|
||||
// Compilers: Visual Studio.NET
|
||||
// Description:
|
||||
// -------------------------------------------------------------------------
|
||||
// History:
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include "StdAfx.h"
|
||||
#include "config.h"
|
||||
|
||||
Config::Config()
|
||||
{
|
||||
}
|
||||
|
||||
Config::~Config()
|
||||
{
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
IConfig* Config::Clone() const
|
||||
{
|
||||
Config *cfg = new Config;
|
||||
cfg->m_map = m_map;
|
||||
return cfg;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
bool Config::HasKey( const char *key ) const
|
||||
{
|
||||
if (m_map.find(key) != m_map.end())
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
bool Config::Get( const char *key,float &value ) const
|
||||
{
|
||||
Map::const_iterator it = m_map.find(key);
|
||||
if (it != m_map.end())
|
||||
{
|
||||
const char* szValue = it->second.GetString();
|
||||
if (1 == sscanf (szValue, "%f", &value))
|
||||
return true;
|
||||
else
|
||||
return false;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
bool Config::Get( const char *key,int &value ) const
|
||||
{
|
||||
Map::const_iterator it = m_map.find(key);
|
||||
if (it != m_map.end())
|
||||
{
|
||||
const char* szValue = it->second.GetString();
|
||||
if (1 == sscanf (szValue, "%d", &value))
|
||||
return true;
|
||||
else
|
||||
return false;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
bool Config::Get( const char *key,bool &value ) const
|
||||
{
|
||||
Map::const_iterator it = m_map.find(key);
|
||||
if (it != m_map.end())
|
||||
{
|
||||
const char* szValue = it->second.GetString();
|
||||
int nTryInt;
|
||||
if (1 == sscanf (szValue, "%d", &nTryInt))
|
||||
{
|
||||
value = nTryInt != 0;
|
||||
return true;
|
||||
}
|
||||
|
||||
if (!stricmp(szValue, "true")
|
||||
||!stricmp(szValue, "yes")
|
||||
||!stricmp(szValue, "enable")
|
||||
||!stricmp(szValue, "y")
|
||||
||!stricmp(szValue, "t"))
|
||||
{
|
||||
value = true;
|
||||
return true;
|
||||
}
|
||||
|
||||
if (!stricmp(szValue, "false")
|
||||
||!stricmp(szValue, "no")
|
||||
||!stricmp(szValue, "disable")
|
||||
||!stricmp(szValue, "n")
|
||||
||!stricmp(szValue, "f"))
|
||||
{
|
||||
value = false;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void Config::Merge( IConfig *inpConfig )
|
||||
{
|
||||
Config *pConfig=inpConfig->GetInternalRepresentation();
|
||||
|
||||
assert(pConfig);if(!pConfig)return;
|
||||
|
||||
Map::iterator it;
|
||||
|
||||
for(it=pConfig->m_map.begin();it!=pConfig->m_map.end();++it)
|
||||
{
|
||||
CString key=(*it).first;
|
||||
CString value=(*it).second;
|
||||
|
||||
Set(key.GetString(),value.GetString());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
Config *Config::GetInternalRepresentation( void )
|
||||
{
|
||||
return(this);
|
||||
}
|
||||
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
bool Config::Get( const char *key,CString &value ) const
|
||||
{
|
||||
Map::const_iterator it = m_map.find(key);
|
||||
if (it != m_map.end())
|
||||
{
|
||||
value = it->second;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
void Config::Set( const char *key,const char* value )
|
||||
{
|
||||
m_map[key] = value;
|
||||
}
|
||||
58
ResourceCompiler/Config.h
Normal file
58
ResourceCompiler/Config.h
Normal file
@@ -0,0 +1,58 @@
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Crytek Engine Source File.
|
||||
// Copyright (C), Crytek Studios, 2002.
|
||||
// -------------------------------------------------------------------------
|
||||
// File name: config.h
|
||||
// Version: v1.00
|
||||
// Created: 4/11/2002 by Timur.
|
||||
// Compilers: Visual Studio.NET
|
||||
// Description:
|
||||
// -------------------------------------------------------------------------
|
||||
// History:
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifndef __config_h__
|
||||
#define __config_h__
|
||||
#pragma once
|
||||
|
||||
|
||||
#include "iconfig.h"
|
||||
|
||||
/** Implementation of IConfig interface.
|
||||
*/
|
||||
class Config : public IConfig
|
||||
{
|
||||
public:
|
||||
Config();
|
||||
virtual ~Config();
|
||||
|
||||
virtual void Release() { delete this; };
|
||||
|
||||
//! Clone configuration.
|
||||
virtual IConfig* Clone() const;
|
||||
|
||||
//! Check if configuration has this key.
|
||||
virtual bool HasKey( const char *key ) const;
|
||||
|
||||
//! Get value of key.
|
||||
//! @return true if option found, false if not.
|
||||
virtual bool Get( const char *key,float &value ) const;
|
||||
virtual bool Get( const char *key,int &value ) const;
|
||||
virtual bool Get( const char *key,bool &value ) const;
|
||||
virtual bool Get( const char *key,CString &value ) const;
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
void Set( const char *key,const char* value );
|
||||
|
||||
void Merge( IConfig *inpConfig );
|
||||
|
||||
virtual Config *GetInternalRepresentation( void );
|
||||
|
||||
private:
|
||||
typedef std::hash_map<CString,CString,stl::hash_stricmp<CString> > Map;
|
||||
Map m_map;
|
||||
};
|
||||
|
||||
#endif // __config_h__
|
||||
84
ResourceCompiler/ConvertContext.h
Normal file
84
ResourceCompiler/ConvertContext.h
Normal file
@@ -0,0 +1,84 @@
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Crytek Engine Source File.
|
||||
// Copyright (C), Crytek Studios, 2002.
|
||||
// -------------------------------------------------------------------------
|
||||
// File name: convertcontext.h
|
||||
// Version: v1.00
|
||||
// Created: 4/11/2002 by Timur.
|
||||
// Compilers: Visual Studio.NET
|
||||
// Description:
|
||||
// -------------------------------------------------------------------------
|
||||
// History:
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifndef __convertcontext_h__
|
||||
#define __convertcontext_h__
|
||||
#pragma once
|
||||
|
||||
#include "PathUtil.h"
|
||||
|
||||
struct IResourceCompiler;
|
||||
struct IConfig;
|
||||
struct IRCLog;
|
||||
struct ICfgFile;
|
||||
|
||||
/** Enumeration of supported platforms.
|
||||
*/
|
||||
enum Platform
|
||||
{
|
||||
PLATFORM_UNKNOWN, //!< Unknown platform.
|
||||
PLATFORM_PC,
|
||||
PLATFORM_XBOX,
|
||||
PLATFORM_PS2,
|
||||
PLATFORM_GAMECUBE,
|
||||
|
||||
// This entry must be last in Platform enum.
|
||||
PLATFORM_LAST,
|
||||
};
|
||||
|
||||
/** ConvertContext is a description of what should be processed by convertor.
|
||||
*/
|
||||
struct ConvertContext
|
||||
{
|
||||
// this string must be prepended to all paths (it's with the trailing slash)
|
||||
CString masterFolder;
|
||||
|
||||
//! Source file that needs to be converted.
|
||||
CString sourceFile;
|
||||
//! Output file that would be created from sourceFile. (relative or absolute)
|
||||
CString outputFile;
|
||||
|
||||
CString getSourcePath() {return masterFolder + Path::Make(sourceFolder,sourceFile);}
|
||||
CString getOutputPath() {return masterFolder + Path::Make(outputFolder,outputFile);}
|
||||
CString getOutputFolderPath(){return masterFolder + outputFolder;}
|
||||
|
||||
//! Source file folder, so that the source file can be opened regardless whether the
|
||||
//! path is given in sourceFile or not
|
||||
CString sourceFolder;
|
||||
//! Output folder
|
||||
CString outputFolder;
|
||||
|
||||
//! Pointer to resource compiler interface.
|
||||
IResourceCompiler *pRC;
|
||||
//! Configuration settings for this file.
|
||||
IConfig *config;
|
||||
//! Returns the log to put the messages during conversion to:
|
||||
//! use Log(), LogWarning() and LogError()
|
||||
IRCLog *pLog;
|
||||
|
||||
//! Dont log much info into log.
|
||||
bool bQuiet;
|
||||
|
||||
//! file specific config file, must not be 0 (if there was no file, a empty instace with the right filename is created)
|
||||
ICfgFile *pFileSpecificConfig;
|
||||
|
||||
//! presets config (for use with the image compiler)
|
||||
ICfgFile *presets;
|
||||
|
||||
//! Platform to which file must be processed.
|
||||
Platform platform;
|
||||
};
|
||||
|
||||
#endif // __convertcontext_h__
|
||||
186
ResourceCompiler/CryBoneDesc.cpp
Normal file
186
ResourceCompiler/CryBoneDesc.cpp
Normal file
@@ -0,0 +1,186 @@
|
||||
#include "stdafx.h"
|
||||
#include "MathUtils.h"
|
||||
#include "CryBoneDesc.h"
|
||||
#include "StringUtils.h"
|
||||
|
||||
using namespace CryStringUtils;
|
||||
|
||||
CryBoneDesc::CryBoneDesc()
|
||||
{
|
||||
m_PhysInfo[0].pPhysGeom = m_PhysInfo[1].pPhysGeom = 0;
|
||||
m_matInvDefGlobal.SetIdentity();; // allows to get difference to def pose matrices
|
||||
}
|
||||
|
||||
CryBoneDesc::~CryBoneDesc()
|
||||
{
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// loads the bone from a raw chunk data (no header)
|
||||
// PARAMETERS:
|
||||
// pEntity - the chunk data to load the bone info from
|
||||
// RETURNS:
|
||||
// false if the bone couldn't be loaded
|
||||
bool CryBoneDesc::LoadRaw (const BONE_ENTITY* pEntity)
|
||||
{
|
||||
//read bone info
|
||||
assert(pEntity->nChildren<200);
|
||||
|
||||
// update the lod 0 physics of this bone
|
||||
UpdatePhysics (*pEntity, 0);
|
||||
|
||||
//get bone info
|
||||
m_nControllerID = pEntity->ControllerID;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// updates this bone physics, from the given entity descriptor, and of the given lod
|
||||
void CryBoneDesc::UpdatePhysics (const BONE_ENTITY& entity, int nLod)
|
||||
{
|
||||
assert (nLod >= 0 && nLod < SIZEOF_ARRAY(m_PhysInfo));
|
||||
CopyPhysInfo(m_PhysInfo[nLod], entity.phys);
|
||||
|
||||
int nFlags = 0;
|
||||
if (entity.prop[0])
|
||||
{
|
||||
nFlags = joint_no_gravity|joint_isolated_accelerations;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!strnstr(entity.prop,"gravity", sizeof(entity.prop)))
|
||||
nFlags |= joint_no_gravity;
|
||||
|
||||
if (!strnstr(entity.prop,"physical",sizeof(entity.prop)))
|
||||
nFlags |= joint_isolated_accelerations;
|
||||
}
|
||||
|
||||
m_PhysInfo[nLod].flags |= nFlags;
|
||||
}
|
||||
|
||||
|
||||
|
||||
//! Performs post-initialization. This step is requred to initialize the pPhysGeom of the bones
|
||||
//! After the bone has been loaded but before it is first used. When the bone is first loaded, pPhysGeom
|
||||
//! is set to the value equal to the chunk id in the file where the physical geometry (BoneMesh) chunk is kept.
|
||||
//! After those chunks are loaded, and chunk ids are mapped to the registered physical geometry objects,
|
||||
//! call this function to replace pPhysGeom chunk ids with the actual physical geometry object pointers.
|
||||
//! RETURNS:
|
||||
// true if the corresponding physical geometry object has been found
|
||||
//! NOTE:
|
||||
//! The entries of the map that were used are deleted
|
||||
bool CryBoneDesc::PostInitPhysGeom (ChunkIdToPhysGeomMap& mapChunkIdToPhysGeom, int nLodLevel)
|
||||
{
|
||||
phys_geometry*& pPhysGeom = m_PhysInfo[nLodLevel].pPhysGeom;
|
||||
ChunkIdToPhysGeomMap::iterator it = mapChunkIdToPhysGeom.find ((INT_PTR)pPhysGeom);
|
||||
if (it != mapChunkIdToPhysGeom.end())
|
||||
{
|
||||
// remap the chunk id to the actual pointer to the geometry
|
||||
pPhysGeom = it->second;
|
||||
mapChunkIdToPhysGeom.erase (it);
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
pPhysGeom = NULL;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// sets the name of the bone out of the given buffer of the given max size
|
||||
void CryBoneDesc::setName (const char* szName)
|
||||
{
|
||||
m_strName.assign (szName);
|
||||
|
||||
static const char *g_arrLimbNames[4] = { "L UpperArm","R UpperArm","L Thigh","R Thigh" };
|
||||
m_nLimbId = -1;
|
||||
for (int j=0; j < SIZEOF_ARRAY(g_arrLimbNames) ;j++)
|
||||
if (strstr(szName,g_arrLimbNames[j]))
|
||||
{
|
||||
m_nLimbId = j;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// returns the bone name, if available
|
||||
const char* CryBoneDesc::getNameCStr()const
|
||||
{
|
||||
return m_strName.c_str();
|
||||
}
|
||||
|
||||
const string& CryBoneDesc::getName()const
|
||||
{
|
||||
return m_strName;
|
||||
}
|
||||
|
||||
// compares two bone descriptions and returns true if they're the same bone
|
||||
// (the same name and the same position in the hierarchy)
|
||||
bool CryBoneDesc::isEqual (const CryBoneDesc& desc)const
|
||||
{
|
||||
return m_strName == desc.m_strName
|
||||
&& m_nControllerID == desc.m_nControllerID
|
||||
&& m_nOffsetParent == desc.m_nOffsetParent
|
||||
&& m_numChildren == desc.m_numChildren
|
||||
&& m_nOffsetChildren == desc.m_nOffsetChildren;
|
||||
}
|
||||
|
||||
|
||||
inline size_t align4 (size_t x)
|
||||
{
|
||||
return (x + 3)&~3;
|
||||
}
|
||||
|
||||
// Serializes the description:
|
||||
// returns the number of required bytes for serialization, if the data pointer is NULL
|
||||
// returns 0 (if the buffer size is not enough) or the number of bytes written, if the data pointer is given
|
||||
unsigned CryBoneDesc::Serialize (bool bSave, void *pStream, unsigned nSize)
|
||||
{
|
||||
if (bSave)
|
||||
{
|
||||
unsigned nSizeRequired = (unsigned)(sizeof(CryBoneDescData_Comp) + align4 (m_strName.length()+1));
|
||||
if (!pStream)
|
||||
return nSizeRequired;
|
||||
if (nSize < nSizeRequired)
|
||||
return 0;
|
||||
|
||||
CopyCryBone(*(CryBoneDescData_Comp*)pStream, *this);
|
||||
memcpy ((CryBoneDescData_Comp*)pStream+1,m_strName.c_str(),m_strName.length()+1);
|
||||
return nSizeRequired;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!pStream)
|
||||
return 0;
|
||||
if (nSize < sizeof(CryBoneDescData_Comp)+1)
|
||||
return 0;
|
||||
if (nSize & 3)
|
||||
return 0; // alignment error
|
||||
CopyCryBone(*this, *(CryBoneDescData_Comp*)pStream);
|
||||
// end of the stream
|
||||
const char* pEnd = (const char*)pStream + nSize;
|
||||
// the start byte of the bone name
|
||||
const char* pName = (const char*)((CryBoneDescData_Comp*)pStream+1);
|
||||
|
||||
// scan until the end of the name (\0 char) or the stream (pEnd address)
|
||||
const char *pNameEnd;
|
||||
for (pNameEnd = pName; pNameEnd < pEnd && *pNameEnd; ++pNameEnd);
|
||||
m_strName.assign (pName, pNameEnd);
|
||||
// return aligned size of the chunk including the string 0 terminator, but
|
||||
// no more than the declared size of the stream
|
||||
return min(nSize, (unsigned)align4 (pNameEnd+1-(const char*)pStream));
|
||||
}
|
||||
}
|
||||
|
||||
void CryBoneDesc::setDefaultGlobal(const Matrix44& matDefault)
|
||||
{
|
||||
m_matInvDefGlobal=OrthoUniformGetInverted (matDefault);
|
||||
}
|
||||
|
||||
|
||||
// scales the bone with the given multiplier
|
||||
void CryBoneDesc::scale (float fScale)
|
||||
{
|
||||
m_matInvDefGlobal.SetTranslationOLD(m_matInvDefGlobal.GetTranslationOLD()*fScale);
|
||||
}
|
||||
170
ResourceCompiler/CryBoneDesc.h
Normal file
170
ResourceCompiler/CryBoneDesc.h
Normal file
@@ -0,0 +1,170 @@
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Crytek Character Animation source code
|
||||
//
|
||||
// File:CryBoneDesc.h
|
||||
//
|
||||
// History:
|
||||
// Created by Sergiy Migdalskiy 01/14/2003
|
||||
//
|
||||
/////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
#ifndef _CRY_BONE_DESC_HDR_
|
||||
#define _CRY_BONE_DESC_HDR_
|
||||
|
||||
// this class contains the information that's common to all instances of bones
|
||||
// in the given model: like bone name, and misc. shared properties
|
||||
// We use a base structure to separate the bunch of parameters that get serialized
|
||||
// together
|
||||
#pragma pack(push,4)
|
||||
template <class TBonePhysics>
|
||||
struct TCryBoneDescData
|
||||
{
|
||||
unsigned int m_nControllerID; // unic id of bone (generated from bone name in the max)
|
||||
|
||||
// [Sergiy] physics info for different lods
|
||||
// lod 0 is the physics of alive body, lod 1 is the physics of a dead body
|
||||
TBonePhysics m_PhysInfo[2];
|
||||
float m_fMass;
|
||||
|
||||
Matrix44 m_matInvDefGlobal; // allows to get difference to def pose matrices
|
||||
|
||||
int m_nLimbId; // set by model state class
|
||||
|
||||
// this bone parent is this[m_nOffsetParent], 0 if the bone is root. Normally this is <= 0
|
||||
int m_nOffsetParent;
|
||||
|
||||
// The whole hierarchy of bones is kept in one big array that belongs to the ModelState
|
||||
// Each bone that has children has its own range of bone objects in that array,
|
||||
// and this points to the beginning of that range and defines the number of bones.
|
||||
unsigned m_numChildren;
|
||||
// the beginning of the subarray of children is at this[m_nOffsetChildren]
|
||||
// this is 0 if there are no children
|
||||
int m_nOffsetChildren;
|
||||
};
|
||||
|
||||
typedef TCryBoneDescData<BONE_PHYSICS> CryBoneDescData;
|
||||
// compatible structure
|
||||
typedef TCryBoneDescData<BONE_PHYSICS_COMP> CryBoneDescData_Comp;
|
||||
|
||||
#define __copy(x) left.x = right.x
|
||||
|
||||
inline void CopyCryBone (CryBoneDescData_Comp& left, const CryBoneDescData& right)
|
||||
{
|
||||
__copy(m_nControllerID);
|
||||
CopyPhysInfo (left.m_PhysInfo[0], right.m_PhysInfo[0]);
|
||||
CopyPhysInfo (left.m_PhysInfo[1], right.m_PhysInfo[1]);
|
||||
__copy(m_fMass);
|
||||
__copy(m_matInvDefGlobal);
|
||||
__copy(m_nLimbId);
|
||||
__copy(m_nOffsetParent);
|
||||
__copy(m_numChildren);
|
||||
__copy(m_nOffsetChildren);
|
||||
}
|
||||
|
||||
inline void CopyCryBone (CryBoneDescData& left, const CryBoneDescData_Comp& right)
|
||||
{
|
||||
__copy(m_nControllerID);
|
||||
CopyPhysInfo (left.m_PhysInfo[0], right.m_PhysInfo[0]);
|
||||
CopyPhysInfo (left.m_PhysInfo[1], right.m_PhysInfo[1]);
|
||||
__copy(m_fMass);
|
||||
__copy(m_matInvDefGlobal);
|
||||
__copy(m_nLimbId);
|
||||
__copy(m_nOffsetParent);
|
||||
__copy(m_numChildren);
|
||||
__copy(m_nOffsetChildren);
|
||||
}
|
||||
|
||||
#undef __copy
|
||||
|
||||
#pragma pack(pop)
|
||||
|
||||
|
||||
|
||||
class CryBoneDesc: public CryBoneDescData
|
||||
{
|
||||
public:
|
||||
CryBoneDesc ();
|
||||
~CryBoneDesc ();
|
||||
|
||||
// returns the bone name, if available
|
||||
const char* getNameCStr()const;
|
||||
const string& getName()const;
|
||||
|
||||
unsigned getControllerId()const {return m_nControllerID;}
|
||||
|
||||
// sets the name of the bone out of the given buffer of the given max size
|
||||
void setName (const char* szName);
|
||||
|
||||
unsigned numChildren ()const {return m_numChildren;}
|
||||
bool hasParent() const {return m_nOffsetParent != 0;}
|
||||
int getParentIndexOffset()const {return m_nOffsetParent;}
|
||||
int getFirstChildIndexOffset() const {return m_nOffsetChildren;}
|
||||
|
||||
const Matrix44& getInvDefGlobal() const {return m_matInvDefGlobal;}
|
||||
void setDefaultGlobal(const Matrix44& mxDefault);
|
||||
int getLimbId () const {return m_nLimbId;}
|
||||
|
||||
BONE_PHYSICS& getPhysInfo (int nLod) {return m_PhysInfo[nLod];}
|
||||
|
||||
// updates this bone physics, from the given entity descriptor, and of the given lod
|
||||
void UpdatePhysics (const BONE_ENTITY& entity, int nLod);
|
||||
void setPhysics (int nLod, const BONE_PHYSICS& BonePhysics)
|
||||
{
|
||||
assert (nLod >= 0 && nLod < sizeof(m_PhysInfo)/sizeof(m_PhysInfo[0]));
|
||||
m_PhysInfo[nLod] = BonePhysics;
|
||||
}
|
||||
// the physics for the given LOD is not available
|
||||
void resetPhysics (int nLod)
|
||||
{
|
||||
assert (nLod >= 0 && nLod < sizeof(m_PhysInfo)/sizeof(m_PhysInfo[0]));
|
||||
memset (&m_PhysInfo[nLod], 0, sizeof(m_PhysInfo[nLod]));
|
||||
}
|
||||
const BONE_PHYSICS& getPhysics (int nLod)const
|
||||
{
|
||||
assert (nLod >= 0 && nLod < sizeof(m_PhysInfo)/sizeof(m_PhysInfo[0]));
|
||||
return m_PhysInfo[nLod];
|
||||
}
|
||||
|
||||
// Returns the id of the bone mesh chunk from which the bone physical geometry
|
||||
// should be taken. The caller should take this id, find the corresponding chunk in the CCG/CGF file
|
||||
// and construct physical geometry using IGeomManager::CreateMesh.
|
||||
// Then, register it with RegisterGeometry(). It will return phys_geometry* that the caller
|
||||
// should put into the corresponding LOD m_PhysInfo.pPhysGeom
|
||||
// CryBoneInfo::PostInitPhysGeom uses this same id to find the physical geometry in the map
|
||||
INT_PTR getPhysGeomId (unsigned nLOD) {return (INT_PTR)m_PhysInfo[nLOD].pPhysGeom;}
|
||||
|
||||
// compares two bone descriptions and returns true if they're the same bone
|
||||
// (the same name and the same position in the hierarchy)
|
||||
bool isEqual(const CryBoneDesc& desc)const;
|
||||
|
||||
// Serializes the description:
|
||||
// returns the number of required bytes for serialization, if the data pointer is NULL
|
||||
// returns 0 (if the buffer size is not enough) or the number of bytes written, if the data pointer is given
|
||||
unsigned Serialize (bool bSave, void *pStream, unsigned nSize);
|
||||
|
||||
// scales the bone with the given multiplier
|
||||
void scale (float fScale);
|
||||
|
||||
protected:
|
||||
|
||||
// loads the bone from a raw chunk data (no header)
|
||||
// returns false if the bone couldn't be loaded
|
||||
bool LoadRaw (const BONE_ENTITY* pEntity);
|
||||
|
||||
//! Performs post-initialization. This step is requred to initialize the pPhysGeom of the bones
|
||||
//! After the bone has been loaded but before it is first used. When the bone is first loaded, pPhysGeom
|
||||
//! is set to the value equal to the chunk id in the file where the physical geometry (BoneMesh) chunk is kept.
|
||||
//! After those chunks are loaded, and chunk ids are mapped to the registered physical geometry objects,
|
||||
//! call this function to replace pPhysGeom chunk ids with the actual physical geometry object pointers.
|
||||
//! NOTE:
|
||||
//! The entries of the map that were used are deleted
|
||||
typedef std::map<INT_PTR, struct phys_geometry*> ChunkIdToPhysGeomMap;
|
||||
bool PostInitPhysGeom (ChunkIdToPhysGeomMap& mapChunkIdToPhysGeom, int nLodLevel);
|
||||
|
||||
friend class CryBoneHierarchyLoader;
|
||||
|
||||
protected:
|
||||
string m_strName;
|
||||
};
|
||||
|
||||
#endif
|
||||
228
ResourceCompiler/CryBoneHierarchyLoader.cpp
Normal file
228
ResourceCompiler/CryBoneHierarchyLoader.cpp
Normal file
@@ -0,0 +1,228 @@
|
||||
/////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Crytek Character Animation source code
|
||||
//
|
||||
// History:
|
||||
// 22 Sep 2002 :- Created by Sergiy Migdalskiy <sergiy@crytek.de>
|
||||
//
|
||||
// Contains:
|
||||
// class - loading context - responsible for loading the linearized bone hierarchy from the BONEANIM
|
||||
// chunk
|
||||
/////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include "stdafx.h"
|
||||
#include "MathUtils.h"
|
||||
#include "CryBoneHierarchyLoader.h"
|
||||
#include "ChunkFileReader.h"
|
||||
#include "CgfUtils.h"
|
||||
|
||||
CryBoneHierarchyLoader::CryBoneHierarchyLoader ():
|
||||
#ifdef DEBUG_STD_CONTAINERS
|
||||
m_arrBones("CryBoneHierarchyLoader.Bones"),
|
||||
m_arrIdToIndex ("CryBoneHierarchyLoader.indexidmaps"),
|
||||
m_arrIndexToId ("CryBoneHierarchyLoader.indexidmaps"),
|
||||
#endif
|
||||
m_pChunkBoneAnim(NULL),
|
||||
m_pChunkBoneAnimSize(0),
|
||||
|
||||
m_pBoneAnimRawData (NULL),
|
||||
m_pBoneAnimRawDataEnd (NULL),
|
||||
m_szLastError ("")
|
||||
{
|
||||
}
|
||||
|
||||
unsigned CryBoneHierarchyLoader::load (const BONEANIM_CHUNK_DESC* pChunk, unsigned nChunkSize)
|
||||
{
|
||||
m_arrBones.clear();
|
||||
m_arrIndexToId.clear();
|
||||
m_arrIdToIndex.clear();
|
||||
|
||||
m_pChunkBoneAnim = pChunk;
|
||||
m_pChunkBoneAnimSize = nChunkSize;
|
||||
|
||||
m_pBoneAnimRawData = pChunk+1;
|
||||
m_pBoneAnimRawDataEnd = ((const char*) pChunk) + nChunkSize;
|
||||
|
||||
if (nChunkSize < sizeof(*pChunk))
|
||||
{
|
||||
m_szLastError = "Couldn't read the data." ;
|
||||
m_pBoneAnimRawData = pChunk;
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (pChunk->nBones <= 0)
|
||||
{
|
||||
m_szLastError = "There must be at least one bone.";
|
||||
m_pBoneAnimRawData = pChunk;
|
||||
return 0;
|
||||
}
|
||||
|
||||
const BONE_ENTITY* pBones = (const BONE_ENTITY*) (pChunk+1);
|
||||
if (m_pBoneAnimRawDataEnd < (const byte*)(pBones + pChunk->nBones))
|
||||
{
|
||||
m_szLastError = "Premature end of data.";
|
||||
return 0;
|
||||
}
|
||||
|
||||
// check for one-and-only-one root rule
|
||||
if (pBones[0].ParentID != -1)
|
||||
{
|
||||
m_szLastError = "The first bone in the hierarchy has a parent, but it is expected to be the root bone.";
|
||||
return 0;
|
||||
}
|
||||
|
||||
for (int i = 1; i < pChunk->nBones; ++i)
|
||||
{
|
||||
if (pBones[i].ParentID == -1)
|
||||
{
|
||||
m_szLastError = "The skeleton has multiple roots. Only single-rooted skeletons are supported in this version.";
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
m_arrBones.resize (numBones());
|
||||
m_arrIndexToId.resize (numBones(), -1);
|
||||
m_arrIdToIndex.resize (numBones(), -1);
|
||||
m_nNextBone = 0;
|
||||
|
||||
int nRootBoneIndex = (int)allocateBones (1);
|
||||
|
||||
if (nRootBoneIndex < 0 || !load(nRootBoneIndex, nRootBoneIndex))
|
||||
m_pBoneAnimRawData = pChunk;
|
||||
|
||||
updateInvDefGlobalMatrices();
|
||||
return (const byte*)m_pBoneAnimRawData - (const byte*)m_pChunkBoneAnim;
|
||||
}
|
||||
|
||||
// updates the bone InvDefGlobal matrices, if the default pose matrices
|
||||
// are available
|
||||
void CryBoneHierarchyLoader::updateInvDefGlobalMatrices()
|
||||
{
|
||||
if (m_arrInitPose.empty() || m_arrBones.empty())
|
||||
return;
|
||||
|
||||
if (m_arrInitPose.size() != m_arrBones.size())
|
||||
{
|
||||
#ifdef _CRY_ANIMATION_BASE_HEADER_
|
||||
g_GetLog()->LogError ("\003there are %d bones and %d initial pose matrices. ignoring matrices.", m_arrBones.size(), m_arrInitPose.size());
|
||||
#endif
|
||||
return;
|
||||
}
|
||||
|
||||
for (unsigned nBone = 0; nBone < m_arrBones.size(); ++nBone)
|
||||
{
|
||||
unsigned nBoneID = mapIndexToId(nBone);
|
||||
m_arrBones[nBone].setDefaultGlobal (m_arrInitPose[nBoneID]);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// loads the default positions of each bone; if the bone chunk is loaded,
|
||||
// updates the bone inverse default pose matrices
|
||||
// returns number of bytes read if successful, 0 if not
|
||||
unsigned CryBoneHierarchyLoader::load (const BONEINITIALPOS_CHUNK_DESC_0001*pChunk, unsigned nChunkSize)
|
||||
{
|
||||
if (nChunkSize < sizeof(*pChunk) || pChunk->numBones < 0 || pChunk->numBones > 0x10000)
|
||||
return 0;
|
||||
const char* pChunkEnd = ((const char*)pChunk) + nChunkSize;
|
||||
const SBoneInitPosMatrix* pDefMatrix = (const SBoneInitPosMatrix*)(pChunk+1);
|
||||
|
||||
// the end of utilized data in the chunk
|
||||
const char* pUtilizedEnd = (const char*)(pDefMatrix + pChunk->numBones);
|
||||
if (pUtilizedEnd > pChunkEnd)
|
||||
return 0;
|
||||
|
||||
m_arrInitPose.resize (pChunk->numBones);
|
||||
for (unsigned nBone = 0; nBone < pChunk->numBones; ++nBone)
|
||||
{
|
||||
Matrix44& matBone = m_arrInitPose[nBone];
|
||||
copyMatrix (matBone,pDefMatrix[nBone]);
|
||||
// for some reason Max supplies unnormalized matrices.
|
||||
matBone.NoScale();
|
||||
}
|
||||
|
||||
updateInvDefGlobalMatrices();
|
||||
return pUtilizedEnd - (const char*)pChunk;
|
||||
}
|
||||
|
||||
void CryBoneHierarchyLoader::scale (float fScale)
|
||||
{
|
||||
unsigned i;
|
||||
for (i = 0; i < m_arrInitPose.size(); ++i)
|
||||
m_arrInitPose[i].ScaleTranslationOLD (fScale);
|
||||
|
||||
updateInvDefGlobalMatrices();
|
||||
}
|
||||
|
||||
// allocates the required number of bones in the plain hierarchy array, starting at the next available place
|
||||
// -1 if couldn't allocate
|
||||
int CryBoneHierarchyLoader::allocateBones(int numBones)
|
||||
{
|
||||
if (m_nNextBone + numBones > (int)this->numBones())
|
||||
return -1; // the request is for too many bones
|
||||
|
||||
int nResult = m_nNextBone;
|
||||
m_nNextBone += numBones;
|
||||
assert (m_nNextBone <= (int)this->numBones());
|
||||
return nResult;
|
||||
}
|
||||
|
||||
|
||||
// loads the whole hierarchy of bones, using the state machine
|
||||
// when this funciton is called, the bone is already allocated
|
||||
bool CryBoneHierarchyLoader::load (int nBoneParentIndex, int nBoneIndex)
|
||||
{
|
||||
const BONE_ENTITY* pEntity;
|
||||
if (!EatRawDataPtr(pEntity, 1, m_pBoneAnimRawData, m_pBoneAnimRawDataEnd))
|
||||
return false;
|
||||
|
||||
// initialize the next bone
|
||||
CryBoneDesc& rBoneDesc = m_arrBones[nBoneIndex];
|
||||
if (!rBoneDesc.LoadRaw (pEntity))
|
||||
return false;
|
||||
|
||||
// set the mapping entries
|
||||
m_arrIndexToId[nBoneIndex] = pEntity->BoneID;
|
||||
m_arrIdToIndex[pEntity->BoneID] = nBoneIndex;
|
||||
|
||||
rBoneDesc.m_nOffsetParent = nBoneParentIndex - nBoneIndex;
|
||||
|
||||
// load children
|
||||
if (pEntity->nChildren)
|
||||
{
|
||||
int nChildrenIndexBase = allocateBones(pEntity->nChildren);
|
||||
if (nChildrenIndexBase < 0)
|
||||
return false;
|
||||
|
||||
// load the children
|
||||
rBoneDesc.m_numChildren = pEntity->nChildren;
|
||||
rBoneDesc.m_nOffsetChildren = nChildrenIndexBase - nBoneIndex;
|
||||
|
||||
for (int nChild = 0; nChild < pEntity->nChildren; ++nChild)
|
||||
{
|
||||
if (!load(nBoneIndex, nChildrenIndexBase + nChild))
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
rBoneDesc.m_numChildren = 0;
|
||||
rBoneDesc.m_nOffsetChildren = 0;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
// compares the two bone structures. Returns true if they're equal
|
||||
// (e.g. for validation of different lods)
|
||||
bool CryBoneHierarchyLoader::isEqual (const CryBoneHierarchyLoader& right)const
|
||||
{
|
||||
if (m_arrBones.size() != right.m_arrBones.size())
|
||||
return false;
|
||||
for (unsigned nBone = 0; nBone < m_arrBones.size(); ++nBone)
|
||||
{
|
||||
if (!m_arrBones[nBone].isEqual(right.m_arrBones[nBone]))
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
101
ResourceCompiler/CryBoneHierarchyLoader.h
Normal file
101
ResourceCompiler/CryBoneHierarchyLoader.h
Normal file
@@ -0,0 +1,101 @@
|
||||
/////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Crytek Character Animation source code
|
||||
//
|
||||
// History:
|
||||
// 22 Sep 2002 :- Created by Sergiy Migdalskiy <sergiy@crytek.de>
|
||||
//
|
||||
// Contains:
|
||||
// class - loading context - responsible for loading the linearized bone hierarchy from the BONEANIM
|
||||
// chunk
|
||||
/////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
#ifndef _CRY_BONE_HIERARCHY_LOADER_HDR_
|
||||
#define _CRY_BONE_HIERARCHY_LOADER_HDR_
|
||||
|
||||
#include "CryBoneDesc.h"
|
||||
|
||||
// this class is responsible for building the bone hierarchy array out of the chunk in file
|
||||
// it does recursive building so that the hierarchy is continuous, each bone has continuous child array
|
||||
class CryBoneHierarchyLoader
|
||||
{
|
||||
public:
|
||||
CryBoneHierarchyLoader();
|
||||
|
||||
// loads and creates the array of bones;
|
||||
// returns number of bytes read if successful, 0 if not
|
||||
// updates the CryBoneDesc inv def matrices, if the initial pose matrices are already available
|
||||
unsigned load(const BONEANIM_CHUNK_DESC* pChunk, unsigned nChunkSize);
|
||||
|
||||
// loads the default positions of each bone; if the bone chunk is loaded,
|
||||
// updates the bone inverse default pose matrices
|
||||
// returns number of bytes read if successful, 0 if not
|
||||
unsigned load (const BONEINITIALPOS_CHUNK_DESC_0001*pChunk, unsigned nChunkSize);
|
||||
|
||||
void scale (float fScale);
|
||||
|
||||
// maps the given index of the bone into the id with which the bone is identified in the file
|
||||
int mapIndexToId(int nIndex) const {return m_arrIndexToId[nIndex];}
|
||||
const int* getIndexToIdMap ()const {return &m_arrIndexToId[0];}
|
||||
int mapIdToIndex (int nId)const {return m_arrIdToIndex[nId];}
|
||||
const int* getIdToIndexMap ()const {return &m_arrIdToIndex[0];}
|
||||
|
||||
// initializes the map id->index (inverse of mapIndexToId)
|
||||
void getIdToIndexMap (unsigned* pMap)const;
|
||||
|
||||
const CryBoneDesc& getBoneByIndex (unsigned nIndex) const {return m_arrBones[nIndex];}
|
||||
|
||||
// compares the two bone structures. Returns true if they're equal
|
||||
// (e.g. for validation of different lods)
|
||||
bool isEqual(const CryBoneHierarchyLoader& right)const;
|
||||
|
||||
// returns the number of loaded bones, or 0 if no bones were loaded yet
|
||||
unsigned numBones() const {return m_pChunkBoneAnim ? m_pChunkBoneAnim->nBones : 0;}
|
||||
|
||||
bool hasInitPos () const {return !m_arrInitPose.empty();}
|
||||
const Matrix44& getInitPosMatrixByIndex(int nBoneIndex){return m_arrInitPose[mapIndexToId(nBoneIndex)];}
|
||||
|
||||
const char* getLastError() const {return m_szLastError;}
|
||||
|
||||
// array of bones that's initialized in the constructor
|
||||
// this array is allocated and is not reallocated afterwards; it gives the number of entries in the id<->index map tables
|
||||
// The bones are in the internal (Index) indexation
|
||||
typedef std::vector<CryBoneDesc> CryBoneDescArray;
|
||||
CryBoneDescArray m_arrBones;
|
||||
|
||||
// the array of default bone positions; it's empty if no
|
||||
// init pos chunk was loaded; it doesn't matter in which
|
||||
// order the bones and init pose chunk are loaded:
|
||||
// when both are loaded, the bone descriptors receive the
|
||||
// inverse of these matrices, when they're available.
|
||||
// NOTE:
|
||||
// This is in BoneID indexation
|
||||
std::vector<Matrix44> m_arrInitPose;
|
||||
protected:
|
||||
// loads the whole hierarchy of bones, using the state machine
|
||||
bool load (int nBoneParentIndex, int nBoneIndex);
|
||||
|
||||
// allocates the required number of bones in the plain hierarchy array, starting at the next available place
|
||||
int allocateBones(int numBones);
|
||||
|
||||
// updates the bone InvDefGlobal matrices, if the default pose matrices
|
||||
// are available
|
||||
void updateInvDefGlobalMatrices();
|
||||
protected:
|
||||
const BONEANIM_CHUNK_DESC* m_pChunkBoneAnim;
|
||||
unsigned m_pChunkBoneAnimSize;
|
||||
|
||||
// the current raw data pointer
|
||||
const void* m_pBoneAnimRawData, *m_pBoneAnimRawDataEnd;
|
||||
|
||||
// the currently free position in the array of bones
|
||||
int m_nNextBone;
|
||||
|
||||
// the mapping bone index->bone id and vice versa
|
||||
// have the same size as m_arrBones; -1 means no entry
|
||||
std::vector<int> m_arrIndexToId, m_arrIdToIndex;
|
||||
|
||||
const char* m_szLastError;
|
||||
private:
|
||||
};
|
||||
|
||||
#endif
|
||||
640
ResourceCompiler/CryChunkedFile.cpp
Normal file
640
ResourceCompiler/CryChunkedFile.cpp
Normal file
@@ -0,0 +1,640 @@
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Crytek Engine Source File.
|
||||
// Copyright (C), Crytek Studios, 2002.
|
||||
// -------------------------------------------------------------------------
|
||||
// File name: CryChunkedFile.cpp
|
||||
// Version: v1.00
|
||||
// Created: 13.01.2003 by Sergiy
|
||||
// Compilers: Visual Studio.NET
|
||||
// Description:
|
||||
// -------------------------------------------------------------------------
|
||||
// History:
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
#include "stdafx.h"
|
||||
#include <stdarg.h>
|
||||
#include "CryVertexBinding.h"
|
||||
#include "CgfUtils.h"
|
||||
#include "CryChunkedFile.h"
|
||||
#include "CryBoneDesc.h"
|
||||
#include "CryBoneHierarchyLoader.h"
|
||||
|
||||
#pragma warning(default:4018)
|
||||
|
||||
//E:\GAME01\STLPORT\stlport
|
||||
|
||||
// parses the given chunked file into the internal structure;
|
||||
// outputs warnings if some of the chunks are incomplete or otherwise broken
|
||||
CryChunkedFile::CryChunkedFile (CChunkFileReader* pFile):
|
||||
m_pFile (pFile),
|
||||
pTiming (NULL),
|
||||
pRangeEntities (NULL),
|
||||
pFileHeader (NULL),
|
||||
m_numBoneLightBinds (0),
|
||||
m_pBoneLightBind (NULL),
|
||||
numSceneProps(0),
|
||||
pSceneProps(NULL)
|
||||
{
|
||||
|
||||
unsigned numChunks = pFile->numChunks();
|
||||
this->pFileHeader = &pFile->getFileHeader();
|
||||
|
||||
for (unsigned nChunk = 0; nChunk < numChunks; ++nChunk)
|
||||
{
|
||||
const void* pChunkData = pFile->getChunkData(nChunk);
|
||||
unsigned nChunkSize = pFile->getChunkSize(nChunk);
|
||||
const CHUNK_HEADER& chunkHeader = pFile->getChunkHeader(nChunk);
|
||||
|
||||
switch (chunkHeader.ChunkType)
|
||||
{
|
||||
case ChunkType_Timing:
|
||||
addChunkTiming (chunkHeader, (const TIMING_CHUNK_DESC*)pChunkData, nChunkSize);
|
||||
break;
|
||||
case ChunkType_Node:
|
||||
addChunkNode (chunkHeader, (const NODE_CHUNK_DESC*)pChunkData, nChunkSize);
|
||||
break;
|
||||
case ChunkType_Light:
|
||||
addChunkLight (chunkHeader, (const LIGHT_CHUNK_DESC*)pChunkData, nChunkSize);
|
||||
break;
|
||||
case ChunkType_Mesh:
|
||||
addChunkMesh (chunkHeader, (const MESH_CHUNK_DESC*)pChunkData, nChunkSize);
|
||||
break;
|
||||
case ChunkType_BoneMesh:
|
||||
addChunkBoneMesh (chunkHeader, (const MESH_CHUNK_DESC*)pChunkData, nChunkSize);
|
||||
break;
|
||||
case ChunkType_Mtl:
|
||||
addChunkMaterial(chunkHeader, pChunkData, nChunkSize);
|
||||
break;
|
||||
case ChunkType_BoneAnim:
|
||||
addChunkBoneAnim (chunkHeader, (const BONEANIM_CHUNK_DESC*)pChunkData, nChunkSize);
|
||||
break;
|
||||
case ChunkType_BoneInitialPos:
|
||||
addChunkBoneInitialPos (chunkHeader, (const BONEINITIALPOS_CHUNK_DESC_0001*)pChunkData, nChunkSize);
|
||||
break;
|
||||
case ChunkType_BoneNameList:
|
||||
addChunkBoneNameList (chunkHeader, pChunkData, nChunkSize);
|
||||
break;
|
||||
case ChunkType_MeshMorphTarget:
|
||||
addChunkMeshMorphTarget (chunkHeader, (const MESHMORPHTARGET_CHUNK_DESC_0001*)pChunkData, nChunkSize);
|
||||
break;
|
||||
case ChunkType_BoneLightBinding:
|
||||
addChunkBoneLightBinding (chunkHeader, (const BONELIGHTBINDING_CHUNK_DESC_0001*)pChunkData, nChunkSize);
|
||||
break;
|
||||
case ChunkType_SceneProps:
|
||||
addChunkSceneProps(chunkHeader, (const SCENEPROPS_CHUNK_DESC*)pChunkData, nChunkSize);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// necessary for superfluous content (misc. back-pointers that can be deduced without any additional info) post-step:
|
||||
adjust();
|
||||
}
|
||||
|
||||
|
||||
CryChunkedFile::~CryChunkedFile()
|
||||
{
|
||||
}
|
||||
|
||||
void CheckChunk (const CHUNK_HEADER& chunkHeader, unsigned nChunkSize, unsigned nExpectedVersion, unsigned nExpectedSize)
|
||||
{
|
||||
if (chunkHeader.ChunkVersion != nExpectedVersion)
|
||||
throw CryChunkedFile::Error ("Unexpected timing chunk 0x%X version 0x%X", chunkHeader.ChunkID, chunkHeader.ChunkVersion);
|
||||
if (nChunkSize < nExpectedSize)
|
||||
throw CryChunkedFile::Error ("Truncated node chunk 0x%X: %d bytes (at least %d bytes expected)", chunkHeader.ChunkID, nChunkSize, nExpectedSize);
|
||||
}
|
||||
|
||||
|
||||
void CryChunkedFile::addChunkTiming (const CHUNK_HEADER& chunkHeader, const TIMING_CHUNK_DESC* pChunkData, unsigned nChunkSize)
|
||||
{
|
||||
CheckChunk(chunkHeader, nChunkSize, pChunkData->VERSION, sizeof(TIMING_CHUNK_DESC) + sizeof(RANGE_ENTITY)*pChunkData->nSubRanges);
|
||||
|
||||
this->pTiming = pChunkData;
|
||||
this->pRangeEntities = (const RANGE_ENTITY*)(pChunkData+1);
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
void CryChunkedFile::addChunkNode (const CHUNK_HEADER& chunkHeader, const NODE_CHUNK_DESC* pChunkData, unsigned nChunkSize)
|
||||
{
|
||||
CheckChunk(chunkHeader, nChunkSize, NODE_CHUNK_DESC::VERSION, sizeof(NODE_CHUNK_DESC) + pChunkData->PropStrLen + sizeof(int)*pChunkData->nChildren);
|
||||
|
||||
unsigned nNodeIdx = this->arrNodes.size();
|
||||
this->mapObjectNodeIdx.insert (NodeIdxMap::value_type(pChunkData->ObjectID, nNodeIdx));
|
||||
this->mapNodeIdx.insert (NodeIdxMap::value_type(chunkHeader.ChunkID, nNodeIdx));
|
||||
this->arrNodes.push_back (NodeDesc(pChunkData));
|
||||
}
|
||||
|
||||
|
||||
void CryChunkedFile::addChunkLight (const CHUNK_HEADER& chunkHeader, const LIGHT_CHUNK_DESC* pChunkData, unsigned nChunkSize)
|
||||
{
|
||||
CheckChunk(chunkHeader, nChunkSize, LIGHT_CHUNK_DESC::VERSION, sizeof(*pChunkData));
|
||||
|
||||
this->mapLights[chunkHeader.ChunkID] = pChunkData;
|
||||
}
|
||||
|
||||
|
||||
void CryChunkedFile::addChunkMesh (const CHUNK_HEADER& chunkHeader, const MESH_CHUNK_DESC* pChunkData, unsigned nChunkSize)
|
||||
{
|
||||
CheckChunk (chunkHeader, nChunkSize, MESH_CHUNK_DESC::VERSION, sizeof(MESH_CHUNK_DESC));
|
||||
this->mapMeshIdx.insert (MeshIdxMap::value_type (chunkHeader.ChunkID, this->arrMeshes.size()));
|
||||
this->arrMeshes.push_back(MeshDesc(pChunkData, nChunkSize));
|
||||
}
|
||||
|
||||
void CryChunkedFile::addChunkBoneMesh (const CHUNK_HEADER& chunkHeader, const MESH_CHUNK_DESC* pChunkData, unsigned nChunkSize)
|
||||
{
|
||||
CheckChunk (chunkHeader, nChunkSize, MESH_CHUNK_DESC::VERSION, sizeof(MESH_CHUNK_DESC));
|
||||
this->mapBoneMeshIdx.insert (MeshIdxMap::value_type (chunkHeader.ChunkID, this->arrBoneMeshes.size()));
|
||||
this->arrBoneMeshes.push_back(MeshDesc(pChunkData, nChunkSize));
|
||||
}
|
||||
|
||||
|
||||
// this is postprocess: after all structures are in place, this function
|
||||
// sets the superfuous pointers/etc
|
||||
void CryChunkedFile::adjust()
|
||||
{
|
||||
unsigned numBones = this->Bones.numBones(), nBone, i;
|
||||
|
||||
// for each mesh, try to find and set the node
|
||||
// also remap the bone ids to bone indices
|
||||
// also recalculate
|
||||
for (i = 0; i < arrMeshes.size(); ++i)
|
||||
{
|
||||
MeshDesc& Mesh = arrMeshes[i];
|
||||
Mesh.pNode = NULL;
|
||||
if (numBones > 0)
|
||||
Mesh.remapBoneIds (this->Bones.getIdToIndexMap(),numBones);
|
||||
}
|
||||
|
||||
if (numBones != this->arrNames.size())
|
||||
{
|
||||
throw Error ("bones count (%d) is differs from names count (%d); file is corrupted.", this->Bones.numBones(), this->arrNames.size());
|
||||
}
|
||||
|
||||
// Assign a name to every bone
|
||||
for (nBone = 0; nBone < numBones; ++nBone)
|
||||
{
|
||||
unsigned nBoneId = this->Bones.mapIndexToId(nBone);
|
||||
this->Bones.m_arrBones[nBone].setName (this->arrNames[nBoneId]);
|
||||
}
|
||||
|
||||
//if (numBones)
|
||||
// computeBoneBBoxes();
|
||||
|
||||
// fill in the back-references from mesh to nodes,
|
||||
// and references from nodes to their parent and children nodes
|
||||
for (i = 0; i < arrNodes.size(); ++i)
|
||||
{
|
||||
NodeDesc* pNode = &arrNodes[i];
|
||||
MeshDesc* pMesh = GetMeshDesc (pNode->pDesc->ObjectID);
|
||||
if (pMesh)
|
||||
pMesh->pNode = pNode;
|
||||
|
||||
pNode->pParent = GetNodeDesc (pNode->pDesc->ParentID);
|
||||
pNode->arrChildren.clear();
|
||||
for (int j = 0; j < pNode->pDesc->nChildren; ++j)
|
||||
pNode->arrChildren.push_back(GetNodeDesc(pNode->pChildren[j]));
|
||||
}
|
||||
|
||||
if (!arrMeshes.empty())
|
||||
arrMeshes[0].arrMorphTargets.reserve (m_arrMorphTargetChunks.size());
|
||||
|
||||
// fill each mesh morph target array
|
||||
for (unsigned nMT = 0; nMT < m_arrMorphTargetChunks.size(); ++nMT)
|
||||
{
|
||||
const MorphTargetChunk& rChunk = m_arrMorphTargetChunks[nMT];
|
||||
MeshDesc* pMesh = GetMeshDesc(rChunk.pData->nChunkIdMesh);
|
||||
if (pMesh)
|
||||
{
|
||||
MorphTargetDesc desc;
|
||||
desc.numMorphVertices = rChunk.pData->numMorphVertices;
|
||||
desc.pMorphVertices = (const SMeshMorphTargetVertex*)(rChunk.pData+1);
|
||||
const char* pName = (const char*)(desc.pMorphVertices + desc.numMorphVertices);
|
||||
const char* pDataEnd = ((const char*)rChunk.pData) + rChunk.nSize;
|
||||
desc.strName.assign (pName, pDataEnd);
|
||||
pMesh->arrMorphTargets.push_back(desc);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// given a correct array of links and array of bones (with indices synchronized)
|
||||
// calculates for each bone description a bounding box
|
||||
/*
|
||||
void CryChunkedFile::computeBoneBBoxes()
|
||||
{
|
||||
if (this->Bones.numBones() == 0 || this->arrMeshes.empty())
|
||||
return;
|
||||
|
||||
|
||||
MeshDesc::VertBindArray::const_iterator it = arrMeshes[0].arrVertBinds.begin(), itEnd = arrMeshes[0].arrVertBinds.end();
|
||||
for (; it != itEnd; ++it)
|
||||
{
|
||||
for (CryVertexBinding::const_iterator itLink = it->begin(); itLink != it->end(); ++itLink)
|
||||
{
|
||||
CryBoneDesc& rBone = this->Bones.m_arrBones[itLink->BoneID];
|
||||
AddToBounds(itLink->offset, rBone.m_vBBMin, rBone.m_vBBMax);
|
||||
}
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
|
||||
CryChunkedFile::NodeDesc::NodeDesc (const NODE_CHUNK_DESC* pDesc)
|
||||
{
|
||||
this->pDesc = pDesc;
|
||||
|
||||
if (pDesc->nChildren)
|
||||
this->pChildren = (const int*)((const char*)(pDesc+1) + pDesc->PropStrLen);
|
||||
else
|
||||
this->pChildren = NULL;
|
||||
|
||||
//if ((pDesc->PropStrLen&3)!=0 && pDesc->nChildren)
|
||||
// throw (Error("Node chunk contains unaligned data"));
|
||||
|
||||
if (pDesc->PropStrLen)
|
||||
this->strProps.assign ((const char*)(pDesc+1), pDesc->PropStrLen);
|
||||
else
|
||||
this->strProps.erase();
|
||||
}
|
||||
|
||||
|
||||
CryChunkedFile::MeshDesc::MeshDesc (const MESH_CHUNK_DESC* pChunk, unsigned nSize):
|
||||
pVColors(NULL)
|
||||
{
|
||||
this->pNode = NULL;
|
||||
this->pDesc = pChunk; // from now on, we can use num****s() functions
|
||||
|
||||
const char* pChunkEnd = ((const char*)pChunk) + nSize;
|
||||
|
||||
this->pVertices = (const CryVertex*)(pChunk+1);
|
||||
this->pFaces = (const CryFace*)(this->pVertices + numVertices());
|
||||
|
||||
if ((const char*)(this->pFaces) > pChunkEnd)
|
||||
throw Error ("Mesh Chunk Truncated at vertex array (%d vertices expected)", numVertices());
|
||||
|
||||
this->pUVs = (const CryUV*)(this->pFaces+numFaces());
|
||||
|
||||
if ((const char*)this->pUVs > pChunkEnd)
|
||||
throw Error ("Mesh Chunk Truncated at face array (%d faces expected)", numFaces());
|
||||
|
||||
this->pTexFaces = (const CryTexFace*)(this->pUVs + numUVs());
|
||||
|
||||
if ((const char*)this->pTexFaces > pChunkEnd)
|
||||
throw Error ("Mesh Chunk Truncated at UV array (%d UVs expected)", numUVs());
|
||||
|
||||
const void* pRawData = this->pTexFaces + numTexFaces();
|
||||
|
||||
this->arrVertBinds.clear();
|
||||
if (hasBoneInfo())
|
||||
{
|
||||
this->arrVertBinds.resize (numVertices());
|
||||
|
||||
for (int i=0; i < pChunk->nVerts; i++)
|
||||
{
|
||||
// the links for the current vertex in the geometry info structure
|
||||
CryVertexBinding& arrLinks = getLink(i);
|
||||
|
||||
// read the number of links and initialize the link array
|
||||
{
|
||||
// the number of links for the current vertex
|
||||
unsigned numLinks;
|
||||
if (!EatRawData (&numLinks, 1, pRawData, nSize))
|
||||
throw Error("Truncated vertex link array");
|
||||
|
||||
if(numLinks > 32u)
|
||||
throw Error("Number of links for vertex (%u) is invalid", numLinks);
|
||||
|
||||
arrLinks.resize(numLinks);
|
||||
}
|
||||
|
||||
if (arrLinks.empty())
|
||||
{
|
||||
//throw("File contains unbound vertices");
|
||||
// if we choose not to throw, bind the unbound vertices to the root bone
|
||||
arrLinks.resize(1);
|
||||
arrLinks[0].Blending = 1;
|
||||
arrLinks[0].BoneID = 0;
|
||||
arrLinks[0].offset = Vec3d (0,0,0);
|
||||
continue;
|
||||
}
|
||||
else {
|
||||
|
||||
u32 size = arrLinks.size();
|
||||
|
||||
if (!EatRawData(&arrLinks[0], arrLinks.size(), pRawData, nSize))
|
||||
throw Error("Truncated vertex link array");
|
||||
|
||||
//---------------------------------------------------
|
||||
//changes to optimize skinning added by ivo
|
||||
//---------------------------------------------------
|
||||
for (u32 x=0; x<size; x++) {
|
||||
for (u32 y=x+1; y<size; y++) {
|
||||
if (arrLinks[x].BoneID==arrLinks[y].BoneID) {
|
||||
//add blending of same bone to 1st found bone in list;
|
||||
arrLinks[x].Blending+=arrLinks[y].Blending;
|
||||
//remove link from the list;
|
||||
for (u32 z=y; z<size; z++) arrLinks[z]=arrLinks[z+1];
|
||||
arrLinks.pop_back();
|
||||
size = arrLinks.size();
|
||||
y--;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------
|
||||
|
||||
if (size==1) { arrLinks[0].Blending=1.0f; }
|
||||
else
|
||||
{
|
||||
//loop over all vertices and check for "minimal" blending vlaues
|
||||
for (u32 i=0; i<size; i++)
|
||||
{
|
||||
float minval=0.12f;
|
||||
float f=arrLinks[i].Blending;
|
||||
if (f<(0.0f+minval)) arrLinks[i].Blending=0.0f;
|
||||
if (f>(1.0f-minval)) arrLinks[i].Blending=1.0f;
|
||||
}
|
||||
|
||||
for (u32 x=0; x<size; x++)
|
||||
{
|
||||
if (arrLinks[x].Blending==0.0f)
|
||||
{
|
||||
//remove link from the list;
|
||||
for (u32 z=x; z<size; z++) arrLinks[z]=arrLinks[z+1];
|
||||
arrLinks.pop_back();
|
||||
size = arrLinks.size();
|
||||
x--;
|
||||
}
|
||||
}
|
||||
|
||||
float t=0;
|
||||
//sum up all blending values
|
||||
for (u32 i=0; i<size; i++) t+=arrLinks[i].Blending;
|
||||
//normalized blending
|
||||
for (u32 i=0; i<size; i++) arrLinks[i].Blending/=t;
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
|
||||
//check if summed blending of all bones is 1.0f
|
||||
float Blending=0;
|
||||
for (u32 i=0; i<size; i++) Blending+=arrLinks[i].Blending;
|
||||
|
||||
assert( fabsf(Blending-1.0f)<0.005f );
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
if (pChunk->HasVertexCol)
|
||||
{
|
||||
this->pVColors = (const CryIRGB*)pRawData;
|
||||
if (nSize < pChunk->nVerts * sizeof(CryIRGB))
|
||||
throw Error ("Vertex Color chunk is truncated: %d bytes expected, %d bytes available", pChunk->nVerts * sizeof(CryIRGB), nSize);
|
||||
}
|
||||
else
|
||||
this->pVColors = NULL;
|
||||
|
||||
validateIndices();
|
||||
buildReconstructedNormals();
|
||||
}
|
||||
|
||||
|
||||
// returns node pointer by the node chunk id; if chunkid is not node , returns NULL
|
||||
CryChunkedFile::NodeDesc* CryChunkedFile::GetNodeDesc (unsigned nChunkId)
|
||||
{
|
||||
NodeIdxMap::const_iterator it = this->mapNodeIdx.find (nChunkId);
|
||||
if (it == this->mapNodeIdx.end())
|
||||
return NULL;
|
||||
return &this->arrNodes[it->second];
|
||||
}
|
||||
|
||||
// returns node pointer by the object (to which the node refers, and which should refer back to node) id
|
||||
// if can't find it, returns NULL
|
||||
CryChunkedFile::NodeDesc* CryChunkedFile::GetObjectNodeDesc (unsigned nObjectId)
|
||||
{
|
||||
NodeIdxMap::const_iterator it = this->mapObjectNodeIdx.find (nObjectId);
|
||||
if (it == this->mapObjectNodeIdx.end())
|
||||
return NULL;
|
||||
return &this->arrNodes[it->second];
|
||||
}
|
||||
|
||||
// returns light pointer by the light chunk id.
|
||||
// returns NULL on failure
|
||||
const LIGHT_CHUNK_DESC* CryChunkedFile::GetLightDesc (unsigned nChunkId)
|
||||
{
|
||||
LightMap::iterator it = this->mapLights.find (nChunkId);
|
||||
if (it == this->mapLights.end())
|
||||
return NULL;
|
||||
return it->second;
|
||||
}
|
||||
|
||||
|
||||
// returns mesh pointer by the mesh chunk id
|
||||
CryChunkedFile::MeshDesc* CryChunkedFile::GetMeshDesc (unsigned nChunkId)
|
||||
{
|
||||
MeshIdxMap::const_iterator it = this->mapMeshIdx.find (nChunkId);
|
||||
if (it == this->mapMeshIdx.end())
|
||||
return NULL;
|
||||
return &this->arrMeshes[it->second];
|
||||
}
|
||||
|
||||
// returns mesh pointer by the mesh chunk id
|
||||
CryChunkedFile::MeshDesc* CryChunkedFile::GetBoneMeshDesc (unsigned nChunkId)
|
||||
{
|
||||
MeshIdxMap::const_iterator it = this->mapBoneMeshIdx.find (nChunkId);
|
||||
if (it == this->mapBoneMeshIdx.end())
|
||||
return NULL;
|
||||
return &this->arrBoneMeshes[it->second];
|
||||
}
|
||||
|
||||
bool CryChunkedFile::DoesMtlCastShadow(int nMtl)
|
||||
{
|
||||
if (nMtl < 0 || (unsigned)nMtl >= this->arrMtls.size())
|
||||
return true;
|
||||
|
||||
if (this->arrMtls[nMtl].Dyn_StaticFriction == 1)
|
||||
return false; //doesn't cast shadow
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
void CryChunkedFile::addChunkMaterial (const CHUNK_HEADER& chunkHeader, const void* pChunkData, unsigned nChunkSize)
|
||||
{
|
||||
MAT_ENTITY me;
|
||||
|
||||
MatChunkLoadErrorEnum nError = LoadMatEntity (chunkHeader, pChunkData, nChunkSize, me);
|
||||
|
||||
switch(nError)
|
||||
{
|
||||
case MCLE_Success:
|
||||
this->arrMtls.push_back(me);
|
||||
break;
|
||||
case MCLE_IgnoredType:
|
||||
break;
|
||||
case MCLE_Truncated:
|
||||
throw Error ("Material chunk 0x%X is truncated (%d bytes)", chunkHeader.ChunkID, nChunkSize);
|
||||
break;
|
||||
case MCLE_UnknownVersion:
|
||||
throw Error ("Material chunk 0x%X is unknown version 0x%X", chunkHeader.ChunkID, chunkHeader.ChunkVersion);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void CryChunkedFile::addChunkBoneNameList (const CHUNK_HEADER& chunkHeader, const void* pChunkData, unsigned nChunkSize)
|
||||
{
|
||||
if (!LoadBoneNameList(chunkHeader, pChunkData, nChunkSize, this->arrNames))
|
||||
throw Error ("Cannot load bone name list");
|
||||
}
|
||||
|
||||
|
||||
void CryChunkedFile::addChunkBoneInitialPos (const CHUNK_HEADER& chunkHeader, const BONEINITIALPOS_CHUNK_DESC_0001* pChunkData, unsigned nChunkSize)
|
||||
{
|
||||
if (chunkHeader.ChunkVersion != pChunkData->VERSION)
|
||||
throw Error ("Unexpected BoneInitialPos chunk version 0x%X", chunkHeader.ChunkVersion);
|
||||
|
||||
unsigned numBytesRead = this->Bones.load (pChunkData, nChunkSize);
|
||||
if (numBytesRead != nChunkSize)
|
||||
throw Error ("Can't read BoneInitialPos chunk: %d bytes parsed instead of %d", numBytesRead, nChunkSize);
|
||||
}
|
||||
|
||||
void CryChunkedFile::addChunkMeshMorphTarget (const CHUNK_HEADER& chunkHeader, const MESHMORPHTARGET_CHUNK_DESC_0001* pChunkData, unsigned nChunkSize)
|
||||
{
|
||||
if (chunkHeader.ChunkVersion != pChunkData->VERSION)
|
||||
throw Error ("Unexpected MeshMorphTarget chunk version 0x%X", chunkHeader.ChunkVersion);
|
||||
|
||||
if (nChunkSize < sizeof(*pChunkData))
|
||||
throw Error ("Truncated MeshMorphTarget chunk header");
|
||||
|
||||
if (nChunkSize < sizeof(*pChunkData) + pChunkData->numMorphVertices*sizeof(SMeshMorphTargetVertex))
|
||||
throw Error ("Truncated MeshMorphTarget chunk data");
|
||||
|
||||
MorphTargetChunk Chunk;
|
||||
Chunk.nSize = nChunkSize;
|
||||
Chunk.pData = pChunkData;
|
||||
m_arrMorphTargetChunks.push_back (Chunk);
|
||||
}
|
||||
|
||||
|
||||
void CryChunkedFile::addChunkBoneAnim (const CHUNK_HEADER& chunkHeader, const BONEANIM_CHUNK_DESC* pChunkData, unsigned nChunkSize)
|
||||
{
|
||||
if (nChunkSize < sizeof(*pChunkData))
|
||||
throw Error ("Truncated BoneAnim chunk header: %d bytes", nChunkSize);
|
||||
if (pChunkData->VERSION != pChunkData->chdr.ChunkVersion)
|
||||
throw Error ("Unexpected BoneAnim chunk version 0x%X", pChunkData->chdr.ChunkVersion);
|
||||
if (nChunkSize < sizeof(*pChunkData) + sizeof(BONE_ENTITY)*pChunkData->nBones)
|
||||
throw Error ("Truncated BoneAnim chunk: %d bytes, %d bones", nChunkSize, pChunkData->nBones);
|
||||
|
||||
unsigned numBytesRead = this->Bones.load(pChunkData, nChunkSize);
|
||||
if (numBytesRead != nChunkSize)
|
||||
throw Error ("Can't read BoneAnim chunk: %d bytes parsed (%d total bytes)", numBytesRead, nChunkSize);
|
||||
if (this->Bones.m_arrBones.size() != pChunkData->nBones)
|
||||
throw Error ("Unexpected number of bones in BoneAnim chunk: %d claimed, %d loaded", pChunkData->nBones, this->Bones.m_arrBones.size());
|
||||
|
||||
// update the bone physics as if it were LOD 0
|
||||
BONE_ENTITY* pBoneEntities = (BONE_ENTITY*)(pChunkData+1);
|
||||
for (int nId = 0; nId < pChunkData->nBones; ++nId)
|
||||
{
|
||||
int nIndex = this->Bones.mapIdToIndex(nId);
|
||||
this->Bones.m_arrBones[nIndex].UpdatePhysics(pBoneEntities[nId], 0);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void CryChunkedFile::addChunkBoneLightBinding (
|
||||
const CHUNK_HEADER& chunkHeader,
|
||||
const BONELIGHTBINDING_CHUNK_DESC_0001* pChunkData,
|
||||
unsigned nChunkSize)
|
||||
{
|
||||
if (m_pBoneLightBind)
|
||||
throw Error ("There are multiple BoneLightBinding chunks in the file. This is not supported at the moment.");
|
||||
|
||||
if (pChunkData->numBindings > (unsigned)m_pFile->numChunks())
|
||||
throw Error ("BoneLightBinding chunk has invalid number of bindings declared (%d)", pChunkData->numBindings);
|
||||
|
||||
unsigned numExpectedBytes = pChunkData->numBindings * sizeof(SBoneLightBind) + sizeof(*pChunkData);
|
||||
if (numExpectedBytes != nChunkSize)
|
||||
throw Error ("BoneLightBinding chunk has unexpected length (%d instead of %d)", nChunkSize, numExpectedBytes);
|
||||
|
||||
m_pBoneLightBind = (const SBoneLightBind*)(pChunkData + 1);
|
||||
m_numBoneLightBinds = pChunkData->numBindings;
|
||||
}
|
||||
|
||||
void CryChunkedFile::addChunkSceneProps (const CHUNK_HEADER& chunkHeader, const SCENEPROPS_CHUNK_DESC*pChunkData, unsigned nChunkSize)
|
||||
{
|
||||
if (nChunkSize < sizeof(*pChunkData) )
|
||||
throw Error ("Truncated SCENEPROPS_CHUNK_DESC chunk header (%d bytes, at least %d expected)", nChunkSize, sizeof(*pChunkData));
|
||||
if (nChunkSize < sizeof(*pChunkData) + sizeof(SCENEPROP_ENTITY) * pChunkData->nProps)
|
||||
throw Error ("Truncated SCENEPROPS_CHUNK_DESC chunk, %d props, %d bytes, %d expected", pChunkData->nProps, nChunkSize , sizeof(*pChunkData) + sizeof(SCENEPROP_ENTITY) * pChunkData->nProps);
|
||||
this->numSceneProps = pChunkData->nProps;
|
||||
this->pSceneProps = (const SCENEPROP_ENTITY*)(pChunkData+1);
|
||||
}
|
||||
|
||||
|
||||
CryChunkedFile::Error::Error(const char* szFormat, ...)
|
||||
{
|
||||
va_list args;
|
||||
va_start (args,szFormat);
|
||||
char szBuf[0x1000];
|
||||
_vsnprintf (szBuf, sizeof(szBuf), szFormat, args);
|
||||
va_end (args);
|
||||
this->strDesc = szBuf;
|
||||
}
|
||||
|
||||
// remaps the bone ids using the given transmutation from old to new
|
||||
void CryChunkedFile::MeshDesc::remapBoneIds(const int* pPermutation, unsigned numBones)
|
||||
{
|
||||
VertBindArray::iterator it;
|
||||
for (it = this->arrVertBinds.begin(); it != this->arrVertBinds.end(); ++it)
|
||||
it->remapBoneIds((unsigned*)pPermutation, numBones);
|
||||
}
|
||||
|
||||
// recalculates (if necessary) the normals of the mesh and returns
|
||||
// the pointer tot he array of recalculated normals
|
||||
void CryChunkedFile::MeshDesc::buildReconstructedNormals()
|
||||
{
|
||||
// recalculate the normals
|
||||
this->arrNormals.resize (numVertices());
|
||||
memset (&this->arrNormals[0], 0, sizeof(Vec3d)*numVertices());
|
||||
for (unsigned nFace = 0; nFace < numFaces(); ++nFace)
|
||||
{
|
||||
const CryFace& Face = this->pFaces[nFace];
|
||||
Vec3d v1, v2, vTmpNormal;
|
||||
v1 = this->pVertices[Face.v0].p - this->pVertices[Face.v1].p;
|
||||
v2 = this->pVertices[Face.v0].p - this->pVertices[Face.v2].p;
|
||||
vTmpNormal = v1 ^ v2;
|
||||
this->arrNormals[Face.v0] += vTmpNormal;
|
||||
this->arrNormals[Face.v1] += vTmpNormal;
|
||||
this->arrNormals[Face.v2] += vTmpNormal;
|
||||
}
|
||||
for (unsigned nVertex=0; nVertex < numVertices(); ++nVertex)
|
||||
{
|
||||
Vec3d& vN = this->arrNormals[nVertex];
|
||||
float fLength = vN.Length();
|
||||
if (fLength < 1e-3)
|
||||
vN = Vec3d(0,1,0);
|
||||
else
|
||||
vN /= fLength;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// validates the indices of the mesh. if there are some indices out of range,
|
||||
// throws an appropriate exception
|
||||
void CryChunkedFile::MeshDesc::validateIndices()
|
||||
{
|
||||
for (unsigned nFace = 0; nFace < numFaces(); ++nFace)
|
||||
{
|
||||
const CryFace& Face = this->pFaces[nFace];
|
||||
if (Face.v0 < 0 || (unsigned)Face.v0 >= numVertices()
|
||||
||Face.v1 < 0 || (unsigned)Face.v1 >= numVertices()
|
||||
||Face.v2 < 0 || (unsigned)Face.v2 >= numVertices())
|
||||
throw Error("Face %d (v={%d,%d,%d}) has one or more indices out of range (%d vertices in the mesh)",
|
||||
nFace, Face.v0, Face.v1, Face.v2, numVertices());
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
238
ResourceCompiler/CryChunkedFile.h
Normal file
238
ResourceCompiler/CryChunkedFile.h
Normal file
@@ -0,0 +1,238 @@
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Crytek Engine Source File.
|
||||
// Copyright (C), Crytek Studios, 2003.
|
||||
// -------------------------------------------------------------------------
|
||||
// File name: CryChunkedFile.h
|
||||
// Version: v1.00
|
||||
// Created: 13.01.2003 by Sergiy.
|
||||
// Compilers: Visual Studio.NET
|
||||
// Description: CryChunkedFile structure with substructures. It contains
|
||||
// everything about c?f file, in ready parsed form
|
||||
// -------------------------------------------------------------------------
|
||||
// History:
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifndef __crychunkedfile_h__
|
||||
#define __crychunkedfile_h__
|
||||
|
||||
#include "ChunkFileReader.h"
|
||||
#include "CryVertexBinding.h"
|
||||
#include "CryBoneHierarchyLoader.h"
|
||||
|
||||
|
||||
// The mesh bone links contain bone indices (not ids)
|
||||
// The CryBoneDesc array contains the physics in LOD0 only
|
||||
//
|
||||
struct CryChunkedFile:public _reference_target_t
|
||||
{
|
||||
class Error
|
||||
{
|
||||
public:
|
||||
Error (const char* szFormat, ...);
|
||||
string strDesc;
|
||||
};
|
||||
|
||||
// parses the given chunked file into the internal structure;
|
||||
// outputs warnings if some of the chunks are incomplete or otherwise broken
|
||||
CryChunkedFile(CChunkFileReader* pFile);
|
||||
|
||||
// ChunkType_Timing
|
||||
// NULL if no timing chunk was found
|
||||
const TIMING_CHUNK_DESC* pTiming;
|
||||
// the range entities following the timing chunk. There are (pTiming->nSubRanges) of them
|
||||
const RANGE_ENTITY* pRangeEntities;
|
||||
|
||||
// the file header
|
||||
const FILE_HEADER* pFileHeader;
|
||||
|
||||
// the file type
|
||||
int GetFileType ()const {return /*(FileTypes)*/pFileHeader->FileType;}
|
||||
|
||||
// the array of nodes
|
||||
struct NodeDesc
|
||||
{
|
||||
NodeDesc ():pDesc(NULL), pChildren (NULL){}
|
||||
NodeDesc (const NODE_CHUNK_DESC*);
|
||||
|
||||
const NODE_CHUNK_DESC* pDesc;
|
||||
// array of chunk ids; there are pDesc->nChildren of them
|
||||
const int* pChildren;
|
||||
// the property string
|
||||
string strProps;
|
||||
|
||||
// array of children nodes (superfluous)
|
||||
std::vector <NodeDesc*> arrChildren;
|
||||
// pointer to the parent node (superfluous)
|
||||
NodeDesc* pParent;
|
||||
|
||||
Matrix44 getWorldTransform()const
|
||||
{
|
||||
if (pParent)
|
||||
return pDesc->tm * pParent->getWorldTransform();
|
||||
else
|
||||
return pDesc->tm;
|
||||
}
|
||||
};
|
||||
std::vector<NodeDesc> arrNodes;
|
||||
|
||||
// map: chunk id (node chunk id) -> index in arrNodes array
|
||||
typedef std::map<unsigned, unsigned> UintUintMap;
|
||||
typedef UintUintMap NodeIdxMap;
|
||||
NodeIdxMap mapNodeIdx,mapObjectNodeIdx;
|
||||
// map of light chunks
|
||||
typedef std::map<unsigned, const LIGHT_CHUNK_DESC*> LightMap;
|
||||
LightMap mapLights;
|
||||
|
||||
// returns node pointer by the node chunk id; if chunkid is not node , returns NULL
|
||||
virtual NodeDesc* GetNodeDesc (unsigned nChunkId);
|
||||
// returns node pointer by the object (to which the node refers, and which should refer back to node) id
|
||||
// if can't find it, returns NULL
|
||||
virtual NodeDesc* GetObjectNodeDesc (unsigned nObjectId);
|
||||
|
||||
// returns light pointer by the light chunk id.
|
||||
// returns NULL on failure
|
||||
virtual const LIGHT_CHUNK_DESC* GetLightDesc (unsigned nChunkId);
|
||||
|
||||
// given a correct array of links and array of bones (with indices synchronized)
|
||||
// calculates for each bone description a bounding box
|
||||
void computeBoneBBoxes();
|
||||
|
||||
|
||||
// the structure describing the morph target
|
||||
struct MorphTargetDesc
|
||||
{
|
||||
unsigned numMorphVertices;
|
||||
const SMeshMorphTargetVertex* pMorphVertices;
|
||||
string strName;
|
||||
};
|
||||
|
||||
// NOTE: the bone ids in the CryLinks are the bone indices after this all has been loaded (remapped
|
||||
// from within adjust() function)
|
||||
struct MeshDesc
|
||||
{
|
||||
MeshDesc (): pDesc (NULL), pNode (NULL) {}
|
||||
|
||||
MeshDesc (const MESH_CHUNK_DESC* pChunk, unsigned nSize);
|
||||
|
||||
// back-reference to the node referencing to this mesh (superfluous)
|
||||
const NodeDesc* pNode;
|
||||
|
||||
const MESH_CHUNK_DESC* pDesc;
|
||||
|
||||
// array of pDesc->nVerts vertices
|
||||
unsigned numVertices() const {return (unsigned)pDesc->nVerts;}
|
||||
const CryVertex* pVertices;
|
||||
|
||||
// array of pDesc->nFaces faces
|
||||
unsigned numFaces() const {return (unsigned)pDesc->nFaces;}
|
||||
const CryFace* pFaces;
|
||||
|
||||
// array of pDesc->nTVerts
|
||||
unsigned numUVs() const {return (unsigned)pDesc->nTVerts;}
|
||||
const CryUV* pUVs;
|
||||
|
||||
// array of texture faces; present only when there are UVs
|
||||
unsigned numTexFaces () const {return (unsigned)(pDesc->nTVerts?pDesc->nFaces:0);}
|
||||
const CryTexFace* pTexFaces;
|
||||
|
||||
// answers the question: has this mesh chunk bone info (links with offsets and weights for each vertex)?
|
||||
// if yes, arrVertBinds will contain them
|
||||
bool hasBoneInfo()const {return this->pDesc->HasBoneInfo;}
|
||||
// the actual binding to bones
|
||||
typedef std::vector<CryVertexBinding> VertBindArray;
|
||||
VertBindArray arrVertBinds;
|
||||
CryVertexBinding& getLink(unsigned i) {return arrVertBinds[i];}
|
||||
|
||||
// answers the question: has this mesh vertex colors?
|
||||
bool hasVertColors()const {return this->pDesc->HasVertexCol;}
|
||||
const CryIRGB* pVColors;
|
||||
|
||||
// remaps the bone ids using the given transmutation from old to new
|
||||
void remapBoneIds(const int* pPermutation, unsigned numBones);
|
||||
|
||||
// validates the indices of the mesh. if there are some indices out of range,
|
||||
// throws an appropriate exception
|
||||
void validateIndices();
|
||||
|
||||
// recalculates the normals of the mesh and returns
|
||||
// the pointer tot he array of recalculated normals
|
||||
void buildReconstructedNormals();
|
||||
|
||||
// this is the array of normals calculated on demand
|
||||
std::vector<Vec3d> arrNormals;
|
||||
|
||||
std::vector<MorphTargetDesc>arrMorphTargets;
|
||||
};
|
||||
std::vector<MeshDesc> arrMeshes;
|
||||
std::vector<MeshDesc> arrBoneMeshes;
|
||||
|
||||
struct MorphTargetChunk
|
||||
{
|
||||
const MESHMORPHTARGET_CHUNK_DESC_0001* pData;
|
||||
unsigned nSize;
|
||||
};
|
||||
std::vector<MorphTargetChunk> m_arrMorphTargetChunks;
|
||||
|
||||
// map: from mesh ChunkId to index in arrMeshes array (or arrBoneMeshes for mapBoneMeshIdx)
|
||||
typedef UintUintMap MeshIdxMap;
|
||||
MeshIdxMap mapMeshIdx, mapBoneMeshIdx;
|
||||
|
||||
// returns mesh pointer by the mesh chunk id
|
||||
// returns NULL if error
|
||||
virtual MeshDesc* GetMeshDesc (unsigned nChunkId);
|
||||
|
||||
// returns mesh pointer by the mesh chunk id
|
||||
// returns NULL if error
|
||||
virtual MeshDesc* GetBoneMeshDesc (unsigned nChunkId);
|
||||
|
||||
std::vector<MAT_ENTITY> arrMtls;
|
||||
|
||||
virtual bool DoesMtlCastShadow(int nMtl);
|
||||
|
||||
// the array of bone names from the corresponding chunk ; these get assigned to the CryBoneDesc's
|
||||
// in the final step (adjust())
|
||||
std::vector<const char*> arrNames;
|
||||
|
||||
// the bone loader, providing info about the bones
|
||||
CryBoneHierarchyLoader Bones;
|
||||
|
||||
// bone-light bindings
|
||||
unsigned m_numBoneLightBinds;
|
||||
const SBoneLightBind* m_pBoneLightBind;
|
||||
|
||||
bool IsBoneInitialPosPresent() {return Bones.hasInitPos();}
|
||||
|
||||
unsigned numSceneProps;
|
||||
const SCENEPROP_ENTITY* pSceneProps;
|
||||
|
||||
// chunk parsers, each parses its chunk into the internal structures of this object
|
||||
protected:
|
||||
void addChunkTiming (const CHUNK_HEADER& chunkHeader, const TIMING_CHUNK_DESC* pChunkData, unsigned nChunkSize);
|
||||
void addChunkNode (const CHUNK_HEADER& chunkHeader, const NODE_CHUNK_DESC* pChunkData, unsigned nChunkSize);
|
||||
void addChunkLight (const CHUNK_HEADER& chunkHeader, const LIGHT_CHUNK_DESC* pChunkData, unsigned nChunkSize);
|
||||
void addChunkMesh (const CHUNK_HEADER& chunkHeader, const MESH_CHUNK_DESC* pChunkData, unsigned nChunkSize);
|
||||
void addChunkBoneMesh (const CHUNK_HEADER& chunkHeader, const MESH_CHUNK_DESC* pChunkData, unsigned nChunkSize);
|
||||
void addChunkMaterial (const CHUNK_HEADER& chunkHeader, const void* pChunkData, unsigned nChunkSize);
|
||||
void addChunkBoneNameList (const CHUNK_HEADER& chunkHeader, const void* pChunkData, unsigned nChunkSize);
|
||||
void addChunkBoneAnim (const CHUNK_HEADER& chunkHeader, const BONEANIM_CHUNK_DESC* pChunkData, unsigned nChunkSize);
|
||||
void addChunkBoneInitialPos (const CHUNK_HEADER& chunkHeader, const BONEINITIALPOS_CHUNK_DESC_0001* pChunkData, unsigned nChunkSize);
|
||||
void addChunkMeshMorphTarget (const CHUNK_HEADER& chunkHeader, const MESHMORPHTARGET_CHUNK_DESC_0001* pChunkData, unsigned nChunkSize);
|
||||
void addChunkBoneLightBinding (const CHUNK_HEADER& chunkHeader, const BONELIGHTBINDING_CHUNK_DESC_0001* pChunkData, unsigned nChunkSize);
|
||||
void addChunkSceneProps(const CHUNK_HEADER& chunkHeader, const SCENEPROPS_CHUNK_DESC*pChunkData, unsigned nChunkSize);
|
||||
|
||||
// this is postprocess: after all structures are in place, this function
|
||||
// sets the superfuous pointers/etc
|
||||
void adjust();
|
||||
protected:
|
||||
// releases all the internally referenced structures
|
||||
// the clients of this class should release it via Release() method
|
||||
virtual ~CryChunkedFile();
|
||||
|
||||
CChunkFileReader_AutoPtr m_pFile;
|
||||
};
|
||||
|
||||
TYPEDEF_AUTOPTR (CryChunkedFile);
|
||||
|
||||
#endif
|
||||
128
ResourceCompiler/CryVertexBinding.cpp
Normal file
128
ResourceCompiler/CryVertexBinding.cpp
Normal file
@@ -0,0 +1,128 @@
|
||||
#include "stdafx.h"
|
||||
#include "CryVertexBinding.h"
|
||||
|
||||
|
||||
CryVertexBinding::CryVertexBinding()
|
||||
#ifdef DEBUG_STD_CONTAINERS
|
||||
:std::vector<CryLink>("CryVertexBinding")
|
||||
#endif
|
||||
{
|
||||
}
|
||||
|
||||
// normalizes the weights of links so that they sum up to 1
|
||||
void CryVertexBinding::normalizeBlendWeights()
|
||||
{
|
||||
// renormalize blending
|
||||
float fBlendSumm = 0;
|
||||
unsigned j;
|
||||
for (j = 0; j < size(); j++)
|
||||
fBlendSumm += (*this)[j].Blending;
|
||||
|
||||
assert (fBlendSumm > 0.1f && fBlendSumm <=1.001f);
|
||||
|
||||
for (j=0; j<size(); j++)
|
||||
(*this)[j].Blending /= fBlendSumm;
|
||||
}
|
||||
|
||||
|
||||
// prunes the weights that are less than the specified minimal blending factor
|
||||
// ASSUMES: that the links are already sorted by the blending factors in descending order
|
||||
void CryVertexBinding::pruneSmallWeights(float fMinBlending, unsigned numMinLinks)
|
||||
{
|
||||
// remove 0 blending links and merge the links to the same bones
|
||||
unsigned j;
|
||||
for (j = numMinLinks; j < size(); j++)
|
||||
{
|
||||
assert (j == 0 || (*this)[j].Blending <= (*this)[j-1].Blending);
|
||||
if((*this)[j].Blending <= fMinBlending)
|
||||
{
|
||||
resize(j);
|
||||
assert(j);
|
||||
break;
|
||||
}
|
||||
}
|
||||
/*
|
||||
// the links to delete
|
||||
std::set<unsigned> setToDel;
|
||||
for (i = 0; i < size()-1; ++i)
|
||||
for (j = i+1; j < size(); ++j)
|
||||
if ((*this)[i].BoneID == (*this)[j].BoneID)
|
||||
setToDel.insert (j);
|
||||
|
||||
// delete
|
||||
for (std::set<unsigned>::reverse_iterator it = setToDel.rbegin(); it != setToDel.rend(); ++it)
|
||||
this->erase (*it);
|
||||
*/
|
||||
}
|
||||
|
||||
|
||||
// remaps the bone ids
|
||||
void CryVertexBinding::remapBoneIds (const unsigned* arrBoneIdMap, unsigned numBoneIds)
|
||||
{
|
||||
for (iterator it = begin(); it != end(); ++it)
|
||||
{
|
||||
// if you get this assert, most probably there is dissynchronization between different LODs of the same model
|
||||
// - all of them must be exported with exactly the same skeletons.
|
||||
if(it->BoneID >= 0 && it->BoneID < (int)numBoneIds)
|
||||
it->BoneID = arrBoneIdMap[it->BoneID];
|
||||
else
|
||||
{
|
||||
#ifdef _CRY_ANIMATION_BASE_HEADER_
|
||||
g_GetLog()->LogError ("\001bone index is out of range");
|
||||
#endif
|
||||
it->BoneID = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// scales all the link offsets multiplying the offset by the given scale
|
||||
void CryVertexBinding::scaleOffsets(float fScale)
|
||||
{
|
||||
for (iterator itLink = begin(); itLink != end(); ++itLink)
|
||||
itLink->offset *= fScale;
|
||||
}
|
||||
|
||||
|
||||
// sorts the links by the blending factor, descending order
|
||||
void CryVertexBinding::sortByBlendingDescending()
|
||||
{
|
||||
// sort the links by blend factor to allow skip unimportant ones
|
||||
std::sort (begin(), end(), CryLinkOrderByBlending());
|
||||
}
|
||||
|
||||
// returns the maximum BoneID in the array of links
|
||||
unsigned CryVertexBinding::maxBoneID ()const
|
||||
{
|
||||
unsigned nResult = 0;
|
||||
for (unsigned i = 0; i < this->size(); ++i)
|
||||
nResult = max((unsigned)(*this)[i].BoneID, nResult);
|
||||
return nResult;
|
||||
}
|
||||
|
||||
// returns the minimal BoneID in the array of links
|
||||
unsigned CryVertexBinding::minBoneID () const
|
||||
{
|
||||
unsigned nResult = (unsigned)(*this)[0].BoneID;
|
||||
for (unsigned i = 1; i < this->size(); ++i)
|
||||
nResult = min((unsigned)(*this)[i].BoneID, nResult);
|
||||
return nResult;
|
||||
}
|
||||
|
||||
// returns the link weight to the given bone
|
||||
float CryVertexBinding::getBoneWeight (int nBoneID)const
|
||||
{
|
||||
for (unsigned i = 0; i < this->size(); ++i)
|
||||
if ((*this)[i].BoneID == nBoneID)
|
||||
return (*this)[i].Blending;
|
||||
return 0;
|
||||
}
|
||||
|
||||
// returns true if there is such bone weight
|
||||
bool CryVertexBinding::hasBoneWeight (int nBoneID, float fWeight) const
|
||||
{
|
||||
for (unsigned i = 0; i < this->size(); ++i)
|
||||
if ((*this)[i].BoneID == nBoneID && (*this)[i].Blending == fWeight)
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
48
ResourceCompiler/CryVertexBinding.h
Normal file
48
ResourceCompiler/CryVertexBinding.h
Normal file
@@ -0,0 +1,48 @@
|
||||
/////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Crytek Character Animation source code
|
||||
//
|
||||
// History:
|
||||
// 11/05/2002 - Created by Sergiy Migdalskiy <sergiy@crytek.de>
|
||||
//
|
||||
// Contains:
|
||||
// Declaration of CryVertexBinding, a class incapsulating the array of links of a vertex to bone.
|
||||
// This class is only used during construction of the geometry, and shouldn't be used for
|
||||
// calculating the actual skin in the run time.
|
||||
/////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifndef _CRY_VERTEX_BINDING_HDR_
|
||||
#define _CRY_VERTEX_BINDING_HDR_
|
||||
|
||||
// array of crylinks for one vertex
|
||||
class CryVertexBinding: public std::vector<CryLink>
|
||||
{
|
||||
public:
|
||||
CryVertexBinding ();
|
||||
// scales all the link offsets multiplying the offset by the given scale
|
||||
void scaleOffsets(float fScale);
|
||||
// sorts the links by the blending factor, descending order
|
||||
void sortByBlendingDescending();
|
||||
// normalizes the weights of links so that they sum up to 1
|
||||
void normalizeBlendWeights();
|
||||
// prunes the weights that are less than the specified minimal blending factor.
|
||||
// Leaves (unpruned) at least the first numMinLinks links
|
||||
// ASSUMES:that the links are already sorted by the blending factors in descending order
|
||||
void pruneSmallWeights(float fMinBlending, unsigned numMinLinks = 1);
|
||||
// remaps the bone ids
|
||||
void remapBoneIds (const unsigned* arrBoneIdMap, unsigned numBoneIds);
|
||||
|
||||
// returns the maximum BoneID in the array of links
|
||||
unsigned maxBoneID ()const;
|
||||
// returns the minimal BoneID in the array of links
|
||||
unsigned minBoneID () const;
|
||||
|
||||
// returns the link weight to the given bone
|
||||
float getBoneWeight (int nBoneID) const;
|
||||
|
||||
// returns true if there is such bone weight
|
||||
bool hasBoneWeight (int nBoneID, float fWeight) const;
|
||||
};
|
||||
|
||||
|
||||
#endif
|
||||
19
ResourceCompiler/DebugLog.h
Normal file
19
ResourceCompiler/DebugLog.h
Normal file
@@ -0,0 +1,19 @@
|
||||
#ifndef _RC_DEBUG_LOG_HDR_
|
||||
#define _RC_DEBUG_LOG_HDR_
|
||||
|
||||
inline void DebugLog (const char* szFormat, ...)
|
||||
{
|
||||
FILE* f = fopen ("Rc.Debug.log", "wa");
|
||||
if (!f)
|
||||
return;
|
||||
va_list args;
|
||||
va_start (args, szFormat);
|
||||
vfprintf (f, szFormat, args);
|
||||
fprintf (f, "\n");
|
||||
vprintf (szFormat, args);
|
||||
printf ("\n");
|
||||
va_end(args);
|
||||
fclose (f);
|
||||
}
|
||||
|
||||
#endif
|
||||
129
ResourceCompiler/ExtensionManager.cpp
Normal file
129
ResourceCompiler/ExtensionManager.cpp
Normal file
@@ -0,0 +1,129 @@
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Crytek Engine Source File.
|
||||
// Copyright (C), Crytek Studios, 2002.
|
||||
// -------------------------------------------------------------------------
|
||||
// File name: extensionmanager.cpp
|
||||
// Version: v1.00
|
||||
// Created: 5/11/2002 by Timur.
|
||||
// Compilers: Visual Studio.NET
|
||||
// Description:
|
||||
// -------------------------------------------------------------------------
|
||||
// History:
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include "StdAfx.h"
|
||||
#include <time.h>
|
||||
#include "ExtensionManager.h"
|
||||
#include "IConvertor.h"
|
||||
#include "IResCompiler.h" // IResourceCompiler
|
||||
#include "IRCLog.h" // IRCLog
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
ExtensionManager::ExtensionManager()
|
||||
{
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
ExtensionManager::~ExtensionManager()
|
||||
{
|
||||
for (int i = 0; i < (int)m_convertors.size(); i++)
|
||||
{
|
||||
IConvertor *conv = m_convertors[i];
|
||||
conv->Release();
|
||||
}
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
IConvertor* ExtensionManager::FindConvertor( Platform platform,const char *ext ) const
|
||||
{
|
||||
const ExtMap *extMap = &(m_extMap[platform]);
|
||||
|
||||
|
||||
ExtMap::const_iterator it;
|
||||
for (it=extMap->begin(); it!=extMap->end(); it++)
|
||||
{
|
||||
CString strExtName = (* it).first;
|
||||
assert((* it).second != NULL);
|
||||
}
|
||||
|
||||
|
||||
IConvertor *foundConvertor = 0;
|
||||
ExtMap::const_iterator low = extMap->find(ext);
|
||||
if (low != extMap->end())
|
||||
{
|
||||
IConvertor* conv = low->second;
|
||||
return conv;
|
||||
/*
|
||||
ExtMap::const_iterator up = extMap->upper_bound(ext);
|
||||
for (ExtMap::const_iterator it = low; it != up; ++it)
|
||||
{
|
||||
IConvertor* conv = *it;
|
||||
// Find convertor that matches platform.
|
||||
int numPlatforms = conv->GetNumPlatforms();
|
||||
for (int i = 0; i < numPlatforms; i++)
|
||||
{
|
||||
if (conv->GetPlatform(i) == platform)
|
||||
{
|
||||
// Matching Convertor found.
|
||||
return conv;
|
||||
}
|
||||
}
|
||||
}
|
||||
*/
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
void ExtensionManager::RegisterConvertor( IConvertor *conv, IResourceCompiler *rc )
|
||||
{
|
||||
assert(conv);
|
||||
assert(rc);
|
||||
|
||||
IRCLog *log=rc->GetIRCLog(); assert(log);
|
||||
|
||||
m_convertors.push_back( conv );
|
||||
|
||||
string strExt;
|
||||
for (int i = 0; i < conv->GetNumExt(); ++i)
|
||||
{
|
||||
if (i)
|
||||
strExt += ", ";
|
||||
strExt += conv->GetExt(i);
|
||||
}
|
||||
|
||||
time_t nTime = conv->GetTimestamp();
|
||||
char* szTime = "unknown";
|
||||
if (nTime)
|
||||
{
|
||||
szTime = asctime(localtime(&nTime));
|
||||
szTime[strlen(szTime)-1] = '\0';
|
||||
}
|
||||
|
||||
// Info ("timestamp %s", szTime);
|
||||
log->Log(" Registered convertor for %s", strExt.c_str());
|
||||
|
||||
assert( conv );
|
||||
for (int k = 0; k < conv->GetNumPlatforms(); k++)
|
||||
{
|
||||
Platform platform = conv->GetPlatform(k);
|
||||
for (int i = 0; i < conv->GetNumExt(); i++)
|
||||
{
|
||||
const char *ext = conv->GetExt(i);
|
||||
assert(ext);
|
||||
m_extMap[platform].insert( ExtMap::value_type(ext,conv) );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
void ExtensionManager::UnregisterAll()
|
||||
{
|
||||
for (int i = 0; i < PLATFORM_LAST; i++)
|
||||
{
|
||||
m_extMap[i].clear();
|
||||
}
|
||||
m_convertors.clear();
|
||||
}
|
||||
47
ResourceCompiler/ExtensionManager.h
Normal file
47
ResourceCompiler/ExtensionManager.h
Normal file
@@ -0,0 +1,47 @@
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Crytek Engine Source File.
|
||||
// Copyright (C), Crytek Studios, 2002.
|
||||
// -------------------------------------------------------------------------
|
||||
// File name: extensionmanager.h
|
||||
// Version: v1.00
|
||||
// Created: 5/11/2002 by Timur.
|
||||
// Compilers: Visual Studio.NET
|
||||
// Description:
|
||||
// -------------------------------------------------------------------------
|
||||
// History:
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifndef __extensionmanager_h__
|
||||
#define __extensionmanager_h__
|
||||
#pragma once
|
||||
|
||||
// forward declarations.
|
||||
struct IConvertor;
|
||||
|
||||
/** Manages mapping between file extensions and convertors.
|
||||
*/
|
||||
class ExtensionManager
|
||||
{
|
||||
public:
|
||||
ExtensionManager();
|
||||
~ExtensionManager();
|
||||
//! Register new convertor with extension manager.
|
||||
//! \param conv must not be 0
|
||||
//! \param rc must not be 0
|
||||
void RegisterConvertor( IConvertor *conv, IResourceCompiler *rc );
|
||||
//! Unregister all convertors.
|
||||
void UnregisterAll();
|
||||
|
||||
//! Find convertor that matches given platform and extension.
|
||||
IConvertor* FindConvertor( Platform platform,const char *ext ) const;
|
||||
|
||||
private:
|
||||
// Maps extension to convertors.
|
||||
typedef std::multimap<CString,IConvertor*,stl::less_stricmp<CString> > ExtMap;
|
||||
ExtMap m_extMap[PLATFORM_LAST];
|
||||
std::vector<IConvertor*> m_convertors;
|
||||
};
|
||||
|
||||
#endif // __extensionmanager_h__
|
||||
192
ResourceCompiler/FileMapping.cpp
Normal file
192
ResourceCompiler/FileMapping.cpp
Normal file
@@ -0,0 +1,192 @@
|
||||
#include "StdAfx.h"
|
||||
#include "FileMapping.h"
|
||||
|
||||
#ifdef _DEBUG
|
||||
#undef THIS_FILE
|
||||
static char THIS_FILE[] = __FILE__;
|
||||
#endif
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
// Initializes an empty file mapping object
|
||||
CFileMapping::CFileMapping():
|
||||
m_nSize(0)
|
||||
,m_pData(0)
|
||||
#ifdef USE_FILE_MAPPING
|
||||
,m_hFile (INVALID_HANDLE_VALUE)
|
||||
,m_hMapping (0)
|
||||
#endif
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
// initializes the object and tries to open the given file mapping
|
||||
CFileMapping::CFileMapping (const char* szFileName, unsigned nFlags):
|
||||
m_nSize(0)
|
||||
,m_pData(0)
|
||||
#ifdef USE_FILE_MAPPING
|
||||
,m_hFile (INVALID_HANDLE_VALUE)
|
||||
,m_hMapping (0)
|
||||
#endif
|
||||
{
|
||||
open (szFileName, nFlags);
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
// closes file mapping
|
||||
CFileMapping::~CFileMapping()
|
||||
{
|
||||
close();
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
// Retuns the size of the mapped file, or 0 if no file was mapped or the file is empty
|
||||
unsigned CFileMapping::getSize()const
|
||||
{
|
||||
return m_nSize;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
// Returns the pointer to the mapped file start in memory, or NULL if the file
|
||||
// wasn't mapped
|
||||
CFileMapping::PData CFileMapping::getData() const
|
||||
{
|
||||
return m_pData;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// Returns the file data at the given offset
|
||||
CFileMapping::PData CFileMapping::getData(unsigned nOffset) const
|
||||
{
|
||||
if (m_pData)
|
||||
return ((char*)m_pData)+nOffset;
|
||||
else
|
||||
return NULL;
|
||||
}
|
||||
|
||||
#ifndef USE_FILE_MAPPING
|
||||
// sets the given (already allocated) buffer to this object
|
||||
// the memory must be allocated with malloc()
|
||||
void CFileMapping::attach (PData pData, unsigned nSize)
|
||||
{
|
||||
close();
|
||||
m_pData = pData;
|
||||
m_nSize = nSize;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
// initializes the object, opening the given file
|
||||
// if file open has failed, subsequent getData() and
|
||||
// getSize() will return zeros
|
||||
// Returns true if open was successful
|
||||
bool CFileMapping::open (const char* szFileName, unsigned nFlags)
|
||||
{
|
||||
close();
|
||||
#ifdef USE_FILE_MAPPING
|
||||
m_hFile = CreateFile (szFileName, GENERIC_READ, FILE_SHARE_READ, 0, OPEN_EXISTING, FILE_FLAG_RANDOM_ACCESS, NULL);
|
||||
DWORD dwError = 0;
|
||||
if (m_hFile != INVALID_HANDLE_VALUE)
|
||||
{
|
||||
m_nSize = GetFileSize(m_hFile, NULL);
|
||||
m_hMapping = CreateFileMapping (m_hFile, NULL, PAGE_READONLY, 0, 0, NULL);
|
||||
if (m_hMapping != NULL)
|
||||
{
|
||||
m_pData = MapViewOfFile (m_hMapping, FILE_MAP_READ, 0, 0, 0);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
dwError = GetLastError();
|
||||
}
|
||||
#elif defined(_CRY_ANIMATION_BASE_HEADER_)
|
||||
ICryPak* pPak = g_GetPak();
|
||||
FILE* f = pPak->FOpen (szFileName, "rb", nFlags);
|
||||
if (f != NULL)
|
||||
{
|
||||
if (0 == pPak->FSeek (f, 0, SEEK_END))
|
||||
{
|
||||
m_nSize = pPak->FTell (f);
|
||||
if ((int)m_nSize >= 0)
|
||||
{
|
||||
if (0 == pPak->FSeek (f, 0, SEEK_SET))
|
||||
{
|
||||
void* pData = malloc (m_nSize);
|
||||
if (pData != NULL && 1 != pPak->FRead (pData, m_nSize, 1, f))
|
||||
free (pData);
|
||||
else
|
||||
m_pData = pData;
|
||||
}
|
||||
}
|
||||
}
|
||||
pPak->FClose (f);
|
||||
}
|
||||
#else
|
||||
FILE* f = fxopen (szFileName, "rb");
|
||||
if (f != NULL)
|
||||
{
|
||||
if (0 == fseek (f, 0, SEEK_END))
|
||||
{
|
||||
m_nSize = ftell (f);
|
||||
if ((int)m_nSize >= 0)
|
||||
{
|
||||
if (0 == fseek (f, 0, SEEK_SET))
|
||||
{
|
||||
void* pData = malloc (m_nSize);
|
||||
if (pData != NULL && 1 != fread (pData, m_nSize, 1, f))
|
||||
free (pData);
|
||||
else
|
||||
m_pData = pData;
|
||||
}
|
||||
}
|
||||
}
|
||||
fclose (f);
|
||||
}
|
||||
#endif
|
||||
|
||||
if (!m_pData)
|
||||
{
|
||||
// we couldn't map the file
|
||||
close();
|
||||
return false;
|
||||
}
|
||||
else
|
||||
return true;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
// closes file mapping
|
||||
// NOTE:
|
||||
// this function can also be used for rollback of unsuccessful file mapping open
|
||||
// opration and thus must be able to close partially open file mapping object
|
||||
void CFileMapping::close()
|
||||
{
|
||||
#ifdef USE_FILE_MAPPING
|
||||
if (m_pData)
|
||||
{
|
||||
UnmapViewOfFile(m_pData);
|
||||
m_pData = NULL;
|
||||
}
|
||||
|
||||
if (m_hMapping != NULL)
|
||||
{
|
||||
CloseHandle (m_hMapping);
|
||||
m_hMapping = NULL;
|
||||
}
|
||||
|
||||
if (m_hFile != INVALID_HANDLE_VALUE)
|
||||
{
|
||||
CloseHandle (m_hFile);
|
||||
m_hFile = INVALID_HANDLE_VALUE;
|
||||
}
|
||||
#else
|
||||
if (m_pData)
|
||||
{
|
||||
if (m_pData)
|
||||
free (m_pData);
|
||||
m_pData = NULL;
|
||||
}
|
||||
#endif
|
||||
m_nSize = 0;
|
||||
}
|
||||
86
ResourceCompiler/FileMapping.h
Normal file
86
ResourceCompiler/FileMapping.h
Normal file
@@ -0,0 +1,86 @@
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// CryEngine Source code
|
||||
//
|
||||
// File:FileMapping
|
||||
// Declaration of class CFileMapping
|
||||
// USE_FILE_MAPPING must be defined in the project for this class to really
|
||||
// use the file mapping. Otherwise it just emulates it
|
||||
//
|
||||
// History:
|
||||
// 06/26/2002 :Created by Sergiy Migdalskiy <sergiy@crytek.de>
|
||||
//
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
#pragma once
|
||||
|
||||
////////////////////////////////////////////////////////////////
|
||||
// class CFileMapping
|
||||
// Generic file mapping object, is capable of mapping a file with
|
||||
// a simple call of a method.
|
||||
//
|
||||
// NOTES:
|
||||
//
|
||||
// Read-only file mapping is supported only.
|
||||
//
|
||||
// Error handing is performed through examining the getData()
|
||||
// address: NULL means that no file was open (no file or I/O error)
|
||||
//
|
||||
// No exceptions are thrown.
|
||||
////////////////////////////////////////////////////////////////
|
||||
|
||||
class CFileMapping: public _reference_target_t
|
||||
{
|
||||
public:
|
||||
// Initializes an empty file mapping object
|
||||
CFileMapping();
|
||||
// initializes the object and tries to open the given file mapping
|
||||
CFileMapping (const char* szFileName, unsigned nFlags = 0);
|
||||
// closes file mapping
|
||||
~CFileMapping();
|
||||
|
||||
// Retuns the size of the mapped file, or 0 if no file was mapped or the file is empty
|
||||
unsigned getSize()const;
|
||||
|
||||
typedef
|
||||
#ifdef USE_FILE_MAPPING
|
||||
const
|
||||
#endif
|
||||
void * PData;
|
||||
|
||||
// Returns the pointer to the mapped file start in memory, or NULL if the file
|
||||
// wasn't mapped
|
||||
PData getData() const;
|
||||
|
||||
// Returns the file data at the given offset
|
||||
PData getData(unsigned nOffset) const;
|
||||
|
||||
#ifndef USE_FILE_MAPPING
|
||||
// sets the given (already allocated) buffer to this object
|
||||
// the memory must be allocated with malloc()
|
||||
void attach (PData pData, unsigned nSize);
|
||||
#endif
|
||||
|
||||
// initializes the object, opening the given file
|
||||
// if file open has failed, subsequent getData() and
|
||||
// getSize() will return zeros
|
||||
// Returns true if open was successful
|
||||
bool open (const char* szFileName, unsigned nFlags = 0);
|
||||
|
||||
// closes file mapping
|
||||
void close();
|
||||
|
||||
protected:
|
||||
// the data of the mapped file.
|
||||
PData m_pData;
|
||||
// the mapped file size
|
||||
unsigned m_nSize;
|
||||
|
||||
#ifdef USE_FILE_MAPPING
|
||||
// the mapped file handle
|
||||
HANDLE m_hFile;
|
||||
// the mapped file mapping handle
|
||||
HANDLE m_hMapping;
|
||||
#endif
|
||||
};
|
||||
|
||||
TYPEDEF_AUTOPTR(CFileMapping)
|
||||
99
ResourceCompiler/FileUtil.cpp
Normal file
99
ResourceCompiler/FileUtil.cpp
Normal file
@@ -0,0 +1,99 @@
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Crytek Engine Source File.
|
||||
// Copyright (C), Crytek Studios, 2002.
|
||||
// -------------------------------------------------------------------------
|
||||
// File name: fileutil.cpp
|
||||
// Version: v1.00
|
||||
// Created: 5/11/2002 by Timur.
|
||||
// Compilers: Visual Studio.NET
|
||||
// Description:
|
||||
// -------------------------------------------------------------------------
|
||||
// History:
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include "StdAfx.h"
|
||||
#include "FileUtil.h"
|
||||
|
||||
#include <io.h>
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// the paths must have trailing slash
|
||||
static bool ScanDirectoryRecursive( const CString &root,const CString &path,const CString &file,std::vector<CString> &files, bool recursive )
|
||||
{
|
||||
__finddata64_t c_file;
|
||||
intptr_t hFile;
|
||||
|
||||
bool anyFound = false;
|
||||
|
||||
CString fullPath = root + path + file;
|
||||
if ( (hFile = _findfirst64( fullPath.GetString(), &c_file )) != -1L )
|
||||
{
|
||||
// Find the rest of the files.
|
||||
do {
|
||||
if (!(c_file.attrib & _A_SUBDIR))
|
||||
{
|
||||
anyFound = true;
|
||||
files.push_back( path + c_file.name );
|
||||
}
|
||||
} while (_findnext64( hFile, &c_file ) == 0);
|
||||
_findclose( hFile );
|
||||
}
|
||||
|
||||
if (recursive)
|
||||
{
|
||||
fullPath = root + path + "*.*";
|
||||
if( (hFile = _findfirst64( fullPath.GetString(), &c_file )) != -1L )
|
||||
{
|
||||
// Find directories.
|
||||
do {
|
||||
if (c_file.attrib & _A_SUBDIR)
|
||||
{
|
||||
// If recursive.
|
||||
if (c_file.name[0] != '.')
|
||||
{
|
||||
if (ScanDirectoryRecursive( root,path + c_file.name + "\\",file,files,recursive ))
|
||||
anyFound = true;
|
||||
}
|
||||
}
|
||||
} while (_findnext64( hFile, &c_file ) == 0);
|
||||
_findclose( hFile );
|
||||
}
|
||||
}
|
||||
|
||||
return anyFound;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
bool FileUtil::ScanDirectory( const CString &path,const CString &file,std::vector<CString> &files, bool recursive )
|
||||
{
|
||||
return ScanDirectoryRecursive(path,"",file,files,recursive );
|
||||
}
|
||||
|
||||
|
||||
// Magic number explanation:
|
||||
// Both epochs are Gregorian. 1970 - 1601 = 369. Assuming a leap
|
||||
// year every four years, 369 / 4 = 92. However, 1700, 1800, and 1900
|
||||
// were NOT leap years, so 89 leap years, 280 non-leap years.
|
||||
// 89 * 366 + 280 * 365 = 134744 days between epochs. Of course
|
||||
// 60 * 60 * 24 = 86400 seconds per day, so 134744 * 86400 =
|
||||
// 11644473600 = SECS_BETWEEN_EPOCHS.
|
||||
//
|
||||
// This result is also confirmed in the MSDN documentation on how
|
||||
// to convert a time_t value to a win32 FILETIME.
|
||||
static const __int64 SECS_BETWEEN_EPOCHS = 11644473600;
|
||||
static const __int64 SECS_TO_100NS = 10000000; /* 10^7 */
|
||||
|
||||
// converts the FILETIME to the C Timestamp (compatible with dbghelp.dll)
|
||||
DWORD FileUtil::FiletimeToUnixTime(const FILETIME& ft)
|
||||
{
|
||||
return (DWORD)((((__int64&)ft) / SECS_TO_100NS) - SECS_BETWEEN_EPOCHS);
|
||||
}
|
||||
|
||||
// converts the C Timestamp (compatible with dbghelp.dll) to FILETIME
|
||||
FILETIME FileUtil::UnixTimeToFiletime(DWORD nCTime)
|
||||
{
|
||||
__int64 time = (nCTime + SECS_BETWEEN_EPOCHS) * SECS_TO_100NS;
|
||||
return (FILETIME&)time;
|
||||
}
|
||||
30
ResourceCompiler/FileUtil.h
Normal file
30
ResourceCompiler/FileUtil.h
Normal file
@@ -0,0 +1,30 @@
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Crytek Engine Source File.
|
||||
// Copyright (C), Crytek Studios, 2002.
|
||||
// -------------------------------------------------------------------------
|
||||
// File name: fileutil.h
|
||||
// Version: v1.00
|
||||
// Created: 5/11/2002 by Timur.
|
||||
// Compilers: Visual Studio.NET
|
||||
// Description:
|
||||
// -------------------------------------------------------------------------
|
||||
// History:
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifndef __fileutil_h__
|
||||
#define __fileutil_h__
|
||||
#pragma once
|
||||
|
||||
namespace FileUtil
|
||||
{
|
||||
// Find all files matching filespec.
|
||||
bool ScanDirectory( const CString &path,const CString &filespec,std::vector<CString> &files,bool recursive );
|
||||
// converts the FILETIME to the C Timestamp (compatible with dbghelp.dll)
|
||||
DWORD FiletimeToUnixTime(const FILETIME& ft);
|
||||
// converts the C Timestamp (compatible with dbghelp.dll) to FILETIME
|
||||
FILETIME UnixTimeToFiletime(DWORD nCTime);
|
||||
};
|
||||
|
||||
#endif // __fileutil_h__
|
||||
50
ResourceCompiler/ICfgFile.h
Normal file
50
ResourceCompiler/ICfgFile.h
Normal file
@@ -0,0 +1,50 @@
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Crytek Engine Source File.
|
||||
// Copyright (C), Crytek Studios, 2002.
|
||||
// -------------------------------------------------------------------------
|
||||
// File name: ICfgFile.h
|
||||
// Version: v1.00
|
||||
// Created: 3/14/2003 by MM.
|
||||
// Compilers: Visual Studio.NET
|
||||
// Description:
|
||||
// -------------------------------------------------------------------------
|
||||
// History:
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifndef __icfgfile_h__
|
||||
#define __icfgfile_h__
|
||||
#pragma once
|
||||
|
||||
/** Configuration file interface.
|
||||
Use format similar to windows .ini files.
|
||||
*/
|
||||
struct ICfgFile
|
||||
{
|
||||
virtual ~ICfgFile() {}
|
||||
|
||||
//! Delete instance of configuration file class.
|
||||
virtual void Release() = 0;
|
||||
|
||||
//! Load configuration file.
|
||||
//! @return true=success, false otherwise
|
||||
virtual bool Load( const CString &fileName ) = 0;
|
||||
|
||||
//! Save configuration file, with the stored name in m_fileName
|
||||
//! @return true=success, false otherwise
|
||||
virtual bool Save( void ) = 0;
|
||||
|
||||
//!
|
||||
//! @param inszSection
|
||||
//! @param inszKey
|
||||
//! @param inszValue
|
||||
virtual void UpdateOrCreateEntry( const char *inszSection, const char *inszKey, const char *inszValue ) = 0;
|
||||
|
||||
virtual bool SetConfig( const char *section, IConfig *config ) = 0;
|
||||
|
||||
virtual const char *GetSectionName(unsigned int n) = 0;
|
||||
virtual int Find(const char *sectionname) = 0;
|
||||
};
|
||||
|
||||
#endif // __icfgfile_h__
|
||||
54
ResourceCompiler/IConfig.h
Normal file
54
ResourceCompiler/IConfig.h
Normal file
@@ -0,0 +1,54 @@
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Crytek Engine Source File.
|
||||
// Copyright (C), Crytek Studios, 2002.
|
||||
// -------------------------------------------------------------------------
|
||||
// File name: iconfig.h
|
||||
// Version: v1.00
|
||||
// Created: 4/11/2002 by Timur.
|
||||
// Compilers: Visual Studio.NET
|
||||
// Description:
|
||||
// -------------------------------------------------------------------------
|
||||
// History:
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifndef __iconfig_h__
|
||||
#define __iconfig_h__
|
||||
#pragma once
|
||||
|
||||
class Config;
|
||||
|
||||
/** Configuration options interface.
|
||||
*/
|
||||
struct IConfig
|
||||
{
|
||||
//! Delete instance of configuration class.
|
||||
virtual void Release() = 0;
|
||||
|
||||
//! Clone configuration.
|
||||
virtual IConfig* Clone() const = 0;
|
||||
|
||||
//! Check if configuration has this key.
|
||||
virtual bool HasKey( const char *key ) const = 0;
|
||||
|
||||
//! Get value of key. the value isn't modified if the key isn't found
|
||||
//! @return true if option found, false if not.
|
||||
virtual bool Get( const char *key,float &value ) const = 0;
|
||||
virtual bool Get( const char *key,int &value ) const = 0;
|
||||
virtual bool Get( const char *key,bool &value ) const = 0;
|
||||
virtual bool Get( const char *key,CString &value ) const = 0;
|
||||
|
||||
virtual void Set( const char *key,const char* value ) = 0;
|
||||
|
||||
virtual Config *GetInternalRepresentation( void )=0;
|
||||
|
||||
template <typename T>
|
||||
T GetAs (const char* key, T defaultValue)
|
||||
{
|
||||
Get (key, defaultValue);
|
||||
return defaultValue;
|
||||
}
|
||||
};
|
||||
|
||||
#endif // __iconfig_h__
|
||||
62
ResourceCompiler/IConvertor.h
Normal file
62
ResourceCompiler/IConvertor.h
Normal file
@@ -0,0 +1,62 @@
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Crytek Engine Source File.
|
||||
// Copyright (C), Crytek Studios, 2002.
|
||||
// -------------------------------------------------------------------------
|
||||
// File name: convertor.h
|
||||
// Version: v1.00
|
||||
// Created: 4/11/2002 by Timur.
|
||||
// Compilers: Visual Studio.NET
|
||||
// Description:
|
||||
// -------------------------------------------------------------------------
|
||||
// History:
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifndef __convertor_h__
|
||||
#define __convertor_h__
|
||||
|
||||
#if _MSC_VER > 1000
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#include "ConvertContext.h"
|
||||
|
||||
/** Conertor interface, all convertor must implement this interface.
|
||||
*/
|
||||
struct IConvertor
|
||||
{
|
||||
//! Release memory of interface.
|
||||
virtual void Release() = 0;
|
||||
|
||||
//! Process file
|
||||
//! \return success
|
||||
virtual bool Process( ConvertContext &cc ) = 0;
|
||||
|
||||
//! Construct the name of the file that will be produced from the source file.
|
||||
//! Put this name into outputFile field, if successful
|
||||
//! Returns true if successful or false if can't convert this file
|
||||
// @param cc is the context of conversion; it contains valid sourceFile and may or may not contain outputFile
|
||||
virtual bool GetOutputFile(ConvertContext &cc) = 0;
|
||||
|
||||
//! Return platforms supported by this convertor.
|
||||
virtual int GetNumPlatforms() const = 0;
|
||||
//! Get supported platform.
|
||||
//! @param index Index of platform must be in range 0 < index < GetNumPlatforms().
|
||||
virtual Platform GetPlatform( int index ) const = 0;
|
||||
|
||||
//! Get number of supported extensions.
|
||||
virtual int GetNumExt() const = 0;
|
||||
//! Get supported extension.
|
||||
//! @param index Index of extension must be in range 0 < index < GetNumExt().
|
||||
virtual const char* GetExt( int index ) const = 0;
|
||||
|
||||
// this should retrieve the timestamp of the convertor executable:
|
||||
// when it was created by the linker, normally. This date/time is used to
|
||||
// compare with the compiled file date/time and even if the compiled file
|
||||
// is not older than the source file, it will be recompiled if it's older than the
|
||||
// convertor
|
||||
virtual DWORD GetTimestamp() const = 0;
|
||||
};
|
||||
|
||||
#endif // __convertor_h__
|
||||
194
ResourceCompiler/IRCLog.h
Normal file
194
ResourceCompiler/IRCLog.h
Normal file
@@ -0,0 +1,194 @@
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Crytek Engine Source File.
|
||||
// Copyright (C), Crytek Studios, 2002.
|
||||
// -------------------------------------------------------------------------
|
||||
// File name: ILog.h
|
||||
// Version: v1.00
|
||||
// Created: 24.1.2002 by Sergiy
|
||||
// Compilers: Visual Studio.NET
|
||||
// Description: ILog interface.
|
||||
// -------------------------------------------------------------------------
|
||||
// History:
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifndef _RESOURCE_COMPILER_IRCLOG_HDR_
|
||||
#define _RESOURCE_COMPILER_IRCLOG_HDR_
|
||||
|
||||
#include <stdarg.h>
|
||||
#include "..\CryCommon\ILog.h" // FIXME: won't compile otherwise?
|
||||
|
||||
// This interface is used to log events inside the convertors,
|
||||
// including information and warning messages
|
||||
struct IRCLog: public ILog
|
||||
{
|
||||
|
||||
// interface IRCLog ---------------------------------------------
|
||||
|
||||
//! is used by LogV, you only have to implement this
|
||||
virtual void LogLine ( const ELogType ineType, const char* szText) = 0;
|
||||
|
||||
// interface ILog -----------------------------------------------
|
||||
|
||||
// use only these three methods (\n is auto splitting in lines)
|
||||
|
||||
//
|
||||
virtual void Log( const char* szFormat, ...);
|
||||
|
||||
//
|
||||
virtual void LogWarning( const char* szFormat, ...);
|
||||
|
||||
//
|
||||
virtual void LogError( const char* szFormat, ...);
|
||||
|
||||
// --------------------------------------------------------------
|
||||
|
||||
//! split in lines (empty lines if given) and print with Log function
|
||||
virtual void LogV( const ELogType ineType, const char* szFormat, va_list args )
|
||||
{
|
||||
char str[16*1024],*p=str;
|
||||
|
||||
vsprintf(str,szFormat, args);
|
||||
|
||||
bool bRun=true;
|
||||
|
||||
while(bRun)
|
||||
{
|
||||
char *start=p;
|
||||
|
||||
// search for end marker
|
||||
while(*p!=0 && *p!=10)
|
||||
{
|
||||
if(*p<32)*p=' '; // remove nonprintable characters
|
||||
|
||||
p++;
|
||||
}
|
||||
|
||||
if(*p==0)
|
||||
bRun=false;
|
||||
|
||||
*p=0;
|
||||
|
||||
LogLine(ineType,start);
|
||||
|
||||
p++; // jump over end marker
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*
|
||||
void Info (const char* szFormat, ...);
|
||||
virtual void Info (const char* szFormat, va_list args) {Log(szFormat, args);}
|
||||
void Warning (const char* szFormat, ...);
|
||||
virtual void Warning (const char* szFormat, va_list args) {Log(szFormat, args);}
|
||||
void Error (const char* szFormat, ...);
|
||||
virtual void Error (const char* szFormat, va_list args) {Log(szFormat, args);}
|
||||
*/
|
||||
void ThrowError(const char* szFormat, ...); // print message and exit CStatCFGCompiler::Process function, todo: Use same system for all converters
|
||||
void LogPlus(const char* szFormat, ...); // print message on the prev line (maybe not needed)
|
||||
|
||||
virtual void Release() {}
|
||||
/*
|
||||
void Log(int dwFlags,const char *szCommand,...)
|
||||
{
|
||||
va_list arg;
|
||||
va_start(arg, szCommand);
|
||||
LogV (eMessage, szCommand, arg);
|
||||
va_end(arg);
|
||||
}
|
||||
*/
|
||||
|
||||
//set the file used to log to disk
|
||||
virtual void SetFileName (const char *command = NULL) {}
|
||||
virtual const char* GetFileName() {return "stdout";}
|
||||
virtual void LogToFile(const char *szCommand,...)
|
||||
{
|
||||
va_list arg;
|
||||
va_start(arg, szCommand);
|
||||
LogV (eMessage, szCommand, arg);
|
||||
va_end(arg);
|
||||
}
|
||||
|
||||
virtual void LogToFilePlus(const char *szCommand,...)
|
||||
{
|
||||
va_list arg;
|
||||
va_start(arg, szCommand);
|
||||
LogV (eMessage, szCommand, arg);
|
||||
va_end(arg);
|
||||
}
|
||||
|
||||
//log to console only
|
||||
virtual void LogToConsole(const char *szCommand,...)
|
||||
{
|
||||
va_list arg;
|
||||
va_start(arg, szCommand);
|
||||
LogV (eMessage, szCommand, arg);
|
||||
va_end(arg);
|
||||
}
|
||||
|
||||
//
|
||||
virtual void LogToConsolePlus(const char *szCommand,...) {}
|
||||
|
||||
//
|
||||
virtual void UpdateLoadingScreen(const char *szCommand,...) {}
|
||||
|
||||
//
|
||||
virtual void UpdateLoadingScreenPlus(const char *szCommand,...) {}
|
||||
|
||||
//
|
||||
virtual void EnableVerbosity( bool bEnable ) {}
|
||||
|
||||
//
|
||||
virtual void SetVerbosity( int verbosity ) {}
|
||||
virtual int GetVerbosityLevel () {return 5;}
|
||||
};
|
||||
|
||||
inline void IRCLog::Log(const char* szFormat, ...)
|
||||
{
|
||||
va_list arg;
|
||||
va_start(arg, szFormat);
|
||||
LogV (eMessage, szFormat, arg);
|
||||
va_end(arg);
|
||||
}
|
||||
|
||||
|
||||
inline void IRCLog::LogWarning(const char* szFormat, ...)
|
||||
{
|
||||
va_list arg;
|
||||
va_start(arg, szFormat);
|
||||
LogV (eWarning, szFormat, arg);
|
||||
va_end(arg);
|
||||
}
|
||||
|
||||
|
||||
inline void IRCLog::LogError(const char* szFormat, ...)
|
||||
{
|
||||
va_list arg;
|
||||
va_start(arg, szFormat);
|
||||
LogV (eError, szFormat, arg);
|
||||
va_end(arg);
|
||||
}
|
||||
|
||||
|
||||
inline void IRCLog::LogPlus(const char* szFormat, ...)
|
||||
{
|
||||
va_list arg;
|
||||
va_start(arg, szFormat);
|
||||
LogV (eMessage, szFormat, arg);
|
||||
va_end(arg);
|
||||
}
|
||||
|
||||
inline void IRCLog::ThrowError(const char* szFormat, ...)
|
||||
{
|
||||
va_list arg;
|
||||
va_start(arg, szFormat);
|
||||
LogV (eError, szFormat, arg);
|
||||
va_end(arg);
|
||||
// Beep(1000,1000);
|
||||
// exit(0);
|
||||
throw "ThrowError";
|
||||
}
|
||||
|
||||
#endif // _RESOURCE_COMPILER_IRCLOG_HDR_
|
||||
76
ResourceCompiler/IResCompiler.h
Normal file
76
ResourceCompiler/IResCompiler.h
Normal file
@@ -0,0 +1,76 @@
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Crytek Engine Source File.
|
||||
// Copyright (C), Crytek Studios, 2002.
|
||||
// -------------------------------------------------------------------------
|
||||
// File name: irescompiler.h
|
||||
// Version: v1.00
|
||||
// Created: 4/11/2002 by Timur.
|
||||
// Compilers: Visual Studio.NET
|
||||
// Description: IResourceCompiler interface.
|
||||
// -------------------------------------------------------------------------
|
||||
// History:
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifndef __irescompiler_h__
|
||||
#define __irescompiler_h__
|
||||
#pragma once
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
struct IConvertor;
|
||||
struct CryChunkedFile;
|
||||
struct IRCLog;
|
||||
|
||||
/** Main interface of resource compiler.
|
||||
*/
|
||||
struct IResourceCompiler
|
||||
{
|
||||
//! Register new convertor.
|
||||
virtual void RegisterConvertor( IConvertor *conv ) = 0;
|
||||
|
||||
//! Use this instead of fopen.
|
||||
virtual FILE* OpenFile( const char *filename,const char *mode ) = 0;
|
||||
|
||||
//! Get timestamp of file.
|
||||
//virtual bool GetFileTime( const char *filename,FILETIME *ftimeModify, FILETIME*ftimeCreate) = 0;
|
||||
|
||||
//! Do resource compilation for this file.
|
||||
//! \param outroot path to the root folder e.g.c:\MasterCD
|
||||
//! @param filename Full filename including path to the file that needs compiling.
|
||||
virtual bool CompileFile( const char *filename, const char *outroot, const char *outpath ) = 0;
|
||||
|
||||
//! Load and parse the Crytek Chunked File into the universal (very big) structure
|
||||
//! The caller should then call Release on the structure to free the mem
|
||||
//! @param filename Full filename including path to the file
|
||||
virtual CryChunkedFile* LoadCryChunkedFile (const char* szFileName) = 0;
|
||||
|
||||
//! Returns the main application window
|
||||
virtual HWND GetHWnd() = 0;
|
||||
|
||||
// returns a handle to an empty window to be used with DirectX
|
||||
virtual HWND GetEmptyWindow() = 0;
|
||||
|
||||
//! If the physics was successfully initialized, then returns the pointer to the physics engine;
|
||||
//! otherwise returns NULL
|
||||
virtual class IPhysicalWorld* GetPhysicalWorld() = 0;
|
||||
|
||||
//! \return is always a valid pointer
|
||||
virtual IRCLog *GetIRCLog()=0;
|
||||
|
||||
//! \inszName full name like in 3dsmax
|
||||
virtual void AddDependencyMaterial( const char *inszSrcFilename, const char *inszMatName, const char *inszScriptName )=0;
|
||||
|
||||
//! \inszPathFileName absolute path names
|
||||
virtual void AddDependencyFile( const char *inszSrcFilename, const char *inszPathFileName )=0;
|
||||
};
|
||||
|
||||
|
||||
// this is the plugin function that's exported by plugins
|
||||
// Registers all convertors residing in this DLL
|
||||
extern "C" {
|
||||
typedef void (__stdcall* FnRegisterConvertors )(IResourceCompiler*pRC);
|
||||
}
|
||||
|
||||
#endif // __irescompiler_h__
|
||||
284
ResourceCompiler/MathUtils.h
Normal file
284
ResourceCompiler/MathUtils.h
Normal file
@@ -0,0 +1,284 @@
|
||||
#ifndef _CRY_ANIMATION_MATH_UTILS_HDR_
|
||||
#define _CRY_ANIMATION_MATH_UTILS_HDR_
|
||||
|
||||
#include "IBindable.h"
|
||||
#include "Cry_Geo.h"
|
||||
|
||||
// aligned on 16-byte boundary vector
|
||||
class Vec3dA16
|
||||
{
|
||||
public:
|
||||
Vec3 v;
|
||||
unsigned m_Pad;
|
||||
|
||||
Vec3dA16 () {}
|
||||
Vec3dA16 (float x, float y, float z):
|
||||
v(x,y,z)
|
||||
{}
|
||||
};
|
||||
|
||||
|
||||
// for the given forward vector and position, builds up the right vector and up vector
|
||||
// and builds the corresponding matrix
|
||||
// Builds the right and up vector, given the forward vector, and initializes the matOut
|
||||
void BuildMatrixFromFwd (const Vec3& ptNormal, const Vec3& ptPosition, Matrix44& matOut);
|
||||
|
||||
// for the given forward vector and position, builds up the right vector and up vector
|
||||
// and builds the corresponding matrix
|
||||
// Builds the right and up vector, given the forward vector, and initializes the matOut
|
||||
void BuildMatrixFromFwdZRot (const Vec3& ptNormal, const Vec3& ptPosition, float fZRotate, Matrix44& matOut);
|
||||
|
||||
inline bool IsOrthoUniform (const Matrix44& b, float fTolerance = 0.01f)
|
||||
{
|
||||
for (int i = 0; i < 3; ++i)
|
||||
{
|
||||
if (fabs(b.GetRow(i).GetLengthSquared()-1) > fTolerance)
|
||||
return false;
|
||||
if (fabs(b.GetColumn(i).GetLengthSquared()-1) > fTolerance)
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
inline void OrthoNormalize(Matrix44& m)
|
||||
{
|
||||
m.NoScale();
|
||||
}
|
||||
|
||||
// given the bone matrix, returns its inverted.
|
||||
// the bone matrices are orthounitary
|
||||
inline Matrix44 OrthoUniformGetInverted (const Matrix44& b)
|
||||
{
|
||||
#ifdef _DEBUG
|
||||
for (int i = 0; i < 3; ++i)
|
||||
{
|
||||
assert (fabs(b.GetRow(i).len2()-1) < 1e-2);
|
||||
assert (fabs(b.GetColumn(i).len2()-1) < 1e-2);
|
||||
}
|
||||
#endif
|
||||
return GetInverted44(b);
|
||||
Matrix44 m;
|
||||
m(0,0) = b(0,0); m(0,1) = b(1,0); m(0,2)= b(2,0); m(0,3) = 0;
|
||||
m(1,0) = b(0,1); m(1,1) = b(1,1); m(1,2)= b(2,1); m(1,3) = 0;
|
||||
m(2,0) = b(0,2); m(2,1) = b(1,2); m(2,2)= b(2,2); m(2,3) = 0;
|
||||
m.SetTranslationOLD(b.TransformVectorOLD(b.GetTranslationOLD())); m(3,3) = 1;
|
||||
|
||||
#ifdef _DEBUG
|
||||
Matrix44 e = b * m;
|
||||
assert (e.GetTranslationOLD().GetLengthSquared() < 0.01f);
|
||||
#endif
|
||||
return m;
|
||||
}
|
||||
|
||||
// rotates the matrix by the "Angles" used by the FarCry game
|
||||
void Rotate (Matrix44& matInOut, const Vec3& vAngles);
|
||||
|
||||
// rotates the matrix by the "Angles" used by the FarCry game,
|
||||
// but in inverse order and in opposite direction (effectively constructing the inverse matrix)
|
||||
void RotateInv (Matrix44& matInOut, const Vec3& vAngles);
|
||||
|
||||
// Smoothes linear blending into cubic (b-spline) with 0-derivatives
|
||||
// near 0 and 1
|
||||
extern float SmoothBlendValue (float fBlend);
|
||||
|
||||
template <typename T>
|
||||
T min2 (T a, T b)
|
||||
{
|
||||
return a < b ? a : b;
|
||||
}
|
||||
template <typename T>
|
||||
T max2 (T a, T b)
|
||||
{
|
||||
return a > b ? a : b;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
T max3(T val1, T val2, T val3)
|
||||
{
|
||||
return max2(max2(val1,val2),val3);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
T min3(T val1, T val2, T val3)
|
||||
{
|
||||
return min2(min2(val1,val2),val3);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
T min4 (T a, T b, T c, T d)
|
||||
{
|
||||
return min2(min2(a,b),min2(c,d));
|
||||
}
|
||||
|
||||
|
||||
|
||||
#include "QuaternionExponentX87.h"
|
||||
|
||||
// checks whether the quaternions are almost equal
|
||||
inline bool isEqual (const CryQuat& q, const CryQuat& p)
|
||||
{
|
||||
const float fEpsilon = 0.05f;
|
||||
if (fabs(q.w-p.w) > fEpsilon)
|
||||
return false;
|
||||
if (fabs(q.v.x-p.v.x) > fEpsilon)
|
||||
return false;
|
||||
if (fabs(q.v.y-p.v.y) > fEpsilon)
|
||||
return false;
|
||||
if (fabs(q.v.z-p.v.z) > fEpsilon)
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
__inline void quaternionExponentOptimized(const Vec3& rSrcVector, CryQuat& rDstQuat)
|
||||
{
|
||||
#if DO_ASM && defined (_CPU_X86)
|
||||
float fResultWXYZ[4];
|
||||
quaternionExponent_x87 (&rSrcVector.x, fResultWXYZ);
|
||||
rDstQuat.w = fResultWXYZ[0];
|
||||
rDstQuat.v.x = fResultWXYZ[1];
|
||||
rDstQuat.v.y = fResultWXYZ[2];
|
||||
rDstQuat.v.z = fResultWXYZ[3];
|
||||
|
||||
assert (isEqual(rDstQuat,exp(quaternionf(0,rSrcVector))));
|
||||
#else
|
||||
CryQuat tmp;
|
||||
tmp.v = rSrcVector;
|
||||
tmp.w = 0;
|
||||
rDstQuat = exp(tmp);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
struct CryAABB
|
||||
{
|
||||
|
||||
Vec3 vMin;
|
||||
Vec3 vMax;
|
||||
|
||||
CryAABB() {}
|
||||
|
||||
/* CryAABB(struct IBindable* pObj) {
|
||||
pObj->GetBBox(vMin, vMax);
|
||||
}*/
|
||||
|
||||
CryAABB(const Vec3& a, const Vec3& b) {
|
||||
vMin = a;
|
||||
vMax = b;
|
||||
}
|
||||
|
||||
CryAABB(const CryAABB& right) {
|
||||
vMin = right.vMin;
|
||||
vMax = right.vMax;
|
||||
}
|
||||
|
||||
Vec3 getSize() const {return vMax-vMin;}
|
||||
Vec3 getCenter() const {return (vMin+vMax)*0.5f;}
|
||||
|
||||
bool empty() const {return vMin.x >= vMax.x || vMin.y >= vMax.y || vMin.z >= vMax.z;}
|
||||
|
||||
void include(const Vec3& v) { AddToBounds(v, vMin, vMax);}
|
||||
void include (const CryAABB& right) {
|
||||
include (right.vMin);
|
||||
include (right.vMax);
|
||||
}
|
||||
|
||||
|
||||
// static Vec3& toVec3d(Vec3&v) { return v; }
|
||||
// static const Vec3& toVec3d(const Vec3&v) {return v;}
|
||||
|
||||
// static Vec3& toVec3d(Vec3dA16&v){return v.v;}
|
||||
// static const Vec3& toVec3d(const Vec3dA16&v){return v.v;}
|
||||
// CryAABB& operator = (const Vec3& v) {vMin=vMax = v; return *this;}
|
||||
/*
|
||||
CryAABB(const Vec3& a) {
|
||||
toVec3d(vMin) = a;
|
||||
toVec3d(vMax) = a;
|
||||
}*/
|
||||
|
||||
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
template <typename TVec>
|
||||
class CryBBox_tpl
|
||||
{
|
||||
public:
|
||||
CryBBox_tpl(){}
|
||||
CryBBox_tpl(const Vec3& a)
|
||||
{
|
||||
toVec3d(vMin) = a;
|
||||
toVec3d(vMax) = a;
|
||||
}
|
||||
CryBBox_tpl(struct IBindable* pObj)
|
||||
{
|
||||
pObj->GetBBox(toVec3d(vMin), toVec3d(vMax));
|
||||
}
|
||||
CryBBox_tpl(const Vec3& a, const Vec3& b)
|
||||
{
|
||||
toVec3d(vMin) = a;
|
||||
toVec3d(vMax) = b;
|
||||
}
|
||||
template <typename T2>
|
||||
CryBBox_tpl(const CryBBox_tpl<T2>& right)
|
||||
{
|
||||
toVec3d(vMin) = toVec3d(right.vMin);
|
||||
toVec3d(vMax) = toVec3d(right.vMax);
|
||||
}
|
||||
|
||||
TVec vMin;
|
||||
TVec vMax;
|
||||
|
||||
bool empty()const {return vMin.x >= vMax.x || vMin.y >= vMax.y || vMin.z >= vMax.z;}
|
||||
|
||||
static Vec3& toVec3d(Vec3&v){return v;}
|
||||
static const Vec3& toVec3d(const Vec3&v){return v;}
|
||||
static Vec3& toVec3d(Vec3dA16&v){return v.v;}
|
||||
static const Vec3& toVec3d(const Vec3dA16&v){return v.v;}
|
||||
|
||||
Vec3 getSize() const {return toVec3d(vMax)-toVec3d(vMin);}
|
||||
Vec3 getCenter() const {return (toVec3d(vMin)+toVec3d(vMax))*0.5f;}
|
||||
CryBBox_tpl<TVec>& operator = (const Vec3& v) {toVec3d(vMin) = toVec3d(vMax) = v; return *this;}
|
||||
void include(const Vec3& v) { AddToBounds(v, toVec3d(vMin), toVec3d(vMax));}
|
||||
template <typename T3>
|
||||
void include (const CryBBox_tpl<T3>&right)
|
||||
{
|
||||
include (toVec3d(right.vMin));
|
||||
include (toVec3d(right.vMax));
|
||||
}
|
||||
};
|
||||
|
||||
//typedef CryBBox_tpl<Vec3> CryBBox;
|
||||
typedef CryBBox_tpl<Vec3dA16> CryBBoxA16;
|
||||
|
||||
|
||||
//extern Vec3 UntransformVector (const Matrix& m, const Vec3& v);
|
||||
inline bool isUnit (const Vec3& v, float fTolerance)
|
||||
{
|
||||
float fLen = v.GetLengthSquared();
|
||||
return fLen >= 1-fTolerance && fLen < 1+fTolerance;
|
||||
}
|
||||
|
||||
inline bool isSane(float x)
|
||||
{
|
||||
return x > -1e9 && x < 1e9;
|
||||
}
|
||||
|
||||
inline bool isSane (const Vec3& v)
|
||||
{
|
||||
return isSane(v.x) && isSane(v.y) && isSane(v.z);
|
||||
}
|
||||
|
||||
inline bool isUnit (const TangData& td, float fTolerance)
|
||||
{
|
||||
return isUnit(td.binormal, fTolerance) && isUnit(td.tangent, fTolerance) && isUnit(td.tnormal, fTolerance);
|
||||
}
|
||||
|
||||
#endif
|
||||
86
ResourceCompiler/NvTriStrip/CrtOverrides.h
Normal file
86
ResourceCompiler/NvTriStrip/CrtOverrides.h
Normal file
@@ -0,0 +1,86 @@
|
||||
/*=============================================================================
|
||||
CrtOverrides.h: missing C RunTime overrides implementation.
|
||||
Copyright 2001 Crytek Studios. All Rights Reserved.
|
||||
|
||||
Revision history:
|
||||
* Created by Honitch Andrey
|
||||
|
||||
=============================================================================*/
|
||||
|
||||
#ifdef _XBOX
|
||||
|
||||
#ifndef stricmp
|
||||
inline int stricmp(const char *dst, const char *src)
|
||||
{
|
||||
int f,l;
|
||||
do
|
||||
{
|
||||
if ( ((f=(unsigned char)(*(dst++))) >= 'A') && (f<='Z'))
|
||||
f -= ('A' - 'a');
|
||||
|
||||
if ( ((l=(unsigned char)(*(src++))) >= 'A') && (l<='Z'))
|
||||
l -= ('A' - 'a');
|
||||
} while ( f && (f == l) );
|
||||
|
||||
return(f - l);
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifndef strnicmp
|
||||
inline int strnicmp (const char * first, const char * last, size_t count)
|
||||
{
|
||||
int f,l;
|
||||
if ( count )
|
||||
{
|
||||
do
|
||||
{
|
||||
if ( ((f=(unsigned char)(*(first++))) >= 'A') && (f<='Z') )
|
||||
f -= 'A' - 'a';
|
||||
|
||||
if ( ((l=(unsigned char)(*(last++))) >= 'A') && (l<='Z'))
|
||||
l -= 'A' - 'a';
|
||||
} while ( --count && f && (f == l) );
|
||||
|
||||
return( f - l );
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifndef strdup
|
||||
inline char * strdup (const char * str)
|
||||
{
|
||||
char *memory;
|
||||
|
||||
if (!str)
|
||||
return(NULL);
|
||||
|
||||
memory = (char *)malloc(strlen(str) + 1);
|
||||
if (memory)
|
||||
return(strcpy(memory,str));
|
||||
|
||||
return(NULL);
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifndef strlwr
|
||||
inline char * strlwr (char * str)
|
||||
{
|
||||
unsigned char *dst = NULL; /* destination string */
|
||||
char *cp; /* traverses string for C locale conversion */
|
||||
|
||||
for (cp=str; *cp; ++cp)
|
||||
{
|
||||
if ('A' <= *cp && *cp <= 'Z')
|
||||
*cp += 'a' - 'A';
|
||||
}
|
||||
return str;
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif // _XBOX
|
||||
|
||||
/*-----------------------------------------------------------------------------
|
||||
The End.
|
||||
-----------------------------------------------------------------------------*/
|
||||
311
ResourceCompiler/NvTriStrip/NvTriStrip.cpp
Normal file
311
ResourceCompiler/NvTriStrip/NvTriStrip.cpp
Normal file
@@ -0,0 +1,311 @@
|
||||
#ifdef WIN64
|
||||
#include "WinDef.h"
|
||||
#endif
|
||||
|
||||
|
||||
#include "NvTriStripObjects.h"
|
||||
#include "NvTriStrip.h"
|
||||
|
||||
#pragma warning(push)
|
||||
#pragma warning(disable:4018) // signed/unsigned mismatch
|
||||
#ifdef WIN64 //AMD Port
|
||||
#pragma warning( disable : 4267 ) // conversion from 'size_t' to 'xxx', possible loss of data
|
||||
#endif
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////
|
||||
//private data
|
||||
static unsigned int cacheSize = CACHESIZE_GEFORCE3;// CACHESIZE_GEFORCE1_2;
|
||||
static bool bStitchStrips = true;
|
||||
static unsigned int minStripSize = 0;
|
||||
static bool bListsOnly = false;
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////
|
||||
// SetListsOnly()
|
||||
//
|
||||
// If set to true, will return an optimized list, with no strips at all.
|
||||
//
|
||||
// Default value: false
|
||||
//
|
||||
void SetListsOnly(const bool _bListsOnly)
|
||||
{
|
||||
bListsOnly = _bListsOnly;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////
|
||||
// SetCacheSize()
|
||||
//
|
||||
// Sets the cache size which the stripfier uses to optimize the data.
|
||||
// Controls the length of the generated individual strips.
|
||||
// This is the "actual" cache size, so 24 for GeForce3 and 16 for GeForce1/2
|
||||
// You may want to play around with this number to tweak performance.
|
||||
//
|
||||
// Default value: 16
|
||||
//
|
||||
void SetCacheSize(const unsigned int _cacheSize)
|
||||
{
|
||||
cacheSize = _cacheSize;
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////
|
||||
// SetStitchStrips()
|
||||
//
|
||||
// bool to indicate whether to stitch together strips into one huge strip or not.
|
||||
// If set to true, you'll get back one huge strip stitched together using degenerate
|
||||
// triangles.
|
||||
// If set to false, you'll get back a large number of separate strips.
|
||||
//
|
||||
// Default value: true
|
||||
//
|
||||
void SetStitchStrips(const bool _bStitchStrips)
|
||||
{
|
||||
bStitchStrips = _bStitchStrips;
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////
|
||||
// SetMinStripSize()
|
||||
//
|
||||
// Sets the minimum acceptable size for a strip, in triangles.
|
||||
// All strips generated which are shorter than this will be thrown into one big, separate list.
|
||||
//
|
||||
// Default value: 0
|
||||
//
|
||||
void SetMinStripSize(const unsigned int _minStripSize)
|
||||
{
|
||||
minStripSize = _minStripSize;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////
|
||||
// GenerateStrips()
|
||||
//
|
||||
// in_indices: input index list, the indices you would use to render
|
||||
// in_numIndices: number of entries in in_indices
|
||||
// primGroups: array of optimized/stripified PrimitiveGroups
|
||||
// numGroups: number of groups returned
|
||||
//
|
||||
// Be sure to call delete[] on the returned primGroups to avoid leaking mem
|
||||
//
|
||||
void GenerateStrips(const unsigned short* in_indices, const unsigned int in_numIndices,
|
||||
PrimitiveGroup** primGroups, unsigned short* numGroups)
|
||||
{
|
||||
//put data in format that the stripifier likes
|
||||
int i;
|
||||
WordVec tempIndices;
|
||||
tempIndices.resize(in_numIndices);
|
||||
unsigned short maxIndex = 0;
|
||||
for(i = 0; i < (int)in_numIndices; i++)
|
||||
{
|
||||
tempIndices[i] = in_indices[i];
|
||||
if(in_indices[i] > maxIndex)
|
||||
maxIndex = in_indices[i];
|
||||
}
|
||||
NvStripInfoVec tempStrips;
|
||||
NvFaceInfoVec tempFaces;
|
||||
|
||||
NvStripifier stripifier;
|
||||
|
||||
//do actual stripification
|
||||
stripifier.Stripify(tempIndices, cacheSize, minStripSize, maxIndex, tempStrips, tempFaces);
|
||||
|
||||
//stitch strips together
|
||||
IntVec stripIndices;
|
||||
unsigned int numSeparateStrips = 0;
|
||||
|
||||
if(bListsOnly)
|
||||
{
|
||||
//if we're outputting only lists, we're done
|
||||
*numGroups = 1;
|
||||
(*primGroups) = new PrimitiveGroup[*numGroups];
|
||||
PrimitiveGroup* primGroupArray = *primGroups;
|
||||
|
||||
//count the total number of indices
|
||||
unsigned int numIndices = 0;
|
||||
for(i = 0; i < tempStrips.size(); i++)
|
||||
{
|
||||
numIndices += tempStrips[i]->m_faces.size() * 3;
|
||||
}
|
||||
|
||||
//add in the list
|
||||
numIndices += tempFaces.size() * 3;
|
||||
|
||||
primGroupArray[0].type = PT_LIST;
|
||||
primGroupArray[0].numIndices = numIndices;
|
||||
primGroupArray[0].indices = new unsigned short[numIndices];
|
||||
|
||||
//do strips
|
||||
unsigned int indexCtr = 0;
|
||||
for(i = 0; i < tempStrips.size(); i++)
|
||||
{
|
||||
for(int j = 0; j < tempStrips[i]->m_faces.size(); j++)
|
||||
{
|
||||
//degenerates are of no use with lists
|
||||
if(!NvStripifier::IsDegenerate(tempStrips[i]->m_faces[j]))
|
||||
{
|
||||
primGroupArray[0].indices[indexCtr++] = tempStrips[i]->m_faces[j]->m_v0;
|
||||
primGroupArray[0].indices[indexCtr++] = tempStrips[i]->m_faces[j]->m_v1;
|
||||
primGroupArray[0].indices[indexCtr++] = tempStrips[i]->m_faces[j]->m_v2;
|
||||
}
|
||||
else
|
||||
{
|
||||
//we've removed a tri, reduce the number of indices
|
||||
primGroupArray[0].numIndices -= 3;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//do lists
|
||||
for(i = 0; i < tempFaces.size(); i++)
|
||||
{
|
||||
primGroupArray[0].indices[indexCtr++] = tempFaces[i]->m_v0;
|
||||
primGroupArray[0].indices[indexCtr++] = tempFaces[i]->m_v1;
|
||||
primGroupArray[0].indices[indexCtr++] = tempFaces[i]->m_v2;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
stripifier.CreateStrips(tempStrips, stripIndices, bStitchStrips, numSeparateStrips);
|
||||
|
||||
//if we're stitching strips together, we better get back only one strip from CreateStrips()
|
||||
assert( (bStitchStrips && (numSeparateStrips == 1)) || !bStitchStrips);
|
||||
|
||||
//convert to output format
|
||||
*numGroups = numSeparateStrips; //for the strips
|
||||
if(tempFaces.size() != 0)
|
||||
(*numGroups)++; //we've got a list as well, increment
|
||||
(*primGroups) = new PrimitiveGroup[*numGroups];
|
||||
|
||||
PrimitiveGroup* primGroupArray = *primGroups;
|
||||
|
||||
//first, the strips
|
||||
int startingLoc = 0;
|
||||
for(int stripCtr = 0; stripCtr < numSeparateStrips; stripCtr++)
|
||||
{
|
||||
int stripLength = 0;
|
||||
|
||||
if(!bStitchStrips)
|
||||
{
|
||||
//if we've got multiple strips, we need to figure out the correct length
|
||||
for(i = startingLoc; i < stripIndices.size(); i++)
|
||||
{
|
||||
if(stripIndices[i] == -1)
|
||||
break;
|
||||
}
|
||||
|
||||
stripLength = i - startingLoc;
|
||||
}
|
||||
else
|
||||
stripLength = stripIndices.size();
|
||||
|
||||
primGroupArray[stripCtr].type = PT_STRIP;
|
||||
primGroupArray[stripCtr].indices = new unsigned short[stripLength];
|
||||
primGroupArray[stripCtr].numIndices = stripLength;
|
||||
|
||||
int indexCtr = 0;
|
||||
for(int i = startingLoc; i < stripLength + startingLoc; i++)
|
||||
primGroupArray[stripCtr].indices[indexCtr++] = stripIndices[i];
|
||||
|
||||
//we add 1 to account for the -1 separating strips
|
||||
//this doesn't break the stitched case since we'll exit the loop
|
||||
startingLoc += stripLength + 1;
|
||||
}
|
||||
|
||||
//next, the list
|
||||
if(tempFaces.size() != 0)
|
||||
{
|
||||
int faceGroupLoc = (*numGroups) - 1; //the face group is the last one
|
||||
primGroupArray[faceGroupLoc].type = PT_LIST;
|
||||
primGroupArray[faceGroupLoc].indices = new unsigned short[tempFaces.size() * 3];
|
||||
primGroupArray[faceGroupLoc].numIndices = tempFaces.size() * 3;
|
||||
int indexCtr = 0;
|
||||
for(int i = 0; i < tempFaces.size(); i++)
|
||||
{
|
||||
primGroupArray[faceGroupLoc].indices[indexCtr++] = tempFaces[i]->m_v0;
|
||||
primGroupArray[faceGroupLoc].indices[indexCtr++] = tempFaces[i]->m_v1;
|
||||
primGroupArray[faceGroupLoc].indices[indexCtr++] = tempFaces[i]->m_v2;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//clean up everything
|
||||
|
||||
//delete strips
|
||||
for(i = 0; i < tempStrips.size(); i++)
|
||||
{
|
||||
for(int j = 0; j < tempStrips[i]->m_faces.size(); j++)
|
||||
{
|
||||
delete tempStrips[i]->m_faces[j];
|
||||
tempStrips[i]->m_faces[j] = NULL;
|
||||
}
|
||||
tempStrips[i]->m_faces.resize(0);
|
||||
delete tempStrips[i];
|
||||
tempStrips[i] = NULL;
|
||||
}
|
||||
|
||||
//delete faces
|
||||
for(i = 0; i < tempFaces.size(); i++)
|
||||
{
|
||||
delete tempFaces[i];
|
||||
tempFaces[i] = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////
|
||||
// RemapIndices()
|
||||
//
|
||||
// Function to remap your indices to improve spatial locality in your vertex buffer.
|
||||
//
|
||||
// in_primGroups: array of PrimitiveGroups you want remapped
|
||||
// numGroups: number of entries in in_primGroups
|
||||
// numVerts: number of vertices in your vertex buffer, also can be thought of as the range
|
||||
// of acceptable values for indices in your primitive groups.
|
||||
// remappedGroups: array of remapped PrimitiveGroups
|
||||
//
|
||||
// Note that, according to the remapping handed back to you, you must reorder your
|
||||
// vertex buffer.
|
||||
//
|
||||
void RemapIndices(const PrimitiveGroup* in_primGroups, const unsigned short numGroups,
|
||||
const unsigned short numVerts, PrimitiveGroup** remappedGroups)
|
||||
{
|
||||
(*remappedGroups) = new PrimitiveGroup[numGroups];
|
||||
|
||||
//caches oldIndex --> newIndex conversion
|
||||
int *indexCache;
|
||||
indexCache = new int[numVerts];
|
||||
memset(indexCache, -1, sizeof(int)*numVerts);
|
||||
|
||||
//loop over primitive groups
|
||||
unsigned int indexCtr = 0;
|
||||
for(int i = 0; i < numGroups; i++)
|
||||
{
|
||||
unsigned int numIndices = in_primGroups[i].numIndices;
|
||||
|
||||
//init remapped group
|
||||
(*remappedGroups)[i].type = in_primGroups[i].type;
|
||||
(*remappedGroups)[i].numIndices = numIndices;
|
||||
(*remappedGroups)[i].indices = new unsigned short[numIndices];
|
||||
|
||||
for(int j = 0; j < numIndices; j++)
|
||||
{
|
||||
int cachedIndex = indexCache[in_primGroups[i].indices[j]];
|
||||
if(cachedIndex == -1) //we haven't seen this index before
|
||||
{
|
||||
//point to "last" vertex in VB
|
||||
(*remappedGroups)[i].indices[j] = indexCtr;
|
||||
|
||||
//add to index cache, increment
|
||||
indexCache[in_primGroups[i].indices[j]] = indexCtr++;
|
||||
}
|
||||
else
|
||||
{
|
||||
//we've seen this index before
|
||||
(*remappedGroups)[i].indices[j] = cachedIndex;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
delete[] indexCache;
|
||||
}
|
||||
|
||||
#pragma warning(pop)
|
||||
131
ResourceCompiler/NvTriStrip/NvTriStrip.h
Normal file
131
ResourceCompiler/NvTriStrip/NvTriStrip.h
Normal file
@@ -0,0 +1,131 @@
|
||||
#ifndef NVTRISTRIP_H
|
||||
#define NVTRISTRIP_H
|
||||
|
||||
#ifndef NULL
|
||||
#define NULL 0
|
||||
#endif
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Public interface for stripifier
|
||||
////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
//GeForce1 and 2 cache size
|
||||
#define CACHESIZE_GEFORCE1_2 16
|
||||
|
||||
//GeForce3 cache size
|
||||
#define CACHESIZE_GEFORCE3 24
|
||||
|
||||
enum PrimType
|
||||
{
|
||||
PT_LIST,
|
||||
PT_STRIP,
|
||||
PT_FAN
|
||||
};
|
||||
|
||||
struct SPrimitiveGroup
|
||||
{
|
||||
PrimType type;
|
||||
unsigned int numIndices;
|
||||
unsigned int offsIndex;
|
||||
unsigned int numTris;
|
||||
unsigned int nFirstFace;
|
||||
};
|
||||
|
||||
struct PrimitiveGroup
|
||||
{
|
||||
PrimType type;
|
||||
unsigned int numIndices;
|
||||
unsigned short* indices;
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
PrimitiveGroup() : type(PT_STRIP), numIndices(0), indices(NULL) {}
|
||||
~PrimitiveGroup()
|
||||
{
|
||||
if(indices)
|
||||
delete[] indices;
|
||||
indices = NULL;
|
||||
}
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////
|
||||
// SetCacheSize()
|
||||
//
|
||||
// Sets the cache size which the stripfier uses to optimize the data.
|
||||
// Controls the length of the generated individual strips.
|
||||
// This is the "actual" cache size, so 24 for GeForce3 and 16 for GeForce1/2
|
||||
// You may want to play around with this number to tweak performance.
|
||||
//
|
||||
// Default value: 16
|
||||
//
|
||||
void SetCacheSize(const unsigned int cacheSize);
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////
|
||||
// SetStitchStrips()
|
||||
//
|
||||
// bool to indicate whether to stitch together strips into one huge strip or not.
|
||||
// If set to true, you'll get back one huge strip stitched together using degenerate
|
||||
// triangles.
|
||||
// If set to false, you'll get back a large number of separate strips.
|
||||
//
|
||||
// Default value: true
|
||||
//
|
||||
void SetStitchStrips(const bool bStitchStrips);
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////
|
||||
// SetMinStripSize()
|
||||
//
|
||||
// Sets the minimum acceptable size for a strip, in triangles.
|
||||
// All strips generated which are shorter than this will be thrown into one big, separate list.
|
||||
//
|
||||
// Default value: 0
|
||||
//
|
||||
void SetMinStripSize(const unsigned int minSize);
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////
|
||||
// SetListsOnly()
|
||||
//
|
||||
// If set to true, will return an optimized list, with no strips at all.
|
||||
//
|
||||
// Default value: false
|
||||
//
|
||||
void SetListsOnly(const bool bListsOnly);
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////
|
||||
// GenerateStrips()
|
||||
//
|
||||
// in_indices: input index list, the indices you would use to render
|
||||
// in_numIndices: number of entries in in_indices
|
||||
// primGroups: array of optimized/stripified PrimitiveGroups
|
||||
// numGroups: number of groups returned
|
||||
//
|
||||
// Be sure to call delete[] on the returned primGroups to avoid leaking mem
|
||||
//
|
||||
void GenerateStrips(const unsigned short* in_indices, const unsigned int in_numIndices,
|
||||
PrimitiveGroup** primGroups, unsigned short* numGroups);
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////
|
||||
// RemapIndices()
|
||||
//
|
||||
// Function to remap your indices to improve spatial locality in your vertex buffer.
|
||||
//
|
||||
// in_primGroups: array of PrimitiveGroups you want remapped
|
||||
// numGroups: number of entries in in_primGroups
|
||||
// numVerts: number of vertices in your vertex buffer, also can be thought of as the range
|
||||
// of acceptable values for indices in your primitive groups.
|
||||
// remappedGroups: array of remapped PrimitiveGroups
|
||||
//
|
||||
// Note that, according to the remapping handed back to you, you must reorder your
|
||||
// vertex buffer.
|
||||
//
|
||||
// Credit goes to the MS Xbox crew for the idea for this interface.
|
||||
//
|
||||
void RemapIndices(const PrimitiveGroup* in_primGroups, const unsigned short numGroups,
|
||||
const unsigned short numVerts, PrimitiveGroup** remappedGroups);
|
||||
|
||||
#endif
|
||||
1798
ResourceCompiler/NvTriStrip/NvTriStripObjects.cpp
Normal file
1798
ResourceCompiler/NvTriStrip/NvTriStripObjects.cpp
Normal file
File diff suppressed because it is too large
Load Diff
244
ResourceCompiler/NvTriStrip/NvTriStripObjects.h
Normal file
244
ResourceCompiler/NvTriStrip/NvTriStripObjects.h
Normal file
@@ -0,0 +1,244 @@
|
||||
|
||||
#ifndef NV_TRISTRIP_OBJECTS_H
|
||||
#define NV_TRISTRIP_OBJECTS_H
|
||||
|
||||
#include <assert.h>
|
||||
#ifdef WIN32
|
||||
#include <windows.h>
|
||||
#endif
|
||||
#include <vector>
|
||||
#include <list>
|
||||
#include "VertexCache.h"
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Types defined for stripification
|
||||
//
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
struct MyVertex {
|
||||
float x, y, z;
|
||||
float nx, ny, nz;
|
||||
};
|
||||
|
||||
typedef MyVertex MyVector;
|
||||
|
||||
struct MyFace {
|
||||
int v1, v2, v3;
|
||||
float nx, ny, nz;
|
||||
};
|
||||
|
||||
|
||||
class NvFaceInfo {
|
||||
public:
|
||||
|
||||
// vertex indices
|
||||
NvFaceInfo(int v0, int v1, int v2, bool bIsFake = false){
|
||||
m_v0 = v0; m_v1 = v1; m_v2 = v2;
|
||||
m_stripId = -1;
|
||||
m_testStripId = -1;
|
||||
m_experimentId = -1;
|
||||
m_bIsFake = bIsFake;
|
||||
}
|
||||
|
||||
// data members are left public
|
||||
int m_v0, m_v1, m_v2;
|
||||
int m_stripId; // real strip Id
|
||||
int m_testStripId; // strip Id in an experiment
|
||||
int m_experimentId; // in what experiment was it given an experiment Id?
|
||||
bool m_bIsFake; //if true, will be deleted when the strip it's in is deleted
|
||||
};
|
||||
|
||||
class NvEdgeInfo {
|
||||
public:
|
||||
|
||||
// constructor puts 1 ref on us
|
||||
NvEdgeInfo (int v0, int v1){
|
||||
m_v0 = v0;
|
||||
m_v1 = v1;
|
||||
m_face0 = NULL;
|
||||
m_face1 = NULL;
|
||||
m_nextV0 = NULL;
|
||||
m_nextV1 = NULL;
|
||||
|
||||
// we will appear in 2 lists. this is a good
|
||||
// way to make sure we delete it the second time
|
||||
// we hit it in the edge infos
|
||||
m_refCount = 2;
|
||||
|
||||
}
|
||||
|
||||
// ref and unref
|
||||
void Unref () { if (--m_refCount == 0) delete this; }
|
||||
|
||||
// data members are left public
|
||||
unsigned int m_refCount;
|
||||
NvFaceInfo *m_face0, *m_face1;
|
||||
int m_v0, m_v1;
|
||||
NvEdgeInfo *m_nextV0, *m_nextV1;
|
||||
};
|
||||
|
||||
|
||||
// This class is a quick summary of parameters used
|
||||
// to begin a triangle strip. Some operations may
|
||||
// want to create lists of such items, so they were
|
||||
// pulled out into a class
|
||||
class NvStripStartInfo {
|
||||
public:
|
||||
NvStripStartInfo(NvFaceInfo *startFace, NvEdgeInfo *startEdge, bool toV1){
|
||||
m_startFace = startFace;
|
||||
m_startEdge = startEdge;
|
||||
m_toV1 = toV1;
|
||||
}
|
||||
NvFaceInfo *m_startFace;
|
||||
NvEdgeInfo *m_startEdge;
|
||||
bool m_toV1;
|
||||
};
|
||||
|
||||
|
||||
typedef std::vector<NvFaceInfo*> NvFaceInfoVec;
|
||||
typedef std::list <NvFaceInfo*> NvFaceInfoList;
|
||||
typedef std::list <NvFaceInfoVec*> NvStripList;
|
||||
typedef std::vector<NvEdgeInfo*> NvEdgeInfoVec;
|
||||
|
||||
typedef std::vector<unsigned short> WordVec;
|
||||
typedef std::vector<int> IntVec;
|
||||
typedef std::vector<MyVertex> MyVertexVec;
|
||||
typedef std::vector<MyFace> MyFaceVec;
|
||||
|
||||
template<class T>
|
||||
inline void SWAP(T& first, T& second)
|
||||
{
|
||||
T temp = first;
|
||||
first = second;
|
||||
second = temp;
|
||||
}
|
||||
|
||||
// This is a summary of a strip that has been built
|
||||
class NvStripInfo {
|
||||
public:
|
||||
|
||||
// A little information about the creation of the triangle strips
|
||||
NvStripInfo(const NvStripStartInfo &startInfo, int stripId, int experimentId = -1) :
|
||||
m_startInfo(startInfo)
|
||||
{
|
||||
m_stripId = stripId;
|
||||
m_experimentId = experimentId;
|
||||
visited = false;
|
||||
m_numDegenerates = 0;
|
||||
}
|
||||
|
||||
// This is an experiment if the experiment id is >= 0
|
||||
inline bool IsExperiment () const { return m_experimentId >= 0; }
|
||||
|
||||
inline bool IsInStrip (const NvFaceInfo *faceInfo) const
|
||||
{
|
||||
if(faceInfo == NULL)
|
||||
return false;
|
||||
|
||||
return (m_experimentId >= 0 ? faceInfo->m_testStripId == m_stripId : faceInfo->m_stripId == m_stripId);
|
||||
}
|
||||
|
||||
bool SharesEdge(const NvFaceInfo* faceInfo, NvEdgeInfoVec &edgeInfos);
|
||||
|
||||
// take the given forward and backward strips and combine them together
|
||||
void Combine(const NvFaceInfoVec &forward, const NvFaceInfoVec &backward);
|
||||
|
||||
//returns true if the face is "unique", i.e. has a vertex which doesn't exist in the faceVec
|
||||
bool Unique(NvFaceInfoVec& faceVec, NvFaceInfo* face);
|
||||
|
||||
// mark the triangle as taken by this strip
|
||||
bool IsMarked (NvFaceInfo *faceInfo);
|
||||
void MarkTriangle(NvFaceInfo *faceInfo);
|
||||
|
||||
// build the strip
|
||||
void Build(NvEdgeInfoVec &edgeInfos, NvFaceInfoVec &faceInfos);
|
||||
|
||||
// public data members
|
||||
NvStripStartInfo m_startInfo;
|
||||
NvFaceInfoVec m_faces;
|
||||
int m_stripId;
|
||||
int m_experimentId;
|
||||
|
||||
bool visited;
|
||||
|
||||
int m_numDegenerates;
|
||||
};
|
||||
|
||||
typedef std::vector<NvStripInfo*> NvStripInfoVec;
|
||||
|
||||
|
||||
//The actual stripifier
|
||||
class NvStripifier {
|
||||
public:
|
||||
|
||||
// Constructor
|
||||
NvStripifier();
|
||||
~NvStripifier();
|
||||
|
||||
//the target vertex cache size, the structure to place the strips in, and the input indices
|
||||
void Stripify(const WordVec &in_indices, const int in_cacheSize, const int in_minStripLength,
|
||||
const unsigned short maxIndex, NvStripInfoVec &allStrips, NvFaceInfoVec &allFaces);
|
||||
void CreateStrips(const NvStripInfoVec& allStrips, IntVec& stripIndices, const bool bStitchStrips, unsigned int& numSeparateStrips);
|
||||
|
||||
static int GetUniqueVertexInB(NvFaceInfo *faceA, NvFaceInfo *faceB);
|
||||
//static int GetSharedVertex(NvFaceInfo *faceA, NvFaceInfo *faceB);
|
||||
static void GetSharedVertices(NvFaceInfo *faceA, NvFaceInfo *faceB, int* vertex0, int* vertex1);
|
||||
|
||||
static bool IsDegenerate(const NvFaceInfo* face);
|
||||
|
||||
protected:
|
||||
|
||||
WordVec indices;
|
||||
int cacheSize;
|
||||
int minStripLength;
|
||||
float meshJump;
|
||||
bool bFirstTimeResetPoint;
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Big mess of functions called during stripification
|
||||
//
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
//********************
|
||||
bool IsMoneyFace(const NvFaceInfo& face);
|
||||
bool FaceContainsIndex(const NvFaceInfo& face, const unsigned int index);
|
||||
|
||||
bool IsCW(NvFaceInfo *faceInfo, int v0, int v1);
|
||||
bool NextIsCW(const int numIndices);
|
||||
|
||||
bool IsDegenerate(const unsigned short v0, const unsigned short v1, const unsigned short v2);
|
||||
|
||||
static int GetNextIndex(const WordVec &indices, NvFaceInfo *face);
|
||||
static NvEdgeInfo *FindEdgeInfo(NvEdgeInfoVec &edgeInfos, int v0, int v1);
|
||||
static NvFaceInfo *FindOtherFace(NvEdgeInfoVec &edgeInfos, int v0, int v1, NvFaceInfo *faceInfo);
|
||||
NvFaceInfo *FindGoodResetPoint(NvFaceInfoVec &faceInfos, NvEdgeInfoVec &edgeInfos);
|
||||
|
||||
void FindAllStrips(NvStripInfoVec &allStrips, NvFaceInfoVec &allFaceInfos, NvEdgeInfoVec &allEdgeInfos, int numSamples);
|
||||
void SplitUpStripsAndOptimize(NvStripInfoVec &allStrips, NvStripInfoVec &outStrips, NvEdgeInfoVec& edgeInfos, NvFaceInfoVec& outFaceList);
|
||||
void RemoveSmallStrips(NvStripInfoVec& allStrips, NvStripInfoVec& allBigStrips, NvFaceInfoVec& faceList);
|
||||
|
||||
bool FindTraversal(NvFaceInfoVec &faceInfos, NvEdgeInfoVec &edgeInfos, NvStripInfo *strip, NvStripStartInfo &startInfo);
|
||||
int CountRemainingTris(std::list<NvStripInfo*>::iterator iter, std::list<NvStripInfo*>::iterator end);
|
||||
|
||||
void CommitStrips(NvStripInfoVec &allStrips, const NvStripInfoVec &strips);
|
||||
|
||||
float AvgStripSize(const NvStripInfoVec &strips);
|
||||
int FindStartPoint(NvFaceInfoVec &faceInfos, NvEdgeInfoVec &edgeInfos);
|
||||
|
||||
void UpdateCacheStrip(VertexCache* vcache, NvStripInfo* strip);
|
||||
void UpdateCacheFace(VertexCache* vcache, NvFaceInfo* face);
|
||||
float CalcNumHitsStrip(VertexCache* vcache, NvStripInfo* strip);
|
||||
int CalcNumHitsFace(VertexCache* vcache, NvFaceInfo* face);
|
||||
int NumNeighbors(NvFaceInfo* face, NvEdgeInfoVec& edgeInfoVec);
|
||||
|
||||
void BuildStripifyInfo(NvFaceInfoVec &faceInfos, NvEdgeInfoVec &edgeInfos, const unsigned short maxIndex);
|
||||
bool AlreadyExists(NvFaceInfo* faceInfo, NvFaceInfoVec& faceInfos);
|
||||
|
||||
// let our strip info classes and the other classes get
|
||||
// to these protected stripificaton methods if they want
|
||||
friend class NvStripInfo;
|
||||
};
|
||||
|
||||
#endif
|
||||
15
ResourceCompiler/NvTriStrip/RenderPCH.cpp
Normal file
15
ResourceCompiler/NvTriStrip/RenderPCH.cpp
Normal file
@@ -0,0 +1,15 @@
|
||||
/*=============================================================================
|
||||
RenderPC.cpp: Cry Render support precompiled header.
|
||||
Copyright 2001 Crytek Studios. All Rights Reserved.
|
||||
|
||||
Revision history:
|
||||
* Created by Honitch Andrey
|
||||
|
||||
=============================================================================*/
|
||||
|
||||
#include "RenderPCH.h"
|
||||
|
||||
|
||||
/*-----------------------------------------------------------------------------
|
||||
The End.
|
||||
-----------------------------------------------------------------------------*/
|
||||
132
ResourceCompiler/NvTriStrip/RenderPCH.h
Normal file
132
ResourceCompiler/NvTriStrip/RenderPCH.h
Normal file
@@ -0,0 +1,132 @@
|
||||
/*=============================================================================
|
||||
RenderPC.cpp: Cry Render support precompiled header generator.
|
||||
Copyright 2001 Crytek Studios. All Rights Reserved.
|
||||
|
||||
Revision history:
|
||||
* Created by Honitch Andrey
|
||||
|
||||
=============================================================================*/
|
||||
|
||||
#define CRY_API
|
||||
|
||||
#ifdef _DEBUG
|
||||
#define CRTDBG_MAP_ALLOC
|
||||
#endif //_DEBUG
|
||||
|
||||
//! Include standart headers.
|
||||
#include <assert.h>
|
||||
|
||||
//#define PS2
|
||||
//#define OPENGL
|
||||
|
||||
|
||||
#ifdef _XBOX
|
||||
|
||||
//! Include standart headers.
|
||||
#include <assert.h>
|
||||
#include <math.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <assert.h>
|
||||
#include <memory.h>
|
||||
#include <io.h>
|
||||
#include <memory.h>
|
||||
#include <time.h>
|
||||
#include <direct.h>
|
||||
#include <search.h>
|
||||
#include <stdarg.h>
|
||||
|
||||
typedef unsigned long DWORD;
|
||||
typedef unsigned short WORD;
|
||||
typedef unsigned char BYTE;
|
||||
|
||||
#include <xtl.h>
|
||||
|
||||
#else
|
||||
|
||||
#include <windows.h>
|
||||
|
||||
#endif
|
||||
|
||||
// enable memory pool usage
|
||||
#define USE_NEWPOOL
|
||||
#include <CryMemoryManager.h>
|
||||
|
||||
#include "CrtOverrides.h"
|
||||
|
||||
#if defined _DEBUG && defined OPENGL
|
||||
#define DEBUGALLOC
|
||||
#endif
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// STL //////////////////////////////////////////////////////////////////////
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
#include <vector>
|
||||
#include <list>
|
||||
#include <map>
|
||||
#include <hash_map>
|
||||
#include <set>
|
||||
#include <string>
|
||||
#include <algorithm>
|
||||
|
||||
typedef const char* cstr;
|
||||
|
||||
#define SIZEOF_ARRAY(arr) (sizeof(arr)/sizeof((arr)[0]))
|
||||
|
||||
// Include common headers.
|
||||
//#include "Common\CryHelpers.h"
|
||||
|
||||
typedef string String;
|
||||
|
||||
#ifdef DEBUGALLOC
|
||||
|
||||
#include <crtdbg.h>
|
||||
#define DEBUG_CLIENTBLOCK new( _NORMAL_BLOCK, __FILE__, __LINE__)
|
||||
#define new DEBUG_CLIENTBLOCK
|
||||
|
||||
// memman
|
||||
#define calloc(s,t) _calloc_dbg(s, t, _NORMAL_BLOCK, __FILE__, __LINE__)
|
||||
#define malloc(s) _malloc_dbg(s, _NORMAL_BLOCK, __FILE__, __LINE__)
|
||||
#define realloc(p, s) _realloc_dbg(p, s, _NORMAL_BLOCK, __FILE__, __LINE__)
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
#include <list2.h>
|
||||
#include <Names.h>
|
||||
|
||||
#define MAX_TMU 8
|
||||
|
||||
//! Include main interfaces.
|
||||
#include <ICryPak.h>
|
||||
#include <IEntitySystem.h>
|
||||
#include <IProcess.h>
|
||||
#include <ITimer.h>
|
||||
#include <ISystem.h>
|
||||
#include <ILog.h>
|
||||
#include <IPhysics.h>
|
||||
#include <IConsole.h>
|
||||
#include <IRenderer.h>
|
||||
#include <IStreamEngine.h>
|
||||
#include <CrySizer.h>
|
||||
|
||||
#include "Font.h"
|
||||
#include "Except.h"
|
||||
|
||||
#include <Cry_Math.h>
|
||||
#include "Cry_Camera.h"
|
||||
//#include "_Malloc.h"
|
||||
#include "math.h"
|
||||
|
||||
#include <VertexFormats.h>
|
||||
#include <CREPolyMesh.h>
|
||||
|
||||
|
||||
|
||||
#define max(a,b) (((a) > (b)) ? (a) : (b))
|
||||
#define min(a,b) (((a) < (b)) ? (a) : (b))
|
||||
|
||||
|
||||
#define MAX_PATH_LENGTH 512
|
||||
|
||||
79
ResourceCompiler/NvTriStrip/VertexCache.h
Normal file
79
ResourceCompiler/NvTriStrip/VertexCache.h
Normal file
@@ -0,0 +1,79 @@
|
||||
|
||||
#ifndef VERTEX_CACHE_H
|
||||
|
||||
#define VERTEX_CACHE_H
|
||||
|
||||
class VertexCache
|
||||
{
|
||||
|
||||
public:
|
||||
|
||||
VertexCache(int size)
|
||||
{
|
||||
numEntries = size;
|
||||
|
||||
entries = new int[numEntries];
|
||||
|
||||
for(int i = 0; i < numEntries; i++)
|
||||
entries[i] = -1;
|
||||
}
|
||||
|
||||
VertexCache() { VertexCache(16); }
|
||||
~VertexCache() { delete[] entries; entries = 0; }
|
||||
|
||||
bool InCache(int entry)
|
||||
{
|
||||
bool returnVal = false;
|
||||
for(int i = 0; i < numEntries; i++)
|
||||
{
|
||||
if(entries[i] == entry)
|
||||
{
|
||||
returnVal = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return returnVal;
|
||||
}
|
||||
|
||||
int AddEntry(int entry)
|
||||
{
|
||||
int removed;
|
||||
|
||||
removed = entries[numEntries - 1];
|
||||
|
||||
//push everything right one
|
||||
for(int i = numEntries - 2; i >= 0; i--)
|
||||
{
|
||||
entries[i + 1] = entries[i];
|
||||
}
|
||||
|
||||
entries[0] = entry;
|
||||
|
||||
return removed;
|
||||
}
|
||||
|
||||
void Clear()
|
||||
{
|
||||
memset(entries, -1, sizeof(int) * numEntries);
|
||||
}
|
||||
|
||||
void Copy(VertexCache* inVcache)
|
||||
{
|
||||
for(int i = 0; i < numEntries; i++)
|
||||
{
|
||||
inVcache->Set(i, entries[i]);
|
||||
}
|
||||
}
|
||||
|
||||
int At(int index) { return entries[index]; }
|
||||
void Set(int index, int value) { entries[index] = value; }
|
||||
|
||||
private:
|
||||
|
||||
int *entries;
|
||||
int numEntries;
|
||||
|
||||
};
|
||||
|
||||
#endif
|
||||
160
ResourceCompiler/PathUtil.h
Normal file
160
ResourceCompiler/PathUtil.h
Normal file
@@ -0,0 +1,160 @@
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Crytek Engine Source File.
|
||||
// Copyright (C), Crytek Studios, 2002.
|
||||
// -------------------------------------------------------------------------
|
||||
// File name: pathutil.h
|
||||
// Version: v1.00
|
||||
// Created: 5/11/2002 by Timur.
|
||||
// Compilers: Visual Studio.NET
|
||||
// Description: Utility functions to simplify working with paths.
|
||||
// -------------------------------------------------------------------------
|
||||
// History:
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifndef __pathutil_h__
|
||||
#define __pathutil_h__
|
||||
#pragma once
|
||||
|
||||
namespace Path
|
||||
{
|
||||
// compatibility with CPortableString
|
||||
inline const char* CStr(const CString& s) {return s.GetString();}
|
||||
inline char* CStr(CString& s) {return s.GetBuffer();}
|
||||
|
||||
|
||||
//! Split full file name to path and filename
|
||||
//! @param filepath [IN] Full file name inclusing path.
|
||||
//! @param path [OUT] Extracted file path.
|
||||
//! @param file [OUT] Extracted file (with extension).
|
||||
inline void Split( const CString &filepath,CString &path,CString &file )
|
||||
{
|
||||
char path_buffer[_MAX_PATH];
|
||||
char drive[_MAX_DRIVE];
|
||||
char dir[_MAX_DIR];
|
||||
char fname[_MAX_FNAME];
|
||||
char ext[_MAX_EXT];
|
||||
_splitpath( CStr(filepath),drive,dir,fname,ext );
|
||||
_makepath( path_buffer,drive,dir,0,0 );
|
||||
path = path_buffer;
|
||||
_makepath( path_buffer,0,0,fname,ext );
|
||||
file = path_buffer;
|
||||
}
|
||||
|
||||
//! Extract extension from full specified file path.
|
||||
inline CString GetExt( const CString &filepath )
|
||||
{
|
||||
char ext[_MAX_EXT];
|
||||
_splitpath( CStr(filepath),0,0,0,ext );
|
||||
if (ext[0] == '.')
|
||||
return ext+1;
|
||||
|
||||
return ext;
|
||||
}
|
||||
|
||||
//! Extract path from full specified file path.
|
||||
inline CString GetPath( const CString &filepath )
|
||||
{
|
||||
char path_buffer[_MAX_PATH];
|
||||
char drive[_MAX_DRIVE];
|
||||
char dir[_MAX_DIR];
|
||||
_splitpath( CStr(filepath),drive,dir,0,0 );
|
||||
_makepath( path_buffer,drive,dir,0,0 );
|
||||
return path_buffer;
|
||||
}
|
||||
|
||||
//! Extract file name with extension from full specified file path.
|
||||
inline CString GetFile( const CString &filepath )
|
||||
{
|
||||
char path_buffer[_MAX_PATH];
|
||||
char fname[_MAX_FNAME];
|
||||
char ext[_MAX_EXT];
|
||||
_splitpath( CStr(filepath),0,0,fname,ext );
|
||||
_makepath( path_buffer,0,0,fname,ext );
|
||||
return path_buffer;
|
||||
}
|
||||
|
||||
//! Extract file name without extension from full specified file path.
|
||||
inline CString GetFileName( const CString &filepath )
|
||||
{
|
||||
char fname[_MAX_FNAME];
|
||||
_splitpath( CStr(filepath),0,0,fname,0 );
|
||||
return fname;
|
||||
}
|
||||
|
||||
//! Removes the trailing backslash from a given path.
|
||||
inline CString RemoveBackslash( const CString &path )
|
||||
{
|
||||
if (path[0] && path[path.GetLength()-1] == '\\')
|
||||
return path.Mid( 0,path.GetLength()-1 );
|
||||
return path;
|
||||
}
|
||||
|
||||
//!
|
||||
inline CString AddBackslash( const CString &path )
|
||||
{
|
||||
if(path[0] && path[path.GetLength()-1] != '/' && path[path.GetLength()-1] != '\\')
|
||||
return path + "\\";
|
||||
return path;
|
||||
}
|
||||
|
||||
//! Replace extension for given file.
|
||||
inline CString RemoveExtension( const CString &filepath )
|
||||
{
|
||||
char path_buffer[_MAX_PATH];
|
||||
char drive[_MAX_DRIVE];
|
||||
char dir[_MAX_DIR];
|
||||
char fname[_MAX_FNAME];
|
||||
_splitpath( CStr(filepath),drive,dir,fname,0 );
|
||||
_makepath( path_buffer,drive,dir,fname,0 );
|
||||
int len = (int)strlen(path_buffer);
|
||||
// Remove last dot.
|
||||
if (len > 0 && path_buffer[len-1] == '.')
|
||||
path_buffer[len-1] = 0;
|
||||
return path_buffer;
|
||||
}
|
||||
|
||||
//! Replace extension for given file.
|
||||
inline CString ReplaceExtension( const CString &filepath,const CString &ext )
|
||||
{
|
||||
char path_buffer[_MAX_PATH];
|
||||
char drive[_MAX_DRIVE];
|
||||
char dir[_MAX_DIR];
|
||||
char fname[_MAX_FNAME];
|
||||
_splitpath( CStr(filepath),drive,dir,fname,0 );
|
||||
_makepath( path_buffer,drive,dir,fname, CStr(ext) );
|
||||
return path_buffer;
|
||||
}
|
||||
|
||||
//! Makes a fully specified file path from path and file name.
|
||||
inline CString Make( const CString &path,const CString &file )
|
||||
{
|
||||
return AddBackslash(path) + file;
|
||||
}
|
||||
|
||||
//! Replace path for given file.
|
||||
//! \param srcpath e.g. c:\mastercd
|
||||
//! \param destpath e.g. c:\mastercd\temp
|
||||
//! \param filepath relative or absolute e.g. c:\mastercd\objects\sss.cgf
|
||||
//! \return e.g. c:\mastercd\temp\objects\sss.cgf
|
||||
inline CString ReplacePath( const CString &srcpath, const CString &destpath, const CString &filepath )
|
||||
{
|
||||
int iLen=(int)srcpath.GetLength();
|
||||
|
||||
if(_strnicmp(CStr(srcpath),CStr(filepath),(size_t)iLen)==0)
|
||||
{
|
||||
// srcpath is leading part in filepath
|
||||
return Make( destpath ,filepath.Right((int)filepath.GetLength()-iLen) );
|
||||
}
|
||||
else
|
||||
{
|
||||
// srcpath is not a leading part in filepath
|
||||
assert(strstr(CStr(filepath),":")==0); // the following code assumes a relative path name
|
||||
|
||||
return Make(CStr(destpath),CStr(filepath));
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
#endif // __pathutil_h__
|
||||
148
ResourceCompiler/PortableString.h
Normal file
148
ResourceCompiler/PortableString.h
Normal file
@@ -0,0 +1,148 @@
|
||||
// defines the portable string that will replace ATL string on platforms without ATL
|
||||
#ifndef _RC_PORTABLE_STRING_HDR_
|
||||
#define _RC_PORTABLE_STRING_HDR_
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
|
||||
class CPortableString: public string
|
||||
{
|
||||
//char& operator [] (int i) {return (*this)[i];}
|
||||
//char operator [] (int i) const {return (*this)[i];}
|
||||
public:
|
||||
//operator const char* () const {return this->c_str();}
|
||||
|
||||
CPortableString(){}
|
||||
CPortableString(const char* szThat): string(szThat){}
|
||||
CPortableString(const char* szThat, size_t nCount): string (szThat, nCount) {}
|
||||
CPortableString(const string& str):string(str) {}
|
||||
|
||||
size_t GetLength() const {return length();}
|
||||
|
||||
CPortableString Mid( int iFirst ) const {return iFirst<length() ? c_str() + iFirst : CPortableString();}
|
||||
CPortableString Mid (int iFirst, int nCount) const {return iFirst<length() ? CPortableString(c_str()+iFirst, nCount):CPortableString();}
|
||||
CPortableString Right (int nCount)const
|
||||
{
|
||||
size_t nLength = GetLength();
|
||||
if( nCount >= nLength )
|
||||
{
|
||||
return( *this );
|
||||
}
|
||||
|
||||
return( CPortableString( GetString()+nLength-nCount, nCount ) );
|
||||
}
|
||||
|
||||
char* GetBuffer() {return &(*this)[0];}
|
||||
const char* GetString()const {return c_str();}
|
||||
|
||||
int Replace( char chOld, char chNew )
|
||||
{
|
||||
int nCount = 0;
|
||||
if (chOld != chNew)
|
||||
for (iterator it = begin(); it != end(); ++it)
|
||||
if (*it == chOld)
|
||||
{
|
||||
*it = chNew;
|
||||
++nCount;
|
||||
}
|
||||
return nCount;
|
||||
}
|
||||
|
||||
// Format data using format string 'pszFormat'
|
||||
void __cdecl Format( const char* pszFormat, ... )
|
||||
{
|
||||
va_list argList;
|
||||
va_start( argList, pszFormat );
|
||||
char szBuf[0x400];
|
||||
_vsnprintf (szBuf, sizeof(szBuf), pszFormat, argList);
|
||||
va_end( argList );
|
||||
}
|
||||
|
||||
static int GetFormattedLength( LPCSTR pszFormat, va_list args ) throw()
|
||||
{
|
||||
return _vscprintf( pszFormat, args );
|
||||
}
|
||||
|
||||
// Find the first occurrence of string 'pszSub', starting at index 'iStart'
|
||||
int Find( const char* pszSub, int iStart = 0 ) const
|
||||
{
|
||||
// nLength is in XCHARs
|
||||
int nLength = GetLength();
|
||||
if( iStart > nLength )
|
||||
{
|
||||
return( -1 );
|
||||
}
|
||||
|
||||
// find first matching substring
|
||||
const char* psz = strstr( GetString()+iStart, pszSub );
|
||||
|
||||
// return -1 for not found, distance from beginning otherwise
|
||||
return( (psz == NULL) ? -1 : int( psz-GetString() ) );
|
||||
}
|
||||
// Find the first occurrence of character 'ch', starting at index 'iStart'
|
||||
int Find( char ch, int iStart = 0 ) const throw()
|
||||
{
|
||||
// nLength is in XCHARs
|
||||
int nLength = GetLength();
|
||||
if( iStart >= nLength)
|
||||
{
|
||||
return( -1 );
|
||||
}
|
||||
|
||||
// find first single character
|
||||
const char* psz = strchr( GetString()+iStart, ch );
|
||||
|
||||
// return -1 if not found and index otherwise
|
||||
return( (psz == NULL) ? -1 : int( psz-GetString() ) );
|
||||
}
|
||||
|
||||
CPortableString Left (int nCount) const
|
||||
{
|
||||
return CPortableString(GetString(), nCount);
|
||||
}
|
||||
|
||||
bool IsEmpty() const {return empty();}
|
||||
|
||||
|
||||
// Remove all leading and trailing whitespace
|
||||
CPortableString& Trim()
|
||||
{
|
||||
return( TrimRight().TrimLeft() );
|
||||
}
|
||||
|
||||
inline static bool IsWhitespace (char c)
|
||||
{
|
||||
return (c >= '\x09' && c <= '\x0D') || c == ' ';
|
||||
}
|
||||
|
||||
CPortableString& TrimLeft()
|
||||
{
|
||||
for (size_t i = 0; i < length(); ++i)
|
||||
if (!IsWhitespace(c_str()[i]))
|
||||
{
|
||||
erase (begin(), begin()+i);
|
||||
break;
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
CPortableString& TrimRight()
|
||||
{
|
||||
for (int i = length()-1; i >= 0; --i)
|
||||
if (!IsWhitespace(c_str()[i]))
|
||||
{
|
||||
resize(i+1);
|
||||
break;
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
||||
//const CPortableString operator + (const CPortableString& str) const {return <const string&>(::operator +(str);}
|
||||
};
|
||||
|
||||
// compatibility with STL Utils
|
||||
|
||||
|
||||
|
||||
#endif
|
||||
44
ResourceCompiler/QuaternionExponentX87.h
Normal file
44
ResourceCompiler/QuaternionExponentX87.h
Normal file
@@ -0,0 +1,44 @@
|
||||
#ifndef _CRY_ANIMATION_QUATERNION_EXPONENT_HDR_
|
||||
#define _CRY_ANIMATION_QUATERNION_EXPONENT_HDR_
|
||||
|
||||
#include "platform.h"
|
||||
|
||||
#if defined(_CPU_X86) && !defined(LINUX)
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// x87 asm optimized quaternion exponent
|
||||
// Estimated runtime in good conditions: 315 cycles on P4
|
||||
// PARAMETERS:
|
||||
// pSrcVector[IN] - the vector to calculate the exponent for
|
||||
// pDstQuat [OUT]- the quaternion (exponent of the input)
|
||||
// NOTE:
|
||||
// The input vector mimics a quaternion with 0 real component (W)
|
||||
// This version uses FSINCOS, which takes ~70% of execution time
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
void quaternionExponent_x87(const float* pSrc, float* pDst);
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// x87 asm optimized quaternion exponent
|
||||
// Estimated runtime: 110 cycles on P4
|
||||
// PARAMETERS:
|
||||
// pSrcVector[IN] - the vector to calculate the exponent for
|
||||
// pDstQuat [OUT]- the quaternion (exponent of the input)
|
||||
// WARNING:
|
||||
// the source vector length should be no more than 3-4, otherwise the sin/cos
|
||||
// approximations won't work
|
||||
// NOTE:
|
||||
// The input vector mimics a quaternion with 0 real component (W)
|
||||
// This version uses approximation to FSINCOS (tailor series up to 9th magnitude)
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
void quaternionExponent_x87approx(const float* pSrc, float* pDst);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
#endif
|
||||
30
ResourceCompiler/ResComDefs.h
Normal file
30
ResourceCompiler/ResComDefs.h
Normal file
@@ -0,0 +1,30 @@
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Crytek Engine Source File.
|
||||
// Copyright (C), Crytek Studios, 2002.
|
||||
// -------------------------------------------------------------------------
|
||||
// File name: rescomdefs.h
|
||||
// Version: v1.00
|
||||
// Created: 5/11/2002 by Timur.
|
||||
// Compilers: Visual Studio.NET
|
||||
// Description:
|
||||
// -------------------------------------------------------------------------
|
||||
// History:
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifndef __rescomdefs_h__
|
||||
#define __rescomdefs_h__
|
||||
#pragma once
|
||||
|
||||
#include "StlUtils.h"
|
||||
#include "PathUtil.h"
|
||||
#include "ConvertContext.h"
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// Various global defines.
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
#define RC_INI_FILE "rc.ini"
|
||||
#define DEF_FILE_EXTENSION "_rc"
|
||||
|
||||
#endif // __rescomdefs_h__
|
||||
1073
ResourceCompiler/ResourceCompiler.cpp
Normal file
1073
ResourceCompiler/ResourceCompiler.cpp
Normal file
File diff suppressed because it is too large
Load Diff
176
ResourceCompiler/ResourceCompiler.h
Normal file
176
ResourceCompiler/ResourceCompiler.h
Normal file
@@ -0,0 +1,176 @@
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Crytek Engine Source File.
|
||||
// Copyright (C), Crytek Studios, 2002.
|
||||
// -------------------------------------------------------------------------
|
||||
// File name: resourcecompiler.h
|
||||
// Version: v1.00
|
||||
// Created: 4/11/2002 by Timur.
|
||||
// Compilers: Visual Studio.NET
|
||||
// Description:
|
||||
// -------------------------------------------------------------------------
|
||||
// History:
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifndef __resourcecompiler_h__
|
||||
#define __resourcecompiler_h__
|
||||
#pragma once
|
||||
|
||||
#include "IRCLog.h"
|
||||
#include "IResCompiler.h"
|
||||
#include "Config.h"
|
||||
#include "ExtensionManager.h"
|
||||
|
||||
#include <map> // stl multimap<>
|
||||
#include <string> // stl string
|
||||
|
||||
|
||||
|
||||
|
||||
/** Implementation of IResCompiler interface.
|
||||
*/
|
||||
class ResourceCompiler :
|
||||
public IResourceCompiler,
|
||||
public IRCLog
|
||||
{
|
||||
public:
|
||||
ResourceCompiler();
|
||||
~ResourceCompiler();
|
||||
|
||||
//! e.g. print dependencies
|
||||
void PostBuild();
|
||||
|
||||
// interface IResourceCompiler ---------------------------------------------
|
||||
|
||||
virtual void RegisterConvertor( IConvertor *conv );
|
||||
virtual FILE* OpenFile( const char *filename,const char *mode );
|
||||
bool GetFileTime( const char *filename,FILETIME *ftimeModify, FILETIME*ftimeCreate =NULL );
|
||||
|
||||
// returns the file unix time - the latest of modification and creation times
|
||||
DWORD GetFileUnixTimeMax (const char* filename);
|
||||
|
||||
// returns the file unix time - the earliest of modification and creation times
|
||||
DWORD GetFileUnixTimeMin (const char* filename);
|
||||
|
||||
virtual bool CompileFile( const char *filename, const char *outroot, const char *outpath );
|
||||
|
||||
//! Load and parse the Crytek Chunked File into the universal (very big) structure
|
||||
//! The caller should then call Release on the structure to free the mem
|
||||
//! @param filename Full filename including path to the file
|
||||
virtual CryChunkedFile* LoadCryChunkedFile (const char* szFileName);
|
||||
|
||||
virtual IRCLog *GetIRCLog();
|
||||
|
||||
virtual void AddDependencyMaterial( const char *inszSrcFilename, const char *inszMatName, const char *inszScriptName );
|
||||
|
||||
virtual void AddDependencyFile( const char *inszSrcFilename, const char *inszPathFileName );
|
||||
|
||||
|
||||
// interface IRCLog ---------------------------------------------
|
||||
|
||||
void LogLine( const ELogType ineType, const char* szText );
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// Resource compiler implementation.
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
bool Compile( Platform platform,IConfig* config,const char *filespec );
|
||||
const char* GetSectionName( Platform platform ) const;
|
||||
|
||||
//! call this if user asks for help
|
||||
void show_help();
|
||||
|
||||
void EnsureDirectoriesPresent(const char *path);
|
||||
|
||||
//! Returns the main application window
|
||||
HWND GetHWnd();
|
||||
HWND GetEmptyWindow();
|
||||
|
||||
IPhysicalWorld* GetPhysicalWorld();
|
||||
|
||||
Config m_MainConfig; //!<
|
||||
|
||||
private:
|
||||
|
||||
// private structures
|
||||
|
||||
typedef std::multimap<string,string> CFileDepMap;
|
||||
typedef std::pair<string,string> CFileDepPair;
|
||||
|
||||
class CMatDep
|
||||
{
|
||||
public:
|
||||
string m_sMatName; //!<
|
||||
string m_sScriptName; //!<
|
||||
|
||||
bool operator==( const CMatDep &inRhS ) const
|
||||
{
|
||||
return(inRhS.m_sMatName==m_sMatName && inRhS.m_sScriptName==m_sScriptName);
|
||||
}
|
||||
};
|
||||
|
||||
// helper to get order for CMatDep
|
||||
struct CMatDepOrder: public std::binary_function< CMatDep, CMatDep, bool>
|
||||
{
|
||||
bool operator() ( const CMatDep &a, const CMatDep &b ) const
|
||||
{
|
||||
// first sort by m_sScriptName (neccessary for printout)
|
||||
if(a.m_sScriptName<b.m_sScriptName)return(true);
|
||||
if(a.m_sScriptName>b.m_sScriptName)return(false);
|
||||
|
||||
// then by m_sMatName
|
||||
if(a.m_sMatName<b.m_sMatName)return(true);
|
||||
if(a.m_sMatName>b.m_sMatName)return(false);
|
||||
|
||||
return(false);
|
||||
}
|
||||
};
|
||||
|
||||
typedef std::multimap<CMatDep,string,CMatDepOrder> CMatDepMap;
|
||||
typedef std::pair<CMatDep,string> CMatDepPair;
|
||||
|
||||
// ------------------------------------------------
|
||||
|
||||
|
||||
|
||||
IConfig * m_config; //!< Current global configuration settings.
|
||||
ICfgFile * m_presets;
|
||||
Platform m_platform; //!< Current compilation platform.
|
||||
|
||||
ExtensionManager m_extensionManager; //!<
|
||||
|
||||
IPhysicalWorld* m_pIPhysicalWorld; //!<
|
||||
|
||||
|
||||
CFileDepMap m_FileDependencies; //!< key=dependency e.g. nm.dds value=file that is using it e.g. ball.cgf
|
||||
CMatDepMap m_MaterialDependencies; //!< key=materialname+scriptmaterialname value=file that is using it
|
||||
|
||||
// log files
|
||||
FILE * m_hLogFile; //!< for all messages, might be 0 (no file logging)
|
||||
FILE * m_hWarningLogFile; //!< for all warnigns only, might be 0 (no file logging)
|
||||
FILE * m_hErrorLogFile; //!< for all errors only, might be 0 (no file logging)
|
||||
|
||||
//
|
||||
bool m_bWarningHeaderLine; //!< true= header was already printed, false= header needs to be printed
|
||||
bool m_bErrorHeaderLine; //!< true= header was already printed, false= header needs to be printed
|
||||
bool m_bStatistics; //!< true= show statistics.
|
||||
bool m_bQuiet; //!< true= don't log anything to console, otherwise false
|
||||
string m_sHeaderLine; //!<
|
||||
|
||||
HWND m_hEmptyWindow;
|
||||
//!
|
||||
void InitPhysics();
|
||||
|
||||
//!
|
||||
void ShowFileDependencies();
|
||||
|
||||
//!
|
||||
void ShowMaterialDependencies();
|
||||
|
||||
//! to remove old files for less confusion
|
||||
void RemoveOutputFiles();
|
||||
|
||||
void SetHeaderLine( const char *inszLine );
|
||||
};
|
||||
|
||||
#endif // __resourcecompiler_h__
|
||||
509
ResourceCompiler/ResourceCompiler.vcproj
Normal file
509
ResourceCompiler/ResourceCompiler.vcproj
Normal file
@@ -0,0 +1,509 @@
|
||||
<?xml version="1.0" encoding="windows-1251"?>
|
||||
<VisualStudioProject
|
||||
ProjectType="Visual C++"
|
||||
Version="7.10"
|
||||
Name="ResourceCompiler"
|
||||
ProjectGUID="{2F21D2A8-925B-4A73-A32B-D111580614C3}"
|
||||
SccProjectName="Perforce Project"
|
||||
SccAuxPath=""
|
||||
SccLocalPath=".."
|
||||
SccProvider="MSSCCI:Perforce SCM"
|
||||
Keyword="Win32Proj">
|
||||
<Platforms>
|
||||
<Platform
|
||||
Name="Win32"/>
|
||||
</Platforms>
|
||||
<Configurations>
|
||||
<Configuration
|
||||
Name="Debug|Win32"
|
||||
OutputDirectory="D:\Games\FC\Bin32"
|
||||
IntermediateDirectory="Debug"
|
||||
ConfigurationType="1"
|
||||
CharacterSet="2">
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
Optimization="0"
|
||||
OptimizeForProcessor="0"
|
||||
AdditionalIncludeDirectories="..\CryCommon"
|
||||
PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE"
|
||||
MinimalRebuild="TRUE"
|
||||
BasicRuntimeChecks="3"
|
||||
RuntimeLibrary="3"
|
||||
BufferSecurityCheck="FALSE"
|
||||
EnableFunctionLevelLinking="TRUE"
|
||||
UsePrecompiledHeader="3"
|
||||
WarningLevel="3"
|
||||
Detect64BitPortabilityProblems="FALSE"
|
||||
DebugInformationFormat="4"/>
|
||||
<Tool
|
||||
Name="VCCustomBuildTool"/>
|
||||
<Tool
|
||||
Name="VCLinkerTool"
|
||||
AdditionalDependencies="dbghelp.lib"
|
||||
OutputFile="$(OutDir)/rc.exe"
|
||||
LinkIncremental="2"
|
||||
GenerateDebugInformation="TRUE"
|
||||
ProgramDatabaseFile="$(OutDir)/rc.pdb"
|
||||
SubSystem="1"
|
||||
TargetMachine="1"/>
|
||||
<Tool
|
||||
Name="VCMIDLTool"/>
|
||||
<Tool
|
||||
Name="VCPostBuildEventTool"/>
|
||||
<Tool
|
||||
Name="VCPreBuildEventTool"/>
|
||||
<Tool
|
||||
Name="VCPreLinkEventTool"/>
|
||||
<Tool
|
||||
Name="VCResourceCompilerTool"/>
|
||||
<Tool
|
||||
Name="VCWebServiceProxyGeneratorTool"/>
|
||||
<Tool
|
||||
Name="VCXMLDataGeneratorTool"/>
|
||||
<Tool
|
||||
Name="VCWebDeploymentTool"/>
|
||||
<Tool
|
||||
Name="VCManagedWrapperGeneratorTool"/>
|
||||
<Tool
|
||||
Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
|
||||
</Configuration>
|
||||
<Configuration
|
||||
Name="Release|Win32"
|
||||
OutputDirectory="D:\Games\FC\Bin32"
|
||||
IntermediateDirectory="Release"
|
||||
ConfigurationType="1"
|
||||
CharacterSet="2">
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
Optimization="3"
|
||||
GlobalOptimizations="TRUE"
|
||||
InlineFunctionExpansion="2"
|
||||
EnableIntrinsicFunctions="TRUE"
|
||||
FavorSizeOrSpeed="2"
|
||||
OmitFramePointers="TRUE"
|
||||
EnableFiberSafeOptimizations="FALSE"
|
||||
OptimizeForProcessor="2"
|
||||
OptimizeForWindowsApplication="FALSE"
|
||||
AdditionalIncludeDirectories="..\CryCommon"
|
||||
PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE;_RELEASE"
|
||||
StringPooling="TRUE"
|
||||
RuntimeLibrary="2"
|
||||
BufferSecurityCheck="FALSE"
|
||||
EnableFunctionLevelLinking="FALSE"
|
||||
EnableEnhancedInstructionSet="0"
|
||||
UsePrecompiledHeader="3"
|
||||
WarningLevel="3"
|
||||
Detect64BitPortabilityProblems="FALSE"
|
||||
DebugInformationFormat="3"/>
|
||||
<Tool
|
||||
Name="VCCustomBuildTool"/>
|
||||
<Tool
|
||||
Name="VCLinkerTool"
|
||||
AdditionalOptions="/fixed:no"
|
||||
AdditionalDependencies="dbghelp.lib"
|
||||
OutputFile="$(OutDir)/rc.exe"
|
||||
LinkIncremental="1"
|
||||
GenerateDebugInformation="TRUE"
|
||||
SubSystem="1"
|
||||
OptimizeReferences="2"
|
||||
EnableCOMDATFolding="2"
|
||||
TargetMachine="1"/>
|
||||
<Tool
|
||||
Name="VCMIDLTool"/>
|
||||
<Tool
|
||||
Name="VCPostBuildEventTool"/>
|
||||
<Tool
|
||||
Name="VCPreBuildEventTool"/>
|
||||
<Tool
|
||||
Name="VCPreLinkEventTool"/>
|
||||
<Tool
|
||||
Name="VCResourceCompilerTool"/>
|
||||
<Tool
|
||||
Name="VCWebServiceProxyGeneratorTool"/>
|
||||
<Tool
|
||||
Name="VCXMLDataGeneratorTool"/>
|
||||
<Tool
|
||||
Name="VCWebDeploymentTool"/>
|
||||
<Tool
|
||||
Name="VCManagedWrapperGeneratorTool"/>
|
||||
<Tool
|
||||
Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
|
||||
</Configuration>
|
||||
<Configuration
|
||||
Name="Debug64|Win32"
|
||||
OutputDirectory="D:\Games\FC\Bin32"
|
||||
IntermediateDirectory="Debug64"
|
||||
ConfigurationType="1"
|
||||
CharacterSet="2">
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
Optimization="0"
|
||||
InlineFunctionExpansion="2"
|
||||
AdditionalIncludeDirectories="..\CryCommon"
|
||||
PreprocessorDefinitions="_AMD64_;WIN64;WIN32;_DEBUG;_CONSOLE"
|
||||
BasicRuntimeChecks="0"
|
||||
SmallerTypeCheck="FALSE"
|
||||
RuntimeLibrary="3"
|
||||
BufferSecurityCheck="FALSE"
|
||||
UsePrecompiledHeader="3"
|
||||
WarningLevel="3"
|
||||
Detect64BitPortabilityProblems="TRUE"
|
||||
DebugInformationFormat="3"/>
|
||||
<Tool
|
||||
Name="VCCustomBuildTool"/>
|
||||
<Tool
|
||||
Name="VCLinkerTool"
|
||||
AdditionalOptions="/MACHINE:AMD64"
|
||||
AdditionalDependencies="dbghelp.lib"
|
||||
OutputFile="$(OutDir)/rc64.exe"
|
||||
LinkIncremental="2"
|
||||
GenerateDebugInformation="TRUE"
|
||||
ProgramDatabaseFile="$(OutDir)/$(TargetName).pdb"
|
||||
SubSystem="1"
|
||||
LargeAddressAware="2"
|
||||
TargetMachine="0"/>
|
||||
<Tool
|
||||
Name="VCMIDLTool"/>
|
||||
<Tool
|
||||
Name="VCPostBuildEventTool"/>
|
||||
<Tool
|
||||
Name="VCPreBuildEventTool"/>
|
||||
<Tool
|
||||
Name="VCPreLinkEventTool"/>
|
||||
<Tool
|
||||
Name="VCResourceCompilerTool"/>
|
||||
<Tool
|
||||
Name="VCWebServiceProxyGeneratorTool"/>
|
||||
<Tool
|
||||
Name="VCXMLDataGeneratorTool"/>
|
||||
<Tool
|
||||
Name="VCWebDeploymentTool"/>
|
||||
<Tool
|
||||
Name="VCManagedWrapperGeneratorTool"/>
|
||||
<Tool
|
||||
Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
|
||||
</Configuration>
|
||||
<Configuration
|
||||
Name="Release64|Win32"
|
||||
OutputDirectory="D:\Games\FC\Bin32"
|
||||
IntermediateDirectory="Release64"
|
||||
ConfigurationType="1"
|
||||
CharacterSet="2"
|
||||
WholeProgramOptimization="TRUE">
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
Optimization="0"
|
||||
InlineFunctionExpansion="0"
|
||||
EnableIntrinsicFunctions="FALSE"
|
||||
AdditionalIncludeDirectories="..\CryCommon"
|
||||
PreprocessorDefinitions="_AMD64_;WIN64;WIN32;NDEBUG;_CONSOLE"
|
||||
StringPooling="TRUE"
|
||||
BasicRuntimeChecks="0"
|
||||
SmallerTypeCheck="FALSE"
|
||||
RuntimeLibrary="2"
|
||||
BufferSecurityCheck="FALSE"
|
||||
UsePrecompiledHeader="3"
|
||||
WarningLevel="3"
|
||||
Detect64BitPortabilityProblems="TRUE"
|
||||
DebugInformationFormat="3"/>
|
||||
<Tool
|
||||
Name="VCCustomBuildTool"/>
|
||||
<Tool
|
||||
Name="VCLinkerTool"
|
||||
AdditionalOptions="/MACHINE:AMD64"
|
||||
AdditionalDependencies="dbghelp.lib"
|
||||
OutputFile="$(OutDir)/rc64.exe"
|
||||
LinkIncremental="1"
|
||||
GenerateDebugInformation="TRUE"
|
||||
ProgramDatabaseFile="$(OutDir)/$(TargetName).pdb"
|
||||
SubSystem="1"
|
||||
LargeAddressAware="2"
|
||||
TargetMachine="0"/>
|
||||
<Tool
|
||||
Name="VCMIDLTool"/>
|
||||
<Tool
|
||||
Name="VCPostBuildEventTool"/>
|
||||
<Tool
|
||||
Name="VCPreBuildEventTool"/>
|
||||
<Tool
|
||||
Name="VCPreLinkEventTool"/>
|
||||
<Tool
|
||||
Name="VCResourceCompilerTool"/>
|
||||
<Tool
|
||||
Name="VCWebServiceProxyGeneratorTool"/>
|
||||
<Tool
|
||||
Name="VCXMLDataGeneratorTool"/>
|
||||
<Tool
|
||||
Name="VCWebDeploymentTool"/>
|
||||
<Tool
|
||||
Name="VCManagedWrapperGeneratorTool"/>
|
||||
<Tool
|
||||
Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
|
||||
</Configuration>
|
||||
</Configurations>
|
||||
<References>
|
||||
</References>
|
||||
<Files>
|
||||
<Filter
|
||||
Name="Source Files"
|
||||
Filter="cpp;c;cxx;def;odl;idl;hpj;bat;asm">
|
||||
<File
|
||||
RelativePath="CfgFile.cpp">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="CfgFile.h">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="ChunkFileReader.cpp">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="ChunkFileReader.h">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="CmdLine.cpp">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="CmdLine.h">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="Config.cpp">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="Config.h">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="ConvertContext.h">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="ExtensionManager.cpp">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="ExtensionManager.h">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="FileMapping.cpp">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="FileMapping.h">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="FileUtil.cpp">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="FileUtil.h">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="PathUtil.h">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="ResComDefs.h">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="ResourceCompiler.cpp">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="ResourceCompiler.h">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="stdafx.cpp">
|
||||
<FileConfiguration
|
||||
Name="Debug|Win32">
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
UsePrecompiledHeader="1"/>
|
||||
</FileConfiguration>
|
||||
<FileConfiguration
|
||||
Name="Release|Win32">
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
UsePrecompiledHeader="1"/>
|
||||
</FileConfiguration>
|
||||
<FileConfiguration
|
||||
Name="Debug64|Win32">
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
UsePrecompiledHeader="1"/>
|
||||
</FileConfiguration>
|
||||
<FileConfiguration
|
||||
Name="Release64|Win32">
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
UsePrecompiledHeader="1"/>
|
||||
</FileConfiguration>
|
||||
</File>
|
||||
</Filter>
|
||||
<Filter
|
||||
Name="Header Files"
|
||||
Filter="h;hpp;hxx;hm;inl;inc">
|
||||
<File
|
||||
RelativePath="DebugLog.h">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="PortableString.h">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="stdafx.h">
|
||||
</File>
|
||||
</Filter>
|
||||
<Filter
|
||||
Name="Resource Files"
|
||||
Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe">
|
||||
</Filter>
|
||||
<Filter
|
||||
Name="Interfaces"
|
||||
Filter="">
|
||||
<File
|
||||
RelativePath="ICfgFile.h">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="IConfig.h">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="IConvertor.h">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="IRCLog.h">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="IResCompiler.h">
|
||||
</File>
|
||||
</Filter>
|
||||
<Filter
|
||||
Name="NvTriStrip"
|
||||
Filter="">
|
||||
<File
|
||||
RelativePath="NvTriStrip\NvTriStrip.cpp">
|
||||
<FileConfiguration
|
||||
Name="Debug|Win32">
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
UsePrecompiledHeader="0"/>
|
||||
</FileConfiguration>
|
||||
<FileConfiguration
|
||||
Name="Release|Win32">
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
UsePrecompiledHeader="0"/>
|
||||
</FileConfiguration>
|
||||
<FileConfiguration
|
||||
Name="Debug64|Win32">
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
UsePrecompiledHeader="0"/>
|
||||
</FileConfiguration>
|
||||
<FileConfiguration
|
||||
Name="Release64|Win32">
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
UsePrecompiledHeader="0"/>
|
||||
</FileConfiguration>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="NvTriStrip\NvTriStrip.h">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="NvTriStrip\NvTriStripObjects.cpp">
|
||||
<FileConfiguration
|
||||
Name="Debug|Win32">
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
UsePrecompiledHeader="0"/>
|
||||
</FileConfiguration>
|
||||
<FileConfiguration
|
||||
Name="Release|Win32">
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
UsePrecompiledHeader="0"/>
|
||||
</FileConfiguration>
|
||||
<FileConfiguration
|
||||
Name="Debug64|Win32">
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
UsePrecompiledHeader="0"/>
|
||||
</FileConfiguration>
|
||||
<FileConfiguration
|
||||
Name="Release64|Win32">
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
UsePrecompiledHeader="0"/>
|
||||
</FileConfiguration>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="NvTriStrip\NvTriStripObjects.h">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="NvTriStrip\RenderPCH.cpp">
|
||||
<FileConfiguration
|
||||
Name="Debug|Win32"
|
||||
ExcludedFromBuild="TRUE">
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"/>
|
||||
</FileConfiguration>
|
||||
<FileConfiguration
|
||||
Name="Release|Win32"
|
||||
ExcludedFromBuild="TRUE">
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"/>
|
||||
</FileConfiguration>
|
||||
<FileConfiguration
|
||||
Name="Debug64|Win32"
|
||||
ExcludedFromBuild="TRUE">
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"/>
|
||||
</FileConfiguration>
|
||||
<FileConfiguration
|
||||
Name="Release64|Win32"
|
||||
ExcludedFromBuild="TRUE">
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"/>
|
||||
</FileConfiguration>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="NvTriStrip\RenderPCH.h">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="NvTriStrip\VertexCache.h">
|
||||
</File>
|
||||
</Filter>
|
||||
<Filter
|
||||
Name="Utils"
|
||||
Filter="">
|
||||
<File
|
||||
RelativePath="CgfUtils.cpp">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="CgfUtils.h">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="CryBoneDesc.cpp">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="CryBoneDesc.h">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="CryBoneHierarchyLoader.cpp">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="CryBoneHierarchyLoader.h">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="CryChunkedFile.cpp">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="CryChunkedFile.h">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="CryVertexBinding.cpp">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="CryVertexBinding.h">
|
||||
</File>
|
||||
</Filter>
|
||||
<Filter
|
||||
Name="Math"
|
||||
Filter="">
|
||||
</Filter>
|
||||
</Files>
|
||||
<Globals>
|
||||
</Globals>
|
||||
</VisualStudioProject>
|
||||
10
ResourceCompiler/ResourceCompiler.vcproj.vspscc
Normal file
10
ResourceCompiler/ResourceCompiler.vcproj.vspscc
Normal file
@@ -0,0 +1,10 @@
|
||||
""
|
||||
{
|
||||
"FILE_VERSION" = "9237"
|
||||
"ENLISTMENT_CHOICE" = "NEVER"
|
||||
"PROJECT_FILE_RELATIVE_PATH" = "relative:ResourceCompiler"
|
||||
"NUMBER_OF_EXCLUDED_FILES" = "0"
|
||||
"ORIGINAL_PROJECT_FILE_PATH" = ""
|
||||
"NUMBER_OF_NESTED_PROJECTS" = "0"
|
||||
"SOURCE_CONTROL_SETTINGS_PROVIDER" = "PROJECT"
|
||||
}
|
||||
8
ResourceCompiler/stdafx.cpp
Normal file
8
ResourceCompiler/stdafx.cpp
Normal file
@@ -0,0 +1,8 @@
|
||||
// stdafx.cpp : source file that includes just the standard includes
|
||||
// ResourceCompiler.pch will be the pre-compiled header
|
||||
// stdafx.obj will contain the pre-compiled type information
|
||||
|
||||
#include "stdafx.h"
|
||||
|
||||
// TODO: reference any additional headers you need in STDAFX.H
|
||||
// and not in this file
|
||||
78
ResourceCompiler/stdafx.h
Normal file
78
ResourceCompiler/stdafx.h
Normal file
@@ -0,0 +1,78 @@
|
||||
// stdafx.h : include file for standard system include files,
|
||||
// or project specific include files that are used frequently, but
|
||||
// are changed infrequently
|
||||
//
|
||||
|
||||
#pragma once
|
||||
|
||||
#define NOT_USE_CRY_MEMORY_MANAGER
|
||||
#include <platform.h>
|
||||
#include <stdio.h>
|
||||
#include <tchar.h>
|
||||
// Windows Header Files:
|
||||
#ifdef WIN64
|
||||
#include "PortableString.h"
|
||||
typedef CPortableString CString;
|
||||
#else
|
||||
#include <atlbase.h>
|
||||
#include <atlstr.h>
|
||||
#endif
|
||||
|
||||
// Standart C headers.
|
||||
#include <direct.h>
|
||||
#include <assert.h>
|
||||
|
||||
// STL headers.
|
||||
#include <vector>
|
||||
#include <list>
|
||||
#include <algorithm>
|
||||
#include <functional>
|
||||
#include <map>
|
||||
#include <set>
|
||||
#include <string>
|
||||
#ifdef WIN64
|
||||
#define hash_map map
|
||||
#include "StlUtils.h"
|
||||
//! Specialization of string to const char cast.
|
||||
namespace stl{
|
||||
template <>
|
||||
inline const char* constchar_cast( const CPortableString &str )
|
||||
{
|
||||
return str.GetString();
|
||||
}
|
||||
}
|
||||
|
||||
#else
|
||||
#include <hash_map>
|
||||
#endif
|
||||
//#include <StlDbgAlloc.h>
|
||||
// to make smoother transition back from cry to std namespace...
|
||||
#define cry std
|
||||
#define CRY_AS_STD
|
||||
|
||||
// emulate the facility present in the cry engine
|
||||
#include "ILog.h"
|
||||
|
||||
#include <smartptr.h>
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
#include "ResComDefs.h"
|
||||
|
||||
#include <Cry_Math.h>
|
||||
#include <primitives.h>
|
||||
#include <CryHeaders.h>
|
||||
#include <IPhysics.h>
|
||||
|
||||
#include <IRenderer.h>
|
||||
#include <IShader.h>
|
||||
#include <LeafBuffer.h>
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// globals.
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
extern void MessageBoxError( const char *format,... );
|
||||
// extern void Log( const char *format,... );
|
||||
|
||||
#ifndef SIZEOF_ARRAY
|
||||
#define SIZEOF_ARRAY(arr) (sizeof(arr)/sizeof((arr)[0]))
|
||||
#endif
|
||||
Reference in New Issue
Block a user