Added LibCommon as a submodule (PWE code still needs to be updated to compile correctly with LibCommon changes)
This commit is contained in:
parent
f92b36a8ab
commit
dacd21d7fc
|
@ -13,3 +13,6 @@
|
|||
[submodule "externals/CodeGen"]
|
||||
path = externals/CodeGen
|
||||
url = https://github.com/arukibree/CodeGen
|
||||
[submodule "externals/LibCommon"]
|
||||
path = externals/LibCommon
|
||||
url = https://github.com/arukibree/LibCommon
|
||||
|
|
|
@ -0,0 +1 @@
|
|||
Subproject commit 252e4c7e96099c0f684b96d57eb9d947278d565b
|
|
@ -15,7 +15,7 @@ EXTERNALS_DIR = $$PWD/../externals
|
|||
PWE_MAIN_INCLUDE = $$PWD
|
||||
|
||||
DEFINES += 'APP_NAME=\"\\\"Prime World Editor\\\"\"' \
|
||||
'APP_VERSION=\"\\\"1.2.0\\\"\"'
|
||||
'APP_VERSION=\"\\\"1.2.1\\\"\"'
|
||||
|
||||
PUBLIC_RELEASE {
|
||||
DEFINES += 'PUBLIC_RELEASE=1' \
|
||||
|
|
|
@ -1,53 +0,0 @@
|
|||
#ifndef ASSERT_H
|
||||
#define ASSERT_H
|
||||
|
||||
#include "Log.h"
|
||||
#include "TString.h"
|
||||
#include <cstdlib>
|
||||
#include <string.h>
|
||||
|
||||
/* This header declares a macro, ASSERT(Expression). ASSERT evaluates the input expression and verifies that
|
||||
* it is true. If the expression is false, an error message will be printed to the log with info on what went
|
||||
* wrong and (in debug builds) trigger a debug break. Application execution is aborted. In public release builds,
|
||||
* asserts are compiled out entirely, so neither log messages nor debug breaks will occur.
|
||||
*
|
||||
* Alternatively, this file also declares an ENSURE macro, which is guaranteed always executes and will never be
|
||||
* compiled out, regardless of build configuration.
|
||||
*/
|
||||
#define __FILE_SHORT__ strrchr(__FILE__, '\\') ? strrchr(__FILE__, '\\') + 1 : __FILE__
|
||||
|
||||
#if _DEBUG
|
||||
#define DEBUG_BREAK __debugbreak();
|
||||
#define CONDITIONAL_BREAK(Condition) if (##Condition) DEBUG_BREAK
|
||||
#else
|
||||
#define DEBUG_BREAK {}
|
||||
#define CONDITIONAL_BREAK(Condition) {}
|
||||
#endif
|
||||
|
||||
#define ASSERT_CHECK_BEGIN(Expression) \
|
||||
{ \
|
||||
if (!(Expression)) \
|
||||
{
|
||||
|
||||
#define ASSERT_CHECK_END \
|
||||
} \
|
||||
}
|
||||
|
||||
#define WRITE_FAILURE_TO_LOG(Expression) \
|
||||
Log::Write(TString(__FILE_SHORT__) + "(" + TString::FromInt32(__LINE__, 0, 10) + "): ASSERT FAILED: " + #Expression);
|
||||
|
||||
// ENSURE macro always executes, never gets compiled out
|
||||
#define ENSURE(Expression) \
|
||||
ASSERT_CHECK_BEGIN(Expression) \
|
||||
WRITE_FAILURE_TO_LOG(Expression) \
|
||||
DEBUG_BREAK \
|
||||
abort(); \
|
||||
ASSERT_CHECK_END
|
||||
|
||||
#if !PUBLIC_RELEASE
|
||||
#define ASSERT(Expression) ENSURE(Expression)
|
||||
#else
|
||||
#define ASSERT(Expression) {}
|
||||
#endif
|
||||
|
||||
#endif // ASSERT_H
|
|
@ -1,99 +0,0 @@
|
|||
#include "CAssetID.h"
|
||||
#include "TString.h"
|
||||
#include <random>
|
||||
|
||||
CAssetID::CAssetID()
|
||||
: mLength(eInvalidIDLength)
|
||||
, mID(0xFFFFFFFFFFFFFFFF)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
CAssetID::CAssetID(u64 ID)
|
||||
: mID(ID)
|
||||
{
|
||||
// This constructor is intended to be used with both 32-bit and 64-bit input values
|
||||
// 64-bit - check for valid content in upper 32 bits (at least one bit set + one bit unset)
|
||||
if ((ID & 0xFFFFFFFF00000000) && (~ID & 0xFFFFFFFF00000000))
|
||||
mLength = e64Bit;
|
||||
|
||||
// 32-bit
|
||||
else
|
||||
{
|
||||
mLength = e32Bit;
|
||||
mID &= 0xFFFFFFFF;
|
||||
}
|
||||
}
|
||||
|
||||
CAssetID::CAssetID(u64 ID, EIDLength Length)
|
||||
: mID(ID)
|
||||
, mLength(Length)
|
||||
{
|
||||
if (Length == e32Bit)
|
||||
mID &= 0xFFFFFFFF;
|
||||
}
|
||||
|
||||
void CAssetID::Write(IOutputStream& rOutput, EIDLength ForcedLength /*= eInvalidIDLength*/) const
|
||||
{
|
||||
EIDLength Length = (ForcedLength == eInvalidIDLength ? mLength : ForcedLength);
|
||||
|
||||
if (Length == e32Bit)
|
||||
rOutput.WriteLong(ToLong());
|
||||
else
|
||||
rOutput.WriteLongLong(ToLongLong());
|
||||
}
|
||||
|
||||
CAssetID::CAssetID(IInputStream& rInput, EIDLength Length)
|
||||
: mLength(Length)
|
||||
{
|
||||
if (Length == e32Bit) mID = ((u64) rInput.ReadLong()) & 0xFFFFFFFF;
|
||||
else mID = rInput.ReadLongLong();
|
||||
}
|
||||
|
||||
CAssetID::CAssetID(IInputStream& rInput, EGame Game)
|
||||
{
|
||||
*this = CAssetID(rInput, (Game <= EGame::Echoes ? e32Bit : e64Bit));
|
||||
}
|
||||
|
||||
TString CAssetID::ToString(EIDLength ForcedLength /*= eInvalidIDLength*/) const
|
||||
{
|
||||
EIDLength Length = (ForcedLength == eInvalidIDLength ? mLength : ForcedLength);
|
||||
|
||||
if (Length == e32Bit)
|
||||
return TString::HexString(ToLong(), 8, false, true);
|
||||
else
|
||||
return TString::FromInt64(ToLongLong(), 16, 16).ToUpper();
|
||||
}
|
||||
|
||||
bool CAssetID::IsValid() const
|
||||
{
|
||||
return (mID != 0 && mLength != eInvalidIDLength && mID != InvalidID(mLength).mID);
|
||||
}
|
||||
|
||||
// ************ STATIC ************
|
||||
CAssetID CAssetID::FromString(const TString& rkString)
|
||||
{
|
||||
// If the input is a hex ID in string form, then preserve it... otherwise, generate an ID by hashing the string
|
||||
TString Name = rkString.GetFileName(false);
|
||||
u32 NameLength = Name.Length();
|
||||
|
||||
if (Name.IsHexString())
|
||||
{
|
||||
if (NameLength == 8) return CAssetID(Name.ToInt32());
|
||||
if (NameLength == 16) return CAssetID(Name.ToInt64());
|
||||
}
|
||||
|
||||
return CAssetID(rkString.Hash64());
|
||||
}
|
||||
|
||||
CAssetID CAssetID::RandomID()
|
||||
{
|
||||
CAssetID ID;
|
||||
ID.mLength = e64Bit;
|
||||
ID.mID = (u64(rand()) << 32) | rand();
|
||||
return ID;
|
||||
}
|
||||
|
||||
// ************ STATIC MEMBER INITIALIZATION ************
|
||||
CAssetID CAssetID::skInvalidID32 = CAssetID((u64) -1, e32Bit);
|
||||
CAssetID CAssetID::skInvalidID64 = CAssetID((u64) -1, e64Bit);
|
|
@ -1,60 +0,0 @@
|
|||
#ifndef CASSETID_H
|
||||
#define CASSETID_H
|
||||
|
||||
#include "EGame.h"
|
||||
#include "FileIO.h"
|
||||
#include "TString.h"
|
||||
#include "types.h"
|
||||
|
||||
enum EIDLength
|
||||
{
|
||||
e32Bit = 4,
|
||||
e64Bit = 8,
|
||||
eInvalidIDLength = 0
|
||||
};
|
||||
|
||||
class CAssetID
|
||||
{
|
||||
EIDLength mLength;
|
||||
u64 mID;
|
||||
|
||||
public:
|
||||
CAssetID();
|
||||
CAssetID(u64 ID);
|
||||
CAssetID(u64 ID, EIDLength Length);
|
||||
CAssetID(IInputStream& rInput, EIDLength Length);
|
||||
CAssetID(IInputStream& rInput, EGame Game);
|
||||
void Write(IOutputStream& rOutput, EIDLength ForcedLength = eInvalidIDLength) const;
|
||||
TString ToString(EIDLength ForcedLength = eInvalidIDLength) const;
|
||||
bool IsValid() const;
|
||||
|
||||
// Operators
|
||||
inline void operator= (const u64& rkInput) { *this = CAssetID(rkInput); }
|
||||
inline bool operator==(const CAssetID& rkOther) const { return mLength == rkOther.mLength && mID == rkOther.mID; }
|
||||
inline bool operator!=(const CAssetID& rkOther) const { return mLength != rkOther.mLength || mID != rkOther.mID; }
|
||||
inline bool operator> (const CAssetID& rkOther) const { return mLength >= rkOther.mLength && mID > rkOther.mID; }
|
||||
inline bool operator>=(const CAssetID& rkOther) const { return mLength >= rkOther.mLength && mID >= rkOther.mID; }
|
||||
inline bool operator< (const CAssetID& rkOther) const { return mLength < rkOther.mLength || mID < rkOther.mID; }
|
||||
inline bool operator<=(const CAssetID& rkOther) const { return mLength < rkOther.mLength || mID <= rkOther.mID; }
|
||||
inline bool operator==(u64 Other) const { return mID == Other; }
|
||||
inline bool operator!=(u64 Other) const { return mID != Other; }
|
||||
|
||||
// Accessors
|
||||
inline u32 ToLong() const { return (u32) mID; }
|
||||
inline u64 ToLongLong() const { return mID; }
|
||||
inline EIDLength Length() const { return mLength; }
|
||||
inline void SetLength(EIDLength Length) { mLength = Length; }
|
||||
|
||||
// Static
|
||||
static CAssetID FromString(const TString& rkString);
|
||||
static CAssetID RandomID();
|
||||
|
||||
inline static EIDLength GameIDLength(EGame Game) { return (Game == EGame::Invalid ? eInvalidIDLength : (Game <= EGame::Echoes ? e32Bit : e64Bit)); }
|
||||
inline static CAssetID InvalidID(EIDLength IDLength) { return (IDLength == e32Bit ? skInvalidID32 : skInvalidID64); }
|
||||
inline static CAssetID InvalidID(EGame Game) { return InvalidID(Game <= EGame::Echoes ? e32Bit : e64Bit); }
|
||||
|
||||
static CAssetID skInvalidID32;
|
||||
static CAssetID skInvalidID64;
|
||||
};
|
||||
|
||||
#endif // CASSETID_H
|
|
@ -1,235 +0,0 @@
|
|||
#include "CColor.h"
|
||||
|
||||
CColor::CColor()
|
||||
: R(0.f), G(0.f), B(0.f), A(0.f)
|
||||
{
|
||||
}
|
||||
|
||||
CColor::CColor(IInputStream& rInput, bool Integral /*= false*/)
|
||||
{
|
||||
if (Integral)
|
||||
{
|
||||
R = (u8) rInput.ReadByte() / 255.f;
|
||||
G = (u8) rInput.ReadByte() / 255.f;
|
||||
B = (u8) rInput.ReadByte() / 255.f;
|
||||
A = (u8) rInput.ReadByte() / 255.f;
|
||||
}
|
||||
else
|
||||
{
|
||||
R = rInput.ReadFloat();
|
||||
G = rInput.ReadFloat();
|
||||
B = rInput.ReadFloat();
|
||||
A = rInput.ReadFloat();
|
||||
}
|
||||
}
|
||||
|
||||
CColor::CColor(float RGBA)
|
||||
: R(RGBA), G(RGBA), B(RGBA), A(RGBA)
|
||||
{
|
||||
}
|
||||
|
||||
CColor::CColor(float _R, float _G, float _B, float _A /*= 1.f*/)
|
||||
: R(_R), G(_G), B(_B), A(_A)
|
||||
{
|
||||
}
|
||||
|
||||
void CColor::SetIntegral(u8 RGBA)
|
||||
{
|
||||
float f = RGBA / 255.f;
|
||||
R = G = B = A = f;
|
||||
}
|
||||
|
||||
void CColor::SetIntegral(u8 _R, u8 _G, u8 _B, u8 _A /*= 255*/)
|
||||
{
|
||||
R = _R / 255.f;
|
||||
G = _G / 255.f;
|
||||
B = _B / 255.f;
|
||||
A = _A / 255.f;
|
||||
}
|
||||
|
||||
void CColor::Write(IOutputStream &rOutput, bool Integral /*= false*/) const
|
||||
{
|
||||
if (Integral)
|
||||
{
|
||||
rOutput.WriteLong(ToLongRGBA());
|
||||
}
|
||||
|
||||
else
|
||||
{
|
||||
rOutput.WriteFloat(R);
|
||||
rOutput.WriteFloat(G);
|
||||
rOutput.WriteFloat(B);
|
||||
rOutput.WriteFloat(A);
|
||||
}
|
||||
}
|
||||
|
||||
void CColor::Serialize(IArchive& rArc)
|
||||
{
|
||||
rArc << SerialParameter("R", R)
|
||||
<< SerialParameter("G", G)
|
||||
<< SerialParameter("B", B)
|
||||
<< SerialParameter("A", A, SH_Optional, 1.0f);
|
||||
}
|
||||
|
||||
long CColor::ToLongRGBA() const
|
||||
{
|
||||
u8 _R = (u8) (R * 255);
|
||||
u8 _G = (u8) (G * 255);
|
||||
u8 _B = (u8) (B * 255);
|
||||
u8 _A = (u8) (A * 255);
|
||||
return (_R << 24) | (_G << 16) | (_B << 8) | _A;
|
||||
}
|
||||
|
||||
long CColor::ToLongARGB() const
|
||||
{
|
||||
u8 _R = (u8) (R * 255);
|
||||
u8 _G = (u8) (G * 255);
|
||||
u8 _B = (u8) (B * 255);
|
||||
u8 _A = (u8) (A * 255);
|
||||
return (_A << 24) | (_R << 16) | (_G << 8) | _B;
|
||||
}
|
||||
|
||||
bool CColor::operator==(const CColor& rkOther) const
|
||||
{
|
||||
return ((R == rkOther.R) &&
|
||||
(G == rkOther.G) &&
|
||||
(B == rkOther.B) &&
|
||||
(A == rkOther.A));
|
||||
}
|
||||
|
||||
bool CColor::operator!=(const CColor& rkOther) const
|
||||
{
|
||||
return (!(*this == rkOther));
|
||||
}
|
||||
|
||||
CColor CColor::operator+(const CColor& rkOther) const
|
||||
{
|
||||
float NewR = fmin(R + rkOther.R, 1.f);
|
||||
float NewG = fmin(G + rkOther.G, 1.f);
|
||||
float NewB = fmin(B + rkOther.B, 1.f);
|
||||
float NewA = fmin(A + rkOther.A, 1.f);
|
||||
return CColor(NewR, NewG, NewB, NewA);
|
||||
}
|
||||
|
||||
void CColor::operator+=(const CColor& rkOther)
|
||||
{
|
||||
*this = (*this + rkOther);
|
||||
}
|
||||
|
||||
CColor CColor::operator-(const CColor& rkOther) const
|
||||
{
|
||||
float NewR = fmax(R - rkOther.R, 0.f);
|
||||
float NewG = fmax(G - rkOther.G, 0.f);
|
||||
float NewB = fmax(B - rkOther.B, 0.f);
|
||||
float NewA = fmax(A - rkOther.A, 0.f);
|
||||
return CColor(NewR, NewG, NewB, NewA);
|
||||
}
|
||||
|
||||
void CColor::operator-=(const CColor& other)
|
||||
{
|
||||
*this = (*this - other);
|
||||
}
|
||||
|
||||
CColor CColor::operator*(const CColor& rkOther) const
|
||||
{
|
||||
float NewR = R * rkOther.R;
|
||||
float NewG = G * rkOther.G;
|
||||
float NewB = B * rkOther.B;
|
||||
float NewA = A * rkOther.A;
|
||||
return CColor(NewR, NewG, NewB, NewA);
|
||||
}
|
||||
|
||||
void CColor::operator*=(const CColor& rkOther)
|
||||
{
|
||||
*this = (*this * rkOther);
|
||||
}
|
||||
|
||||
CColor CColor::operator*(float Other) const
|
||||
{
|
||||
float NewR = fmin( fmax(R * Other, 0.f), 1.f);
|
||||
float NewG = fmin( fmax(G * Other, 0.f), 1.f);
|
||||
float NewB = fmin( fmax(B * Other, 0.f), 1.f);
|
||||
float NewA = fmin( fmax(A * Other, 0.f), 1.f);
|
||||
return CColor(NewR, NewG, NewB, NewA);
|
||||
}
|
||||
|
||||
void CColor::operator*=(float Other)
|
||||
{
|
||||
*this = (*this * Other);
|
||||
}
|
||||
|
||||
CColor CColor::operator/(const CColor& rkOther) const
|
||||
{
|
||||
float NewR = (rkOther.R == 0.f) ? 0.f : R / rkOther.R;
|
||||
float NewG = (rkOther.G == 0.f) ? 0.f : G / rkOther.G;
|
||||
float NewB = (rkOther.B == 0.f) ? 0.f : B / rkOther.B;
|
||||
float NewA = (rkOther.A == 0.f) ? 0.f : A / rkOther.A;
|
||||
return CColor(NewR, NewG, NewB, NewA);
|
||||
}
|
||||
|
||||
void CColor::operator/=(const CColor& rkOther)
|
||||
{
|
||||
*this = (*this / rkOther);
|
||||
}
|
||||
|
||||
// ************ STATIC ************
|
||||
CColor CColor::Integral(u8 RGBA)
|
||||
{
|
||||
CColor Out;
|
||||
Out.SetIntegral(RGBA);
|
||||
return Out;
|
||||
}
|
||||
|
||||
CColor CColor::Integral(u8 _R, u8 _G, u8 _B, u8 _A /*= 255*/)
|
||||
{
|
||||
CColor Out;
|
||||
Out.SetIntegral(_R, _G, _B, _A);
|
||||
return Out;
|
||||
}
|
||||
|
||||
CColor CColor::RandomColor(bool Transparent)
|
||||
{
|
||||
float _R = (rand() % 255) / 255.f;
|
||||
float _G = (rand() % 255) / 255.f;
|
||||
float _B = (rand() % 255) / 255.f;
|
||||
float _A = (Transparent ? (rand() % 255) / 255.f : 0);
|
||||
return CColor(_R, _G, _B, _A);
|
||||
}
|
||||
|
||||
CColor CColor::RandomLightColor(bool Transparent)
|
||||
{
|
||||
float _R = 0.5f + (rand() % 128) / 255.f;
|
||||
float _G = 0.5f + (rand() % 128) / 255.f;
|
||||
float _B = 0.5f + (rand() % 128) / 255.f;
|
||||
float _A = (Transparent ? 0.5f + ((rand() % 128) / 255.f) : 0);
|
||||
return CColor(_R, _G, _B, _A);
|
||||
}
|
||||
|
||||
CColor CColor::RandomDarkColor(bool Transparent)
|
||||
{
|
||||
float _R = (rand() % 128) / 255.f;
|
||||
float _G = (rand() % 128) / 255.f;
|
||||
float _B = (rand() % 128) / 255.f;
|
||||
float _A = (Transparent ? (rand() % 128) / 255.f : 0);
|
||||
return CColor(_R, _G, _B, _A);
|
||||
}
|
||||
|
||||
// defining predefined colors
|
||||
const CColor CColor::skRed (1.0f, 0.0f, 0.0f);
|
||||
const CColor CColor::skGreen (0.0f, 1.0f, 0.0f);
|
||||
const CColor CColor::skBlue (0.0f, 0.0f, 1.0f);
|
||||
const CColor CColor::skYellow(1.0f, 1.0f, 0.0f);
|
||||
const CColor CColor::skPurple(1.0f, 0.0f, 1.0f);
|
||||
const CColor CColor::skCyan (0.0f, 1.0f, 1.0f);
|
||||
const CColor CColor::skWhite (1.0f, 1.0f, 1.0f);
|
||||
const CColor CColor::skBlack (0.0f, 0.0f, 0.0f);
|
||||
const CColor CColor::skGray (0.5f, 0.5f, 0.5f);
|
||||
const CColor CColor::skTransparentRed (1.0f, 0.0f, 0.0f, 0.0f);
|
||||
const CColor CColor::skTransparentGreen (0.0f, 1.0f, 0.0f, 0.0f);
|
||||
const CColor CColor::skTransparentBlue (0.0f, 0.0f, 1.0f, 0.0f);
|
||||
const CColor CColor::skTransparentYellow(1.0f, 1.0f, 0.0f, 0.0f);
|
||||
const CColor CColor::skTransparentPurple(1.0f, 0.0f, 1.0f, 0.0f);
|
||||
const CColor CColor::skTransparentCyan (0.0f, 1.0f, 1.0f, 0.0f);
|
||||
const CColor CColor::skTransparentWhite (1.0f, 1.0f, 1.0f, 0.0f);
|
||||
const CColor CColor::skTransparentBlack (0.0f, 0.0f, 0.0f, 0.0f);
|
||||
const CColor CColor::skTransparentGray (0.5f, 0.5f, 0.5f, 0.0f);
|
|
@ -1,66 +0,0 @@
|
|||
#ifndef CCOLOR_H
|
||||
#define CCOLOR_H
|
||||
|
||||
#include "Common/FileIO/IInputStream.h"
|
||||
#include "Common/FileIO/IOutputStream.h"
|
||||
#include "Common/Serialization/IArchive.h"
|
||||
#include "types.h"
|
||||
|
||||
class CColor
|
||||
{
|
||||
public:
|
||||
float R, G, B, A;
|
||||
|
||||
CColor();
|
||||
CColor(IInputStream& rInput, bool Integral = false);
|
||||
CColor(float RGBA);
|
||||
CColor(float _R, float _G, float _B, float A = 1.f);
|
||||
void SetIntegral(u8 RGBA);
|
||||
void SetIntegral(u8 _R, u8 _G, u8 _B, u8 _A = 255);
|
||||
void Write(IOutputStream& rOutput, bool Integral = false) const;
|
||||
void Serialize(IArchive& rArc);
|
||||
|
||||
long ToLongRGBA() const;
|
||||
long ToLongARGB() const;
|
||||
bool operator==(const CColor& rkOther) const;
|
||||
bool operator!=(const CColor& rkOther) const;
|
||||
CColor operator+(const CColor& rkOther) const;
|
||||
void operator+=(const CColor& rkOther);
|
||||
CColor operator-(const CColor& rkOther) const;
|
||||
void operator-=(const CColor& rkOther);
|
||||
CColor operator*(const CColor& rkOther) const;
|
||||
void operator*=(const CColor& rkOther);
|
||||
CColor operator*(float Other) const;
|
||||
void operator*=(float Other);
|
||||
CColor operator/(const CColor& rkOther) const;
|
||||
void operator/=(const CColor& rkOther);
|
||||
|
||||
// Static
|
||||
static CColor Integral(u8 RGBA);
|
||||
static CColor Integral(u8 _R, u8 _G, u8 _B, u8 _A = 255);
|
||||
static CColor RandomColor(bool Transparent);
|
||||
static CColor RandomLightColor(bool Transparent);
|
||||
static CColor RandomDarkColor(bool Transparent);
|
||||
|
||||
// some predefined colors below for ease of use
|
||||
static const CColor skRed;
|
||||
static const CColor skGreen;
|
||||
static const CColor skBlue;
|
||||
static const CColor skYellow;
|
||||
static const CColor skPurple;
|
||||
static const CColor skCyan;
|
||||
static const CColor skWhite;
|
||||
static const CColor skBlack;
|
||||
static const CColor skGray;
|
||||
static const CColor skTransparentRed;
|
||||
static const CColor skTransparentGreen;
|
||||
static const CColor skTransparentBlue;
|
||||
static const CColor skTransparentYellow;
|
||||
static const CColor skTransparentPurple;
|
||||
static const CColor skTransparentCyan;
|
||||
static const CColor skTransparentWhite;
|
||||
static const CColor skTransparentBlack;
|
||||
static const CColor skTransparentGray;
|
||||
};
|
||||
|
||||
#endif // CCOLOR_H
|
|
@ -1,128 +0,0 @@
|
|||
#ifndef CFOURCC_H
|
||||
#define CFOURCC_H
|
||||
|
||||
#include "AssertMacro.h"
|
||||
#include "FileIO.h"
|
||||
#include "types.h"
|
||||
#include "TString.h"
|
||||
|
||||
#define FOURCC_FROM_TEXT(Text) (Text[0] << 24 | Text[1] << 16 | Text[2] << 8 | Text[3])
|
||||
|
||||
// Note: All FourCC constants should be wrapped in this macro
|
||||
#define FOURCC(Value) Value
|
||||
|
||||
class CFourCC
|
||||
{
|
||||
// Note: mFourCC_Chars isn't used much due to endianness.
|
||||
union
|
||||
{
|
||||
u32 mFourCC;
|
||||
char mFourCC_Chars[4];
|
||||
};
|
||||
|
||||
public:
|
||||
// Constructors
|
||||
inline CFourCC() { mFourCC = 0; }
|
||||
inline CFourCC(const char *pkSrc) { mFourCC = FOURCC_FROM_TEXT(pkSrc); }
|
||||
inline CFourCC(const TString& rkSrc) { ASSERT(rkSrc.Length() == 4); mFourCC = FOURCC_FROM_TEXT(rkSrc); }
|
||||
inline CFourCC(const TWideString& rkSrc){ ASSERT(rkSrc.Length() == 4); mFourCC = FOURCC_FROM_TEXT(rkSrc); }
|
||||
inline CFourCC(u32 Src) { mFourCC = Src; }
|
||||
inline CFourCC(IInputStream& rSrc) { Read(rSrc); }
|
||||
|
||||
// Functionality
|
||||
inline void Read(IInputStream& rInput)
|
||||
{
|
||||
mFourCC = rInput.ReadLong();
|
||||
if (rInput.GetEndianness() == IOUtil::eLittleEndian) Reverse();
|
||||
}
|
||||
|
||||
inline void Write(IOutputStream& rOutput) const
|
||||
{
|
||||
u32 Val = mFourCC;
|
||||
if (rOutput.GetEndianness() == IOUtil::eLittleEndian) IOUtil::SwapBytes(Val);
|
||||
rOutput.WriteLong(Val);
|
||||
}
|
||||
|
||||
inline u32 ToLong() const
|
||||
{
|
||||
return mFourCC;
|
||||
}
|
||||
|
||||
inline TString ToString() const
|
||||
{
|
||||
char CharArray[4] = {
|
||||
(char) ((mFourCC >> 24) & 0xFF),
|
||||
(char) ((mFourCC >> 16) & 0xFF),
|
||||
(char) ((mFourCC >> 8) & 0xFF),
|
||||
(char) ((mFourCC >> 0) & 0xFF)
|
||||
};
|
||||
|
||||
return TString(CharArray, 4);
|
||||
}
|
||||
|
||||
inline CFourCC ToUpper() const
|
||||
{
|
||||
CFourCC Out;
|
||||
|
||||
for (int iChr = 0; iChr < 4; iChr++)
|
||||
Out.mFourCC_Chars[iChr] = TString::CharToUpper(mFourCC_Chars[iChr]);
|
||||
|
||||
return CFourCC(Out);
|
||||
}
|
||||
|
||||
inline void Reverse() const
|
||||
{
|
||||
IOUtil::SwapBytes((u32&) mFourCC);
|
||||
}
|
||||
|
||||
// Operators
|
||||
inline char& operator[](int Index)
|
||||
{
|
||||
ASSERT(Index >= 0 && Index < 4);
|
||||
if (IOUtil::kSystemEndianness == IOUtil::eLittleEndian)
|
||||
Index = 3 - Index;
|
||||
|
||||
return ((char*)(&mFourCC))[Index];
|
||||
}
|
||||
|
||||
inline const char& operator[](int Index) const
|
||||
{
|
||||
ASSERT(Index >= 0 && Index < 4);
|
||||
if (IOUtil::kSystemEndianness == IOUtil::eLittleEndian)
|
||||
Index = 3 - Index;
|
||||
|
||||
return ((char*)(&mFourCC))[Index];
|
||||
}
|
||||
|
||||
inline TString operator+(const char *pkText) const
|
||||
{
|
||||
return ToString() + pkText;
|
||||
}
|
||||
|
||||
inline TString operator+(const TString& rkStr) const
|
||||
{
|
||||
return ToString() + rkStr;
|
||||
}
|
||||
|
||||
inline friend TString operator+(const char *pkText, const CFourCC& rkFourCC)
|
||||
{
|
||||
return pkText + rkFourCC.ToString();
|
||||
}
|
||||
|
||||
inline friend TString operator+(const TString& rkStr, const CFourCC& rkFourCC)
|
||||
{
|
||||
return rkStr + rkFourCC.ToString();
|
||||
}
|
||||
|
||||
inline CFourCC& operator=(const char *pkSrc) { mFourCC = FOURCC_FROM_TEXT(pkSrc); return *this; }
|
||||
inline CFourCC& operator=(const TString& rkSrc) { mFourCC = FOURCC_FROM_TEXT(rkSrc); return *this; }
|
||||
inline CFourCC& operator=(u32 Src) { mFourCC = Src; return *this; }
|
||||
inline bool operator==(const CFourCC& rkOther) const { return mFourCC == rkOther.mFourCC; }
|
||||
inline bool operator!=(const CFourCC& rkOther) const { return mFourCC != rkOther.mFourCC; }
|
||||
inline bool operator> (const CFourCC& rkOther) const { return mFourCC > rkOther.mFourCC; }
|
||||
inline bool operator>=(const CFourCC& rkOther) const { return mFourCC >= rkOther.mFourCC; }
|
||||
inline bool operator< (const CFourCC& rkOther) const { return mFourCC < rkOther.mFourCC; }
|
||||
inline bool operator<=(const CFourCC& rkOther) const { return mFourCC <= rkOther.mFourCC; }
|
||||
};
|
||||
|
||||
#endif // CFOURCC_H
|
|
@ -1,43 +0,0 @@
|
|||
#ifndef CSCOPEDTIMER
|
||||
#define CSCOPEDTIMER
|
||||
|
||||
#include "CTimer.h"
|
||||
#include "Log.h"
|
||||
#include "TString.h"
|
||||
|
||||
// Runs a timer and automatically stops + prints the time to the log when it goes out of scope.
|
||||
class CScopedTimer
|
||||
{
|
||||
CTimer mTimer;
|
||||
TString mTimerName;
|
||||
bool mStopped;
|
||||
|
||||
public:
|
||||
CScopedTimer(const TString& rkTimeoutMessage)
|
||||
: mTimerName(rkTimeoutMessage)
|
||||
, mStopped(false)
|
||||
{
|
||||
mTimer.Start();
|
||||
}
|
||||
|
||||
~CScopedTimer()
|
||||
{
|
||||
Stop();
|
||||
}
|
||||
|
||||
void Stop()
|
||||
{
|
||||
if (!mStopped)
|
||||
{
|
||||
Log::Write(mTimerName + " finished in " + TString::FromFloat((float) mTimer.Stop()) + "s");
|
||||
mStopped = true;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
#define SCOPED_TIMER(TimerName) \
|
||||
CScopedTimer TimerName(#TimerName); \
|
||||
(void) TimerName; // This avoids "unused local variable" compiler warnings
|
||||
|
||||
#endif // CSCOPEDTIMER
|
||||
|
|
@ -1,96 +0,0 @@
|
|||
#include "CTimer.h"
|
||||
#include <cmath>
|
||||
#include <ctime>
|
||||
|
||||
CTimer::CTimer()
|
||||
: mStartTime(0)
|
||||
, mStopTime(0)
|
||||
, mStarted(false)
|
||||
, mPaused(false)
|
||||
{
|
||||
}
|
||||
|
||||
void CTimer::Start()
|
||||
{
|
||||
if (!mStarted)
|
||||
{
|
||||
mStartTime = GlobalTime();
|
||||
mStarted = true;
|
||||
mPaused = false;
|
||||
mPauseStartTime = 0;
|
||||
mTotalPauseTime = 0;
|
||||
mStopTime = 0;
|
||||
}
|
||||
}
|
||||
|
||||
void CTimer::Start(double StartTime)
|
||||
{
|
||||
if (!mStarted)
|
||||
{
|
||||
mStartTime = GlobalTime() - StartTime;
|
||||
mStarted = true;
|
||||
mPaused = false;
|
||||
mPauseStartTime = 0;
|
||||
mTotalPauseTime = 0;
|
||||
mStopTime = 0;
|
||||
}
|
||||
}
|
||||
|
||||
void CTimer::Restart()
|
||||
{
|
||||
mStarted = false;
|
||||
Start();
|
||||
}
|
||||
|
||||
double CTimer::Stop()
|
||||
{
|
||||
mStopTime = Time();
|
||||
mStarted = false;
|
||||
mPaused = false;
|
||||
return mStopTime;
|
||||
}
|
||||
|
||||
double CTimer::Pause()
|
||||
{
|
||||
mPauseStartTime = GlobalTime();
|
||||
mPaused = true;
|
||||
return Time();
|
||||
}
|
||||
|
||||
bool CTimer::IsPaused()
|
||||
{
|
||||
return mPaused;
|
||||
}
|
||||
|
||||
void CTimer::Resume()
|
||||
{
|
||||
if (mPaused)
|
||||
{
|
||||
mTotalPauseTime += GlobalTime() - mPauseStartTime;
|
||||
mPaused = false;
|
||||
}
|
||||
}
|
||||
|
||||
double CTimer::Time()
|
||||
{
|
||||
if (mStarted)
|
||||
{
|
||||
double CurrentPauseTime = 0;
|
||||
if (mPaused) CurrentPauseTime = GlobalTime() - mPauseStartTime;
|
||||
return GlobalTime() - mStartTime - mTotalPauseTime - CurrentPauseTime;
|
||||
}
|
||||
|
||||
else
|
||||
return mStopTime;
|
||||
}
|
||||
|
||||
// ************ STATIC ************
|
||||
double CTimer::GlobalTime()
|
||||
{
|
||||
return (double) clock() / CLOCKS_PER_SEC;
|
||||
}
|
||||
|
||||
float CTimer::SecondsMod900()
|
||||
{
|
||||
return fmodf((float) GlobalTime(), 900.f);
|
||||
}
|
|
@ -1,29 +0,0 @@
|
|||
#ifndef CTIMER_H
|
||||
#define CTIMER_H
|
||||
|
||||
class CTimer
|
||||
{
|
||||
double mStartTime;
|
||||
double mPauseStartTime;
|
||||
double mTotalPauseTime;
|
||||
double mStopTime;
|
||||
bool mStarted;
|
||||
bool mPaused;
|
||||
|
||||
public:
|
||||
CTimer();
|
||||
void Start();
|
||||
void Start(double StartTime);
|
||||
void Restart();
|
||||
double Stop();
|
||||
double Pause();
|
||||
bool IsPaused();
|
||||
void Resume();
|
||||
double Time();
|
||||
|
||||
// Static
|
||||
static double GlobalTime();
|
||||
static float SecondsMod900();
|
||||
};
|
||||
|
||||
#endif // CTIMER_H
|
|
@ -1,31 +0,0 @@
|
|||
#ifndef COMMON_H
|
||||
#define COMMON_H
|
||||
|
||||
#include "types.h"
|
||||
#include "AssertMacro.h"
|
||||
#include "CAssetID.h"
|
||||
#include "CColor.h"
|
||||
#include "CFourCC.h"
|
||||
#include "CScopedTimer.h"
|
||||
#include "CTimer.h"
|
||||
#include "EGame.h"
|
||||
#include "EKeyInputs.h"
|
||||
#include "EMouseInputs.h"
|
||||
#include "FileIO.h"
|
||||
#include "FileUtil.h"
|
||||
#include "Flags.h"
|
||||
#include "Log.h"
|
||||
#include "TString.h"
|
||||
#include "Hash/CCRC32.h"
|
||||
#include "Hash/CFNV1A.h"
|
||||
#include "Serialization/Binary.h"
|
||||
#include "Serialization/XML.h"
|
||||
#include "NBasics.h"
|
||||
|
||||
// temporary home for ALIGN macro, moving later
|
||||
#define ALIGN(Val, Align) ((Val + (Align-1)) & ~(Align-1))
|
||||
|
||||
// temporary home for MEMBER_OFFSET macro
|
||||
#define MEMBER_OFFSET(TypeName, MemberName) ( (int) (long long) &((TypeName*)0)->MemberName )
|
||||
|
||||
#endif // COMMON_H
|
|
@ -1,111 +0,0 @@
|
|||
#-------------------------------------------------
|
||||
#
|
||||
# Project created by QtCreator 2015-12-13T15:27:18
|
||||
#
|
||||
#-------------------------------------------------
|
||||
|
||||
QT -= core gui
|
||||
DEFINES += PWE_COMMON
|
||||
|
||||
CONFIG += staticlib
|
||||
TEMPLATE = lib
|
||||
DESTDIR = $$BUILD_DIR/Common
|
||||
|
||||
unix {
|
||||
target.path = /usr/lib
|
||||
QMAKE_CXXFLAGS += /WX
|
||||
INSTALLS += target
|
||||
}
|
||||
|
||||
CONFIG (debug, debug|release) {
|
||||
# Debug Config
|
||||
OBJECTS_DIR = $$BUILD_DIR/Common/debug
|
||||
TARGET = Commond
|
||||
}
|
||||
|
||||
CONFIG (release, debug|release) {
|
||||
# Release Config
|
||||
OBJECTS_DIR = $$BUILD_DIR/build/Common/release
|
||||
TARGET = Common
|
||||
}
|
||||
|
||||
# Include Paths
|
||||
INCLUDEPATH += $$PWE_MAIN_INCLUDE \
|
||||
$$EXTERNALS_DIR/CodeGen/include \
|
||||
$$EXTERNALS_DIR/tinyxml2
|
||||
|
||||
# Header Files
|
||||
HEADERS += \
|
||||
CColor.h \
|
||||
CFourCC.h \
|
||||
CTimer.h \
|
||||
EKeyInputs.h \
|
||||
EMouseInputs.h \
|
||||
Flags.h \
|
||||
TString.h \
|
||||
types.h \
|
||||
Log.h \
|
||||
FileUtil.h \
|
||||
AssertMacro.h \
|
||||
CScopedTimer.h \
|
||||
CAssetID.h \
|
||||
Hash\CFNV1A.h \
|
||||
Serialization/IArchive.h \
|
||||
Serialization/CXMLWriter.h \
|
||||
Serialization/CXMLReader.h \
|
||||
EGame.h \
|
||||
Serialization/CBasicBinaryWriter.h \
|
||||
Serialization/CBasicBinaryReader.h \
|
||||
Serialization/CBinaryWriter.h \
|
||||
Serialization/CBinaryReader.h \
|
||||
Serialization/CSerialVersion.h \
|
||||
Serialization/XML.h \
|
||||
Serialization/Binary.h \
|
||||
FileIO\CFileInStream.h \
|
||||
FileIO\CFileOutStream.h \
|
||||
FileIO\CMemoryInStream.h \
|
||||
FileIO\CMemoryOutStream.h \
|
||||
FileIO\CTextInStream.h \
|
||||
FileIO\CTextOutStream.h \
|
||||
FileIO\CVectorOutStream.h \
|
||||
FileIO\IOUtil.h \
|
||||
FileIO\IInputStream.h \
|
||||
FileIO\IOutputStream.h \
|
||||
FileIO\CBitStreamInWrapper.h \
|
||||
FileIO\CFileLock.h \
|
||||
FileIO.h \
|
||||
Common.h \
|
||||
Hash/CCRC32.h \
|
||||
NBasics.h
|
||||
|
||||
# Source Files
|
||||
SOURCES += \
|
||||
CColor.cpp \
|
||||
CTimer.cpp \
|
||||
TString.cpp \
|
||||
Log.cpp \
|
||||
FileUtil.cpp \
|
||||
CAssetID.cpp \
|
||||
EGame.cpp \
|
||||
Serialization/CSerialVersion.cpp \
|
||||
FileIO\CFileInStream.cpp \
|
||||
FileIO\CFileOutStream.cpp \
|
||||
FileIO\CMemoryInStream.cpp \
|
||||
FileIO\CMemoryOutStream.cpp \
|
||||
FileIO\CTextInStream.cpp \
|
||||
FileIO\CTextOutStream.cpp \
|
||||
FileIO\CVectorOutStream.cpp \
|
||||
FileIO\IOUtil.cpp \
|
||||
FileIO\IInputStream.cpp \
|
||||
FileIO\IOutputStream.cpp \
|
||||
FileIO\CBitStreamInWrapper.cpp \
|
||||
Hash/CCRC32.cpp
|
||||
|
||||
# Codegen
|
||||
CODEGEN_DIR = $$EXTERNALS_DIR/CodeGen
|
||||
CODEGEN_OUT_PATH = $$BUILD_DIR/Common/codegen_build/auto_codegen.cpp
|
||||
CODEGEN_SRC_PATH = $$PWD
|
||||
include($$EXTERNALS_DIR/CodeGen/codegen.pri)
|
||||
|
||||
# Library Sources
|
||||
SOURCES += $$EXTERNALS_DIR/tinyxml2/tinyxml2.cpp
|
|
@ -1,92 +0,0 @@
|
|||
#include "EGame.h"
|
||||
#include "CFourCC.h"
|
||||
#include "Common/Serialization/IArchive.h"
|
||||
|
||||
TString GetGameName(EGame Game)
|
||||
{
|
||||
static const TString skGameNames[EGame::Max] =
|
||||
{
|
||||
"Metroid Prime Demo",
|
||||
"Metroid Prime",
|
||||
"Metroid Prime 2: Echoes Demo",
|
||||
"Metroid Prime 2: Echoes",
|
||||
"Metroid Prime 3: Corruption E3 2006 Prototype",
|
||||
"Metroid Prime 3: Corruption",
|
||||
"Donkey Kong Country Returns"
|
||||
};
|
||||
|
||||
int GameIdx = (int) Game;
|
||||
return (GameIdx >= 0 && GameIdx < (int) EGame::Max) ? skGameNames[GameIdx] : "Unknown Game";
|
||||
}
|
||||
|
||||
TString GetGameShortName(EGame Game)
|
||||
{
|
||||
static const TString skGameNames[EGame::Max] = {
|
||||
"MP1Demo",
|
||||
"MP1",
|
||||
"MP2Demo",
|
||||
"MP2",
|
||||
"MP3Proto",
|
||||
"MP3",
|
||||
"DKCR"
|
||||
};
|
||||
|
||||
int GameIdx = (int) Game;
|
||||
return (GameIdx >= 0 && GameIdx < (int) EGame::Max) ? skGameNames[GameIdx] : "Unknown";
|
||||
}
|
||||
|
||||
CFourCC GameTo4CC(EGame Game)
|
||||
{
|
||||
static const CFourCC skGame4CCs[EGame::Max] =
|
||||
{
|
||||
FOURCC('MP1D'), FOURCC('MPRM'),
|
||||
FOURCC('MP2D'), FOURCC('MP2E'),
|
||||
FOURCC('MP3P'), FOURCC('MP3C'),
|
||||
FOURCC('DKCR')
|
||||
};
|
||||
|
||||
int GameIdx = (int) Game;
|
||||
return (GameIdx >= 0 && GameIdx < (int) EGame::Max) ? skGame4CCs[GameIdx] : FOURCC('UNKN');
|
||||
}
|
||||
|
||||
EGame GameFrom4CC(CFourCC GameId)
|
||||
{
|
||||
static const std::unordered_map<u32, EGame> skIdToGame =
|
||||
{
|
||||
{ FOURCC('MP1D'), EGame::PrimeDemo },
|
||||
{ FOURCC('MPRM'), EGame::Prime },
|
||||
{ FOURCC('MP2D'), EGame::EchoesDemo },
|
||||
{ FOURCC('MP2E'), EGame::Echoes },
|
||||
{ FOURCC('MP3P'), EGame::CorruptionProto },
|
||||
{ FOURCC('MP3C'), EGame::Corruption },
|
||||
{ FOURCC('DKCR'), EGame::DKCReturns }
|
||||
};
|
||||
auto MapFindIter = skIdToGame.find(GameId.ToLong());
|
||||
return (MapFindIter != skIdToGame.end() ? MapFindIter->second : EGame::Invalid);
|
||||
}
|
||||
|
||||
void Serialize(IArchive& rArc, EGame& rGame)
|
||||
{
|
||||
// We serialize EGame as a fourCC in binary formats as a future-proofing measure.
|
||||
// Additionally, older versions of IArchive always serialized EGame as a fourCC.
|
||||
if (rArc.ArchiveVersion() < IArchive::eArVer_GameEnumClass || rArc.IsBinaryFormat())
|
||||
{
|
||||
CFourCC GameId;
|
||||
|
||||
if (rArc.IsWriter())
|
||||
{
|
||||
GameId = GameTo4CC(rGame);
|
||||
}
|
||||
|
||||
rArc.SerializePrimitive(GameId, 0);
|
||||
|
||||
if (rArc.IsReader())
|
||||
{
|
||||
rGame = GameFrom4CC(GameId);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
DefaultEnumSerialize<EGame>(rArc, rGame);
|
||||
}
|
||||
}
|
|
@ -1,42 +0,0 @@
|
|||
#ifndef EGAME_H
|
||||
#define EGAME_H
|
||||
|
||||
#include "TString.h"
|
||||
#include "types.h"
|
||||
|
||||
class CFourCC;
|
||||
class IArchive;
|
||||
|
||||
//@todo I'm not really happy with EGame being in Common (would like Common to be more
|
||||
// generic so it's more reusable between different projects) but atm can't think of
|
||||
// any other decent way to integrate it with IArchive unfortunately
|
||||
enum class EGame
|
||||
{
|
||||
PrimeDemo,
|
||||
Prime,
|
||||
EchoesDemo,
|
||||
Echoes,
|
||||
CorruptionProto,
|
||||
Corruption,
|
||||
DKCReturns,
|
||||
|
||||
Max,
|
||||
Invalid = -1
|
||||
};
|
||||
|
||||
TString GetGameName(EGame Game);
|
||||
TString GetGameShortName(EGame Game);
|
||||
CFourCC GameTo4CC(EGame Game);
|
||||
EGame GameFrom4CC(CFourCC GameId);
|
||||
void Serialize(IArchive& rArc, EGame& rGame);
|
||||
|
||||
// ERegion
|
||||
enum class ERegion
|
||||
{
|
||||
NTSC,
|
||||
PAL,
|
||||
JPN,
|
||||
Unknown = -1
|
||||
};
|
||||
|
||||
#endif // EGAME_H
|
|
@ -1,21 +0,0 @@
|
|||
#ifndef EKEYINPUTS
|
||||
#define EKEYINPUTS
|
||||
|
||||
#include "Flags.h"
|
||||
|
||||
enum EKeyInput
|
||||
{
|
||||
eCtrlKey = 0x1,
|
||||
eShiftKey = 0x2,
|
||||
eAltKey = 0x2,
|
||||
eQKey = 0x4,
|
||||
eWKey = 0x8,
|
||||
eEKey = 0x10,
|
||||
eAKey = 0x20,
|
||||
eSKey = 0x40,
|
||||
eDKey = 0x80
|
||||
};
|
||||
DECLARE_FLAGS(EKeyInput, FKeyInputs)
|
||||
|
||||
#endif // EKEYINPUTS
|
||||
|
|
@ -1,15 +0,0 @@
|
|||
#ifndef EMOUSEINPUTS
|
||||
#define EMOUSEINPUTS
|
||||
|
||||
#include "Flags.h"
|
||||
|
||||
enum EMouseInput
|
||||
{
|
||||
eLeftButton = 0x1,
|
||||
eMiddleButton = 0x2,
|
||||
eRightButton = 0x4
|
||||
};
|
||||
DECLARE_FLAGS(EMouseInput, FMouseInputs)
|
||||
|
||||
#endif // EMOUSEINPUTS
|
||||
|
|
@ -1,19 +0,0 @@
|
|||
#ifndef FILEIO_H
|
||||
#define FILEIO_H
|
||||
|
||||
#include "Common/FileIO/IOUtil.h"
|
||||
|
||||
#include "Common/FileIO/IInputStream.h"
|
||||
#include "Common/FileIO/CFileInStream.h"
|
||||
#include "Common/FileIO/CMemoryInStream.h"
|
||||
#include "Common/FileIO/CTextInStream.h"
|
||||
|
||||
#include "Common/FileIO/IOutputStream.h"
|
||||
#include "Common/FileIO/CFileOutStream.h"
|
||||
#include "Common/FileIO/CMemoryOutStream.h"
|
||||
#include "Common/FileIO/CVectorOutStream.h"
|
||||
#include "Common/FileIO/CTextOutStream.h"
|
||||
|
||||
#include "Common/FileIO/CBitStreamInWrapper.h"
|
||||
|
||||
#endif // FILEIO
|
|
@ -1,67 +0,0 @@
|
|||
#include "CBitStreamInWrapper.h"
|
||||
|
||||
CBitStreamInWrapper::CBitStreamInWrapper(IInputStream *pStream, EChunkSize ChunkSize /*= e32Bit*/)
|
||||
: mpSourceStream(pStream)
|
||||
, mChunkSize(ChunkSize)
|
||||
, mBitPool(0)
|
||||
, mBitsRemaining(0)
|
||||
{
|
||||
}
|
||||
|
||||
void CBitStreamInWrapper::SetChunkSize(EChunkSize Size)
|
||||
{
|
||||
mChunkSize = Size;
|
||||
}
|
||||
|
||||
long CBitStreamInWrapper::ReadBits(u32 NumBits, bool ExtendSignBit /*= true*/)
|
||||
{
|
||||
u32 BitsRemaining = NumBits;
|
||||
u32 Out = 0;
|
||||
u32 Shift = 0;
|
||||
|
||||
while (BitsRemaining > 0)
|
||||
{
|
||||
if (mBitsRemaining < BitsRemaining)
|
||||
{
|
||||
BitsRemaining -= mBitsRemaining;
|
||||
Out |= (mBitPool << Shift);
|
||||
Shift += mBitsRemaining;
|
||||
ReplenishPool();
|
||||
}
|
||||
|
||||
else
|
||||
{
|
||||
long Mask = (1 << BitsRemaining) - 1;
|
||||
Out |= (mBitPool & Mask) << Shift;
|
||||
mBitPool >>= BitsRemaining;
|
||||
mBitsRemaining -= BitsRemaining;
|
||||
BitsRemaining = 0;
|
||||
}
|
||||
}
|
||||
|
||||
if (ExtendSignBit)
|
||||
{
|
||||
bool Sign = ((Out >> (NumBits - 1) & 0x1) == 1);
|
||||
if (Sign) Out |= (-1 << NumBits);
|
||||
}
|
||||
|
||||
return Out;
|
||||
}
|
||||
|
||||
bool CBitStreamInWrapper::ReadBit()
|
||||
{
|
||||
return (ReadBits(1, false) != 0);
|
||||
}
|
||||
|
||||
// ************ PRIVATE ************
|
||||
void CBitStreamInWrapper::ReplenishPool()
|
||||
{
|
||||
if (mChunkSize == e8Bit)
|
||||
mBitPool = mpSourceStream->ReadByte();
|
||||
else if (mChunkSize == e16Bit)
|
||||
mBitPool = mpSourceStream->ReadShort();
|
||||
else if (mChunkSize == e32Bit)
|
||||
mBitPool = mpSourceStream->ReadLong();
|
||||
|
||||
mBitsRemaining = mChunkSize;
|
||||
}
|
|
@ -1,30 +0,0 @@
|
|||
#ifndef CBITSTREAMINWRAPPER_H
|
||||
#define CBITSTREAMINWRAPPER_H
|
||||
|
||||
#include "IInputStream.h"
|
||||
|
||||
class CBitStreamInWrapper
|
||||
{
|
||||
public:
|
||||
enum EChunkSize
|
||||
{
|
||||
e8Bit = 8, e16Bit = 16, e32Bit = 32
|
||||
};
|
||||
|
||||
private:
|
||||
IInputStream *mpSourceStream;
|
||||
EChunkSize mChunkSize;
|
||||
u32 mBitPool;
|
||||
u32 mBitsRemaining;
|
||||
|
||||
public:
|
||||
CBitStreamInWrapper(IInputStream *pStream, EChunkSize ChunkSize = e32Bit);
|
||||
void SetChunkSize(EChunkSize Size);
|
||||
long ReadBits(u32 NumBits, bool ExtendSignBit = true);
|
||||
bool ReadBit();
|
||||
|
||||
private:
|
||||
void ReplenishPool();
|
||||
};
|
||||
|
||||
#endif // CBITSTREAMINWRAPPER_H
|
|
@ -1,112 +0,0 @@
|
|||
#include "CFileInStream.h"
|
||||
|
||||
CFileInStream::CFileInStream()
|
||||
: mpFStream(nullptr)
|
||||
{
|
||||
}
|
||||
|
||||
CFileInStream::CFileInStream(const TString& rkFile)
|
||||
: mpFStream(nullptr)
|
||||
{
|
||||
Open(rkFile, IOUtil::eBigEndian);
|
||||
}
|
||||
|
||||
CFileInStream::CFileInStream(const TString& rkFile, IOUtil::EEndianness FileEndianness)
|
||||
: mpFStream(nullptr)
|
||||
{
|
||||
Open(rkFile, FileEndianness);
|
||||
}
|
||||
|
||||
CFileInStream::CFileInStream(const CFileInStream& rkSrc)
|
||||
: mpFStream(nullptr)
|
||||
{
|
||||
Open(rkSrc.mName, rkSrc.mDataEndianness);
|
||||
|
||||
if (rkSrc.IsValid())
|
||||
Seek(rkSrc.Tell(), SEEK_SET);
|
||||
}
|
||||
|
||||
CFileInStream::~CFileInStream()
|
||||
{
|
||||
if (IsValid())
|
||||
Close();
|
||||
}
|
||||
|
||||
void CFileInStream::Open(const TString& rkFile, IOUtil::EEndianness FileEndianness)
|
||||
{
|
||||
if (IsValid())
|
||||
Close();
|
||||
|
||||
TWideString WideFile = rkFile.ToUTF16();
|
||||
_wfopen_s(&mpFStream, *WideFile, L"rb");
|
||||
mName = rkFile;
|
||||
mDataEndianness = FileEndianness;
|
||||
|
||||
if (IsValid())
|
||||
{
|
||||
Seek(0x0, SEEK_END);
|
||||
mFileSize = Tell();
|
||||
Seek(0x0, SEEK_SET);
|
||||
}
|
||||
else
|
||||
mFileSize = 0;
|
||||
|
||||
SetSourceString(rkFile.GetFileName());
|
||||
}
|
||||
|
||||
void CFileInStream::Close()
|
||||
{
|
||||
if (IsValid())
|
||||
fclose(mpFStream);
|
||||
mpFStream = nullptr;
|
||||
}
|
||||
|
||||
void CFileInStream::ReadBytes(void *pDst, u32 Count)
|
||||
{
|
||||
if (!IsValid()) return;
|
||||
fread(pDst, 1, Count, mpFStream);
|
||||
}
|
||||
|
||||
bool CFileInStream::Seek(s32 Offset, u32 Origin)
|
||||
{
|
||||
if (!IsValid()) return false;
|
||||
return (fseek(mpFStream, Offset, Origin) != 0);
|
||||
}
|
||||
|
||||
bool CFileInStream::Seek64(s64 Offset, u32 Origin)
|
||||
{
|
||||
if (!IsValid()) return false;
|
||||
return (_fseeki64(mpFStream, Offset, Origin) != 0);
|
||||
}
|
||||
|
||||
u32 CFileInStream::Tell() const
|
||||
{
|
||||
if (!IsValid()) return 0;
|
||||
return ftell(mpFStream);
|
||||
}
|
||||
|
||||
u64 CFileInStream::Tell64() const
|
||||
{
|
||||
if (!IsValid()) return 0;
|
||||
return _ftelli64(mpFStream);
|
||||
}
|
||||
|
||||
bool CFileInStream::EoF() const
|
||||
{
|
||||
return (Tell() >= mFileSize);
|
||||
}
|
||||
|
||||
bool CFileInStream::IsValid() const
|
||||
{
|
||||
return (mpFStream != 0);
|
||||
}
|
||||
|
||||
u32 CFileInStream::Size() const
|
||||
{
|
||||
return mFileSize;
|
||||
}
|
||||
|
||||
TString CFileInStream::FileName() const
|
||||
{
|
||||
return mName;
|
||||
}
|
|
@ -1,34 +0,0 @@
|
|||
#ifndef CFILEINSTREAM_H
|
||||
#define CFILEINSTREAM_H
|
||||
|
||||
#include "IInputStream.h"
|
||||
#include "IOUtil.h"
|
||||
|
||||
class CFileInStream : public IInputStream
|
||||
{
|
||||
private:
|
||||
FILE *mpFStream;
|
||||
TString mName;
|
||||
u32 mFileSize;
|
||||
|
||||
public:
|
||||
CFileInStream();
|
||||
CFileInStream(const TString& rkFile);
|
||||
CFileInStream(const TString& rkFile, IOUtil::EEndianness FileEndianness);
|
||||
CFileInStream(const CFileInStream& rkSrc);
|
||||
~CFileInStream();
|
||||
void Open(const TString& rkFile, IOUtil::EEndianness FileEndianness);
|
||||
void Close();
|
||||
|
||||
void ReadBytes(void *pDst, u32 Count);
|
||||
bool Seek(s32 Offset, u32 Origin);
|
||||
bool Seek64(s64 Offset, u32 Origin);
|
||||
u32 Tell() const;
|
||||
u64 Tell64() const;
|
||||
bool EoF() const;
|
||||
bool IsValid() const;
|
||||
u32 Size() const;
|
||||
TString FileName() const;
|
||||
};
|
||||
|
||||
#endif // CFILEINSTREAM_H
|
|
@ -1,36 +0,0 @@
|
|||
#ifndef CFILELOCK_H
|
||||
#define CFILELOCK_H
|
||||
|
||||
#include <cstdio>
|
||||
#include "Common/TString.h"
|
||||
|
||||
// Maintain a file handle to prevent other processes from accessing the file.
|
||||
class CFileLock
|
||||
{
|
||||
FILE* mpFile;
|
||||
|
||||
public:
|
||||
CFileLock()
|
||||
: mpFile(nullptr)
|
||||
{}
|
||||
|
||||
~CFileLock()
|
||||
{
|
||||
Release();
|
||||
}
|
||||
|
||||
void Lock(const TString& rkPath)
|
||||
{
|
||||
Release();
|
||||
TWideString WidePath = rkPath.ToUTF16();
|
||||
mpFile = _wfopen(*WidePath, L"a+");
|
||||
}
|
||||
|
||||
void Release()
|
||||
{
|
||||
if (mpFile)
|
||||
fclose(mpFile);
|
||||
}
|
||||
};
|
||||
|
||||
#endif // CFILELOCK_H
|
|
@ -1,120 +0,0 @@
|
|||
#include "CFileOutStream.h"
|
||||
|
||||
CFileOutStream::CFileOutStream()
|
||||
: mpFStream(nullptr)
|
||||
, mSize(0)
|
||||
{
|
||||
}
|
||||
|
||||
CFileOutStream::CFileOutStream(const TString& rkFile)
|
||||
: mpFStream(nullptr)
|
||||
{
|
||||
Open(rkFile, IOUtil::eBigEndian);
|
||||
}
|
||||
|
||||
CFileOutStream::CFileOutStream(const TString& rkFile, IOUtil::EEndianness FileEndianness)
|
||||
: mpFStream(nullptr)
|
||||
{
|
||||
Open(rkFile, FileEndianness);
|
||||
}
|
||||
|
||||
CFileOutStream::CFileOutStream(const CFileOutStream& rkSrc)
|
||||
: mpFStream(nullptr)
|
||||
{
|
||||
Open(rkSrc.mName, rkSrc.mDataEndianness);
|
||||
|
||||
if (rkSrc.IsValid())
|
||||
Seek(rkSrc.Tell(), SEEK_SET);
|
||||
}
|
||||
|
||||
CFileOutStream::~CFileOutStream()
|
||||
{
|
||||
if (IsValid())
|
||||
Close();
|
||||
}
|
||||
|
||||
void CFileOutStream::Open(const TString& rkFile, IOUtil::EEndianness FileEndianness)
|
||||
{
|
||||
if (IsValid())
|
||||
Close();
|
||||
|
||||
TWideString WideFile = rkFile.ToUTF16();
|
||||
_wfopen_s(&mpFStream, *WideFile, L"wb");
|
||||
mName = rkFile;
|
||||
mDataEndianness = FileEndianness;
|
||||
mSize = 0;
|
||||
}
|
||||
|
||||
void CFileOutStream::Update(const TString& rkFile, IOUtil::EEndianness FileEndianness)
|
||||
{
|
||||
if (IsValid())
|
||||
Close();
|
||||
|
||||
TWideString WideFile = rkFile.ToUTF16();
|
||||
_wfopen_s(&mpFStream, *WideFile, L"rb+");
|
||||
mName = rkFile;
|
||||
mDataEndianness = FileEndianness;
|
||||
Seek(0x0, SEEK_END);
|
||||
mSize = Tell();
|
||||
Seek(0x0, SEEK_SET);
|
||||
}
|
||||
|
||||
void CFileOutStream::Close()
|
||||
{
|
||||
if (IsValid())
|
||||
fclose(mpFStream);
|
||||
mpFStream = nullptr;
|
||||
mSize = 0;
|
||||
}
|
||||
|
||||
void CFileOutStream::WriteBytes(const void *pkSrc, u32 Count)
|
||||
{
|
||||
if (!IsValid()) return;
|
||||
fwrite(pkSrc, 1, Count, mpFStream);
|
||||
if (Tell() > mSize) mSize = Tell();
|
||||
}
|
||||
|
||||
bool CFileOutStream::Seek(s32 Offset, u32 Origin)
|
||||
{
|
||||
if (!IsValid()) return false;
|
||||
return (fseek(mpFStream, Offset, Origin) != 0);
|
||||
}
|
||||
|
||||
bool CFileOutStream::Seek64(s64 Offset, u32 Origin)
|
||||
{
|
||||
if (!IsValid()) return false;
|
||||
return (_fseeki64(mpFStream, Offset, Origin) != 0);
|
||||
}
|
||||
|
||||
u32 CFileOutStream::Tell() const
|
||||
{
|
||||
if (!IsValid()) return 0;
|
||||
return ftell(mpFStream);
|
||||
}
|
||||
|
||||
u64 CFileOutStream::Tell64() const
|
||||
{
|
||||
if (!IsValid()) return 0;
|
||||
return _ftelli64(mpFStream);
|
||||
}
|
||||
|
||||
bool CFileOutStream::EoF() const
|
||||
{
|
||||
return (Tell() == Size());
|
||||
}
|
||||
|
||||
bool CFileOutStream::IsValid() const
|
||||
{
|
||||
return (mpFStream != 0);
|
||||
}
|
||||
|
||||
u32 CFileOutStream::Size() const
|
||||
{
|
||||
if (!IsValid()) return 0;
|
||||
return mSize;
|
||||
}
|
||||
|
||||
TString CFileOutStream::FileName() const
|
||||
{
|
||||
return mName;
|
||||
}
|
|
@ -1,34 +0,0 @@
|
|||
#ifndef CFILEOUTSTREAM_H
|
||||
#define CFILEOUTSTREAM_H
|
||||
|
||||
#include "IOutputStream.h"
|
||||
|
||||
class CFileOutStream : public IOutputStream
|
||||
{
|
||||
private:
|
||||
FILE *mpFStream;
|
||||
TString mName;
|
||||
u32 mSize;
|
||||
|
||||
public:
|
||||
CFileOutStream();
|
||||
CFileOutStream(const TString& rkFile);
|
||||
CFileOutStream(const TString& rkFile, IOUtil::EEndianness FileEndianness);
|
||||
CFileOutStream(const CFileOutStream& rkSrc);
|
||||
~CFileOutStream();
|
||||
void Open(const TString& rkFile, IOUtil::EEndianness);
|
||||
void Update(const TString& rkFile, IOUtil::EEndianness FileEndianness);
|
||||
void Close();
|
||||
|
||||
void WriteBytes(const void *pkSrc, u32 Count);
|
||||
bool Seek(s32 Offset, u32 Origin);
|
||||
bool Seek64(s64 Offset, u32 Origin);
|
||||
u32 Tell() const;
|
||||
u64 Tell64() const;
|
||||
bool EoF() const;
|
||||
bool IsValid() const;
|
||||
u32 Size() const;
|
||||
TString FileName() const;
|
||||
};
|
||||
|
||||
#endif // CFILEOUTSTREAM_H
|
|
@ -1,104 +0,0 @@
|
|||
#include "CMemoryInStream.h"
|
||||
|
||||
CMemoryInStream::CMemoryInStream()
|
||||
: mpDataStart(nullptr)
|
||||
, mDataSize(0)
|
||||
, mPos(0)
|
||||
{
|
||||
}
|
||||
CMemoryInStream::CMemoryInStream(const void *pkData, u32 Size, IOUtil::EEndianness DataEndianness)
|
||||
{
|
||||
SetData(pkData, Size, DataEndianness);
|
||||
}
|
||||
|
||||
CMemoryInStream::~CMemoryInStream()
|
||||
{
|
||||
}
|
||||
|
||||
void CMemoryInStream::SetData(const void *pkData, u32 Size, IOUtil::EEndianness DataEndianness)
|
||||
{
|
||||
mpDataStart = (const char*) pkData;
|
||||
mDataSize = Size;
|
||||
mPos = 0;
|
||||
mDataEndianness = DataEndianness;
|
||||
}
|
||||
|
||||
void CMemoryInStream::ReadBytes(void *pDst, u32 Count)
|
||||
{
|
||||
if (!IsValid()) return;
|
||||
memcpy(pDst, mpDataStart + mPos, Count);
|
||||
mPos += Count;
|
||||
}
|
||||
|
||||
bool CMemoryInStream::Seek(s32 Offset, u32 Origin)
|
||||
{
|
||||
if (!IsValid()) return false;
|
||||
switch (Origin)
|
||||
{
|
||||
case SEEK_SET:
|
||||
mPos = Offset;
|
||||
break;
|
||||
|
||||
case SEEK_CUR:
|
||||
mPos += Offset;
|
||||
break;
|
||||
|
||||
case SEEK_END:
|
||||
mPos = mDataSize - Offset;
|
||||
break;
|
||||
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
|
||||
if (mPos < 0)
|
||||
{
|
||||
mPos = 0;
|
||||
return false;
|
||||
}
|
||||
|
||||
if (mPos > mDataSize)
|
||||
{
|
||||
mPos = mDataSize;
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
u32 CMemoryInStream::Tell() const
|
||||
{
|
||||
return mPos;
|
||||
}
|
||||
|
||||
bool CMemoryInStream::EoF() const
|
||||
{
|
||||
return (mPos >= mDataSize);
|
||||
}
|
||||
|
||||
bool CMemoryInStream::IsValid() const
|
||||
{
|
||||
return (mpDataStart != nullptr);
|
||||
}
|
||||
|
||||
u32 CMemoryInStream::Size() const
|
||||
{
|
||||
return mDataSize;
|
||||
}
|
||||
|
||||
void CMemoryInStream::SetSize(u32 Size)
|
||||
{
|
||||
mDataSize = Size;
|
||||
if (mPos > mDataSize)
|
||||
mPos = mDataSize;
|
||||
}
|
||||
|
||||
const void* CMemoryInStream::Data() const
|
||||
{
|
||||
return mpDataStart;
|
||||
}
|
||||
|
||||
const void* CMemoryInStream::DataAtPosition() const
|
||||
{
|
||||
return mpDataStart + mPos;
|
||||
}
|
|
@ -1,29 +0,0 @@
|
|||
#ifndef CMEMORYINSTREAM_H
|
||||
#define CMEMORYINSTREAM_H
|
||||
|
||||
#include "IInputStream.h"
|
||||
|
||||
class CMemoryInStream : public IInputStream
|
||||
{
|
||||
const char *mpDataStart;
|
||||
u32 mDataSize;
|
||||
u32 mPos;
|
||||
|
||||
public:
|
||||
CMemoryInStream();
|
||||
CMemoryInStream(const void *pkData, u32 Size, IOUtil::EEndianness dataEndianness);
|
||||
~CMemoryInStream();
|
||||
void SetData(const void *pkData, u32 Size, IOUtil::EEndianness dataEndianness);
|
||||
|
||||
void ReadBytes(void *pDst, u32 Count);
|
||||
bool Seek(s32 Offset, u32 Origin);
|
||||
u32 Tell() const;
|
||||
bool EoF() const;
|
||||
bool IsValid() const;
|
||||
u32 Size() const;
|
||||
void SetSize(u32 Size);
|
||||
const void* Data() const;
|
||||
const void* DataAtPosition() const;
|
||||
};
|
||||
|
||||
#endif // CMEMORYINSTREAM_H
|
|
@ -1,115 +0,0 @@
|
|||
#include "CMemoryOutStream.h"
|
||||
|
||||
CMemoryOutStream::CMemoryOutStream()
|
||||
: mpDataStart(nullptr)
|
||||
, mDataSize(0)
|
||||
, mPos(0)
|
||||
, mUsed(0)
|
||||
{
|
||||
}
|
||||
|
||||
CMemoryOutStream::CMemoryOutStream(void *pData, u32 Size, IOUtil::EEndianness DataEndianness)
|
||||
{
|
||||
SetData(pData, Size, DataEndianness);
|
||||
}
|
||||
|
||||
CMemoryOutStream::~CMemoryOutStream()
|
||||
{
|
||||
}
|
||||
|
||||
void CMemoryOutStream::SetData(void *pData, u32 Size, IOUtil::EEndianness DataEndianness)
|
||||
{
|
||||
mpDataStart = (char*) pData;
|
||||
mDataSize = Size;
|
||||
mPos = 0;
|
||||
mUsed = 0;
|
||||
mDataEndianness = DataEndianness;
|
||||
}
|
||||
|
||||
void CMemoryOutStream::WriteBytes(const void *pkSrc, u32 Count)
|
||||
{
|
||||
if (!IsValid()) return;
|
||||
|
||||
memcpy(mpDataStart + mPos, pkSrc, Count);
|
||||
mPos += Count;
|
||||
if (mPos > mUsed) mUsed = mPos;
|
||||
}
|
||||
|
||||
bool CMemoryOutStream::Seek(s32 Offset, u32 Origin)
|
||||
{
|
||||
if (!IsValid()) return false;
|
||||
|
||||
switch (Origin)
|
||||
{
|
||||
case SEEK_SET:
|
||||
mPos = Offset;
|
||||
break;
|
||||
|
||||
case SEEK_CUR:
|
||||
mPos += Offset;
|
||||
break;
|
||||
|
||||
case SEEK_END:
|
||||
mPos = mDataSize - Offset;
|
||||
break;
|
||||
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
|
||||
if (mPos < 0)
|
||||
{
|
||||
mPos = 0;
|
||||
return false;
|
||||
}
|
||||
|
||||
if (mPos > mDataSize)
|
||||
{
|
||||
mPos = mDataSize;
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
u32 CMemoryOutStream::Tell() const
|
||||
{
|
||||
return mPos;
|
||||
}
|
||||
|
||||
bool CMemoryOutStream::EoF() const
|
||||
{
|
||||
return (mPos >= mDataSize);
|
||||
}
|
||||
|
||||
bool CMemoryOutStream::IsValid() const
|
||||
{
|
||||
return (mpDataStart != nullptr);
|
||||
}
|
||||
|
||||
u32 CMemoryOutStream::Size() const
|
||||
{
|
||||
return mDataSize;
|
||||
}
|
||||
|
||||
u32 CMemoryOutStream::SpaceUsed() const
|
||||
{
|
||||
return mUsed;
|
||||
}
|
||||
|
||||
void CMemoryOutStream::SetSize(u32 Size)
|
||||
{
|
||||
mDataSize = Size;
|
||||
if (mPos > mDataSize)
|
||||
mPos = mDataSize;
|
||||
}
|
||||
|
||||
void* CMemoryOutStream::Data() const
|
||||
{
|
||||
return mpDataStart;
|
||||
}
|
||||
|
||||
void* CMemoryOutStream::DataAtPosition() const
|
||||
{
|
||||
return mpDataStart + mPos;
|
||||
}
|
|
@ -1,31 +0,0 @@
|
|||
#ifndef CMEMORYOUTSTREAM_H
|
||||
#define CMEMORYOUTSTREAM_H
|
||||
|
||||
#include "IOutputStream.h"
|
||||
|
||||
class CMemoryOutStream : public IOutputStream
|
||||
{
|
||||
char *mpDataStart;
|
||||
u32 mDataSize;
|
||||
u32 mPos;
|
||||
u32 mUsed;
|
||||
|
||||
public:
|
||||
CMemoryOutStream();
|
||||
CMemoryOutStream(void *pData, u32 Size, IOUtil::EEndianness mDataEndianness);
|
||||
~CMemoryOutStream();
|
||||
void SetData(void *pData, u32 Size, IOUtil::EEndianness mDataEndianness);
|
||||
|
||||
void WriteBytes(const void *pkSrc, u32 Count);
|
||||
bool Seek(s32 Offset, u32 Origin);
|
||||
u32 Tell() const;
|
||||
bool EoF() const;
|
||||
bool IsValid() const;
|
||||
u32 Size() const;
|
||||
u32 SpaceUsed() const;
|
||||
void SetSize(u32 Size);
|
||||
void* Data() const;
|
||||
void* DataAtPosition() const;
|
||||
};
|
||||
|
||||
#endif // CMEMORYOUTSTREAM_H
|
|
@ -1,106 +0,0 @@
|
|||
#include "CTextInStream.h"
|
||||
#include <stdarg.h>
|
||||
#include <stdio.h>
|
||||
|
||||
CTextInStream::CTextInStream()
|
||||
: mpFStream(nullptr)
|
||||
{
|
||||
}
|
||||
|
||||
CTextInStream::CTextInStream(const TString& rkFile)
|
||||
: mpFStream(nullptr)
|
||||
{
|
||||
Open(rkFile);
|
||||
}
|
||||
|
||||
CTextInStream::CTextInStream(const CTextInStream& rkSrc)
|
||||
: mpFStream(nullptr)
|
||||
{
|
||||
Open(rkSrc.mFileName);
|
||||
|
||||
if (rkSrc.IsValid())
|
||||
Seek(rkSrc.Tell(), SEEK_SET);
|
||||
}
|
||||
|
||||
CTextInStream::~CTextInStream()
|
||||
{
|
||||
if (IsValid())
|
||||
Close();
|
||||
}
|
||||
|
||||
void CTextInStream::Open(const TString& rkFile)
|
||||
{
|
||||
if (IsValid())
|
||||
Close();
|
||||
|
||||
TWideString WideFile = rkFile.ToUTF16();
|
||||
_wfopen_s(&mpFStream, *WideFile, L"r");
|
||||
mFileName = rkFile;
|
||||
|
||||
if (IsValid())
|
||||
{
|
||||
Seek(0x0, SEEK_END);
|
||||
mFileSize = Tell();
|
||||
Seek(0x0, SEEK_SET);
|
||||
}
|
||||
else
|
||||
mFileSize = 0;
|
||||
}
|
||||
|
||||
void CTextInStream::Close()
|
||||
{
|
||||
if (IsValid())
|
||||
fclose(mpFStream);
|
||||
mpFStream = nullptr;
|
||||
}
|
||||
|
||||
void CTextInStream::Scan(const char *pkFormat, ... )
|
||||
{
|
||||
if (!IsValid()) return;
|
||||
|
||||
va_list Args;
|
||||
va_start(Args, pkFormat);
|
||||
vfscanf(mpFStream, pkFormat, Args);
|
||||
}
|
||||
|
||||
char CTextInStream::GetChar()
|
||||
{
|
||||
if (!IsValid()) return 0;
|
||||
return (char) fgetc(mpFStream);
|
||||
}
|
||||
|
||||
TString CTextInStream::GetString()
|
||||
{
|
||||
if (!IsValid()) return "";
|
||||
|
||||
char Buf[0x1000];
|
||||
fgets(Buf, 0x1000, mpFStream);
|
||||
return std::string(Buf);
|
||||
}
|
||||
|
||||
u32 CTextInStream::Seek(s32 Offset, u32 Origin)
|
||||
{
|
||||
if (!IsValid()) return 1;
|
||||
return fseek(mpFStream, Offset, Origin);
|
||||
}
|
||||
|
||||
u32 CTextInStream::Tell() const
|
||||
{
|
||||
if (!IsValid()) return 0;
|
||||
return ftell(mpFStream);
|
||||
}
|
||||
|
||||
bool CTextInStream::EoF() const
|
||||
{
|
||||
return (Tell() == mFileSize);
|
||||
}
|
||||
|
||||
bool CTextInStream::IsValid() const
|
||||
{
|
||||
return (mpFStream != 0);
|
||||
}
|
||||
|
||||
u32 CTextInStream::Size() const
|
||||
{
|
||||
return mFileSize;
|
||||
}
|
|
@ -1,32 +0,0 @@
|
|||
#ifndef CTEXTINSTREAM_H
|
||||
#define CTEXTINSTREAM_H
|
||||
|
||||
#include <cstdio>
|
||||
#include "Common/TString.h"
|
||||
|
||||
class CTextInStream
|
||||
{
|
||||
FILE *mpFStream;
|
||||
TString mFileName;
|
||||
long mFileSize;
|
||||
|
||||
public:
|
||||
CTextInStream();
|
||||
CTextInStream(const TString& rkFile);
|
||||
CTextInStream(const CTextInStream& rkSrc);
|
||||
~CTextInStream();
|
||||
void Open(const TString& rkFile);
|
||||
void Close();
|
||||
|
||||
void Scan(const char *pkFormat, ... );
|
||||
char GetChar();
|
||||
TString GetString();
|
||||
|
||||
u32 Seek(s32 Offset, u32 Origin);
|
||||
u32 Tell() const;
|
||||
bool EoF() const;
|
||||
bool IsValid() const;
|
||||
u32 Size() const;
|
||||
};
|
||||
|
||||
#endif // CTEXTINSTREAM_H
|
|
@ -1,95 +0,0 @@
|
|||
#include "CTextOutStream.h"
|
||||
#include <stdarg.h>
|
||||
|
||||
CTextOutStream::CTextOutStream()
|
||||
: mpFStream(nullptr)
|
||||
, mSize(0)
|
||||
{
|
||||
}
|
||||
|
||||
CTextOutStream::CTextOutStream(const TString& rkFile)
|
||||
: mpFStream(nullptr)
|
||||
{
|
||||
Open(rkFile);
|
||||
}
|
||||
|
||||
CTextOutStream::CTextOutStream(const CTextOutStream& rkSrc)
|
||||
: mpFStream(nullptr)
|
||||
{
|
||||
Open(rkSrc.mFileName);
|
||||
|
||||
if (rkSrc.IsValid())
|
||||
Seek(rkSrc.Tell(), SEEK_SET);
|
||||
}
|
||||
|
||||
CTextOutStream::~CTextOutStream()
|
||||
{
|
||||
if (IsValid())
|
||||
Close();
|
||||
}
|
||||
|
||||
void CTextOutStream::Open(const TString& rkFile)
|
||||
{
|
||||
TWideString WideFile = rkFile.ToUTF16();
|
||||
_wfopen_s(&mpFStream, *WideFile, L"w");
|
||||
mFileName = rkFile;
|
||||
mSize = 0;
|
||||
}
|
||||
|
||||
void CTextOutStream::Close()
|
||||
{
|
||||
if (IsValid())
|
||||
fclose(mpFStream);
|
||||
mpFStream = nullptr;
|
||||
mSize = 0;
|
||||
}
|
||||
|
||||
void CTextOutStream::Print(const char *pkFormat, ... )
|
||||
{
|
||||
if (!IsValid()) return;
|
||||
|
||||
va_list Args;
|
||||
va_start(Args, pkFormat);
|
||||
vfprintf(mpFStream, pkFormat, Args);
|
||||
}
|
||||
|
||||
void CTextOutStream::WriteChar(char Chr)
|
||||
{
|
||||
if (!IsValid()) return;
|
||||
fputc(Chr, mpFStream);
|
||||
if (Tell() > mSize) mSize = Tell();
|
||||
}
|
||||
|
||||
void CTextOutStream::WriteString(const TString& rkStr)
|
||||
{
|
||||
if (!IsValid()) return;
|
||||
fputs(*rkStr, mpFStream);
|
||||
if (Tell() > mSize) mSize = Tell();
|
||||
}
|
||||
|
||||
bool CTextOutStream::Seek(s32 Offset, u32 Origin)
|
||||
{
|
||||
if (!IsValid()) return false;
|
||||
return (fseek(mpFStream, Offset, Origin) != 0);
|
||||
}
|
||||
|
||||
u32 CTextOutStream::Tell() const
|
||||
{
|
||||
if (!IsValid()) return 0;
|
||||
return ftell(mpFStream);
|
||||
}
|
||||
|
||||
bool CTextOutStream::EoF() const
|
||||
{
|
||||
return (Tell() == mSize);
|
||||
}
|
||||
|
||||
bool CTextOutStream::IsValid() const
|
||||
{
|
||||
return (mpFStream != 0);
|
||||
}
|
||||
|
||||
u32 CTextOutStream::Size() const
|
||||
{
|
||||
return mSize;
|
||||
}
|
|
@ -1,31 +0,0 @@
|
|||
#ifndef CTEXTOUTSTREAM_H
|
||||
#define CTEXTOUTSTREAM_H
|
||||
|
||||
#include "Common/TString.h"
|
||||
|
||||
class CTextOutStream
|
||||
{
|
||||
FILE *mpFStream;
|
||||
TString mFileName;
|
||||
unsigned long mSize;
|
||||
|
||||
public:
|
||||
CTextOutStream();
|
||||
CTextOutStream(const TString& rkFile);
|
||||
CTextOutStream(const CTextOutStream& rkSrc);
|
||||
~CTextOutStream();
|
||||
void Open(const TString& rkFile);
|
||||
void Close();
|
||||
|
||||
void Print(const char *pkFormat, ... );
|
||||
void WriteChar(char Chr);
|
||||
void WriteString(const TString& rkStr);
|
||||
|
||||
bool Seek(s32 Offset, u32 Origin);
|
||||
u32 Tell() const;
|
||||
bool EoF() const;
|
||||
bool IsValid() const;
|
||||
u32 Size() const;
|
||||
};
|
||||
|
||||
#endif // CTEXTOUTSTREAM_H
|
|
@ -1,139 +0,0 @@
|
|||
#include "CVectorOutStream.h"
|
||||
#include "Common/Common.h"
|
||||
|
||||
CVectorOutStream::CVectorOutStream()
|
||||
: mpVector(new std::vector<char>)
|
||||
, mOwnsVector(true)
|
||||
, mPos(0)
|
||||
{
|
||||
mDataEndianness = IOUtil::eBigEndian;
|
||||
}
|
||||
|
||||
CVectorOutStream::CVectorOutStream(IOUtil::EEndianness DataEndianness)
|
||||
: mpVector(new std::vector<char>)
|
||||
, mOwnsVector(true)
|
||||
, mPos(0)
|
||||
{
|
||||
mDataEndianness = DataEndianness;
|
||||
}
|
||||
|
||||
CVectorOutStream::CVectorOutStream(u32 InitialSize, IOUtil::EEndianness DataEndianness)
|
||||
: mpVector(new std::vector<char>(InitialSize))
|
||||
, mOwnsVector(true)
|
||||
, mPos(0)
|
||||
{
|
||||
mDataEndianness = DataEndianness;
|
||||
}
|
||||
|
||||
CVectorOutStream::CVectorOutStream(std::vector<char> *pVector, IOUtil::EEndianness DataEndianness)
|
||||
: mpVector(pVector)
|
||||
, mOwnsVector(false)
|
||||
, mPos(0)
|
||||
{
|
||||
mDataEndianness = DataEndianness;
|
||||
}
|
||||
|
||||
CVectorOutStream::~CVectorOutStream()
|
||||
{
|
||||
if (mOwnsVector) delete mpVector;
|
||||
}
|
||||
|
||||
void CVectorOutStream::WriteBytes(const void *pkSrc, u32 Count)
|
||||
{
|
||||
if (!IsValid()) return;
|
||||
|
||||
u32 NewSize = mPos + Count;
|
||||
|
||||
if (NewSize > mpVector->size())
|
||||
{
|
||||
if (NewSize > mpVector->capacity())
|
||||
mpVector->reserve( ALIGN(mPos + Count, skAllocSize) );
|
||||
|
||||
mpVector->resize(NewSize);
|
||||
}
|
||||
|
||||
memcpy(mpVector->data() + mPos, pkSrc, Count);
|
||||
mPos += Count;
|
||||
}
|
||||
|
||||
bool CVectorOutStream::Seek(s32 Offset, u32 Origin)
|
||||
{
|
||||
if (!IsValid()) return false;
|
||||
|
||||
switch (Origin)
|
||||
{
|
||||
case SEEK_SET:
|
||||
mPos = Offset;
|
||||
break;
|
||||
|
||||
case SEEK_CUR:
|
||||
mPos += Offset;
|
||||
break;
|
||||
|
||||
case SEEK_END:
|
||||
mPos = mpVector->size() - Offset;
|
||||
break;
|
||||
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
|
||||
if (mPos < 0)
|
||||
{
|
||||
mPos = 0;
|
||||
return false;
|
||||
}
|
||||
|
||||
if (mPos > mpVector->size())
|
||||
mpVector->resize(mPos);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
u32 CVectorOutStream::Tell() const
|
||||
{
|
||||
return mPos;
|
||||
}
|
||||
|
||||
bool CVectorOutStream::EoF() const
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
bool CVectorOutStream::IsValid() const
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
u32 CVectorOutStream::Size() const
|
||||
{
|
||||
return mPos;
|
||||
}
|
||||
|
||||
void CVectorOutStream::SetVector(std::vector<char> *pVector)
|
||||
{
|
||||
if (mOwnsVector)
|
||||
{
|
||||
delete mpVector;
|
||||
mOwnsVector = false;
|
||||
}
|
||||
|
||||
mpVector = pVector;
|
||||
mPos = 0;
|
||||
}
|
||||
|
||||
void* CVectorOutStream::Data()
|
||||
{
|
||||
return mpVector->data();
|
||||
}
|
||||
|
||||
void* CVectorOutStream::DataAtPosition()
|
||||
{
|
||||
return mpVector->data() + mPos;
|
||||
}
|
||||
|
||||
void CVectorOutStream::Clear()
|
||||
{
|
||||
mPos = 0;
|
||||
mpVector->clear();
|
||||
}
|
|
@ -1,34 +0,0 @@
|
|||
#ifndef CVECTOROUTSTREAM_H
|
||||
#define CVECTOROUTSTREAM_H
|
||||
|
||||
#include "IOutputStream.h"
|
||||
#include <vector>
|
||||
|
||||
class CVectorOutStream : public IOutputStream
|
||||
{
|
||||
static const u32 skAllocSize = 1; // must be 1 or a power of 2
|
||||
|
||||
std::vector<char> *mpVector;
|
||||
bool mOwnsVector;
|
||||
u32 mPos;
|
||||
|
||||
public:
|
||||
CVectorOutStream();
|
||||
CVectorOutStream(IOUtil::EEndianness DataEndianness);
|
||||
CVectorOutStream(u32 InitialSize, IOUtil::EEndianness DataEndianness);
|
||||
CVectorOutStream(std::vector<char> *pVector, IOUtil::EEndianness DataEndianness);
|
||||
~CVectorOutStream();
|
||||
|
||||
void WriteBytes(const void *pkSrc, u32 Count);
|
||||
bool Seek(s32 Offset, u32 Origin);
|
||||
u32 Tell() const;
|
||||
bool EoF() const;
|
||||
bool IsValid() const;
|
||||
u32 Size() const;
|
||||
void SetVector(std::vector<char> *pVector);
|
||||
void *Data();
|
||||
void *DataAtPosition();
|
||||
void Clear();
|
||||
};
|
||||
|
||||
#endif // CVECTOROUTSTREAM_H
|
|
@ -1,221 +0,0 @@
|
|||
#include "IInputStream.h"
|
||||
#include <assert.h>
|
||||
|
||||
IInputStream::~IInputStream()
|
||||
{
|
||||
}
|
||||
|
||||
bool IInputStream::ReadBool()
|
||||
{
|
||||
char Val;
|
||||
ReadBytes(&Val, 1);
|
||||
assert(Val == 0 || Val == 1);
|
||||
return (Val != 0 ? true : false);
|
||||
}
|
||||
|
||||
char IInputStream::ReadByte()
|
||||
{
|
||||
char Val;
|
||||
ReadBytes(&Val, 1);
|
||||
return Val;
|
||||
}
|
||||
|
||||
short IInputStream::ReadShort()
|
||||
{
|
||||
short Val;
|
||||
ReadBytes(&Val, 2);
|
||||
if (mDataEndianness != IOUtil::kSystemEndianness) IOUtil::SwapBytes(Val);
|
||||
return Val;
|
||||
}
|
||||
|
||||
long IInputStream::ReadLong()
|
||||
{
|
||||
long Val;
|
||||
ReadBytes(&Val, 4);
|
||||
if (mDataEndianness != IOUtil::kSystemEndianness) IOUtil::SwapBytes(Val);
|
||||
return Val;
|
||||
}
|
||||
|
||||
long long IInputStream::ReadLongLong()
|
||||
{
|
||||
long long Val;
|
||||
ReadBytes(&Val, 8);
|
||||
if (mDataEndianness != IOUtil::kSystemEndianness) IOUtil::SwapBytes(Val);
|
||||
return Val;
|
||||
}
|
||||
|
||||
float IInputStream::ReadFloat()
|
||||
{
|
||||
float Val;
|
||||
ReadBytes(&Val, 4);
|
||||
if (mDataEndianness != IOUtil::kSystemEndianness) IOUtil::SwapBytes(Val);
|
||||
return Val;
|
||||
}
|
||||
|
||||
double IInputStream::ReadDouble()
|
||||
{
|
||||
double Val;
|
||||
ReadBytes(&Val, 8);
|
||||
if (mDataEndianness != IOUtil::kSystemEndianness) IOUtil::SwapBytes(Val);
|
||||
return Val;
|
||||
}
|
||||
|
||||
long IInputStream::ReadFourCC()
|
||||
{
|
||||
long Val;
|
||||
ReadBytes(&Val, 4);
|
||||
if (IOUtil::kSystemEndianness == IOUtil::eLittleEndian) IOUtil::SwapBytes(Val);
|
||||
return Val;
|
||||
}
|
||||
|
||||
TString IInputStream::ReadString()
|
||||
{
|
||||
TString Str;
|
||||
char Chr;
|
||||
|
||||
do
|
||||
{
|
||||
Chr = ReadByte();
|
||||
if (Chr != 0) Str.Append(Chr);
|
||||
}
|
||||
while ((Chr != 0) && (!EoF()));
|
||||
|
||||
return Str;
|
||||
}
|
||||
|
||||
TString IInputStream::ReadString(u32 Count)
|
||||
{
|
||||
TString Str(Count, 0);
|
||||
ReadBytes(&Str[0], Count);
|
||||
return Str;
|
||||
}
|
||||
|
||||
TString IInputStream::ReadSizedString()
|
||||
{
|
||||
u32 StringSize = ReadLong();
|
||||
return ReadString(StringSize);
|
||||
}
|
||||
|
||||
TWideString IInputStream::ReadWString()
|
||||
{
|
||||
TWideString WStr;
|
||||
short Chr = 1;
|
||||
|
||||
do
|
||||
{
|
||||
Chr = ReadShort();
|
||||
if (Chr != 0) WStr.Append(Chr);
|
||||
}
|
||||
while (Chr != 0 && !EoF());
|
||||
|
||||
return WStr;
|
||||
}
|
||||
|
||||
TWideString IInputStream::ReadWString(u32 Count)
|
||||
{
|
||||
TWideString WStr(Count, 0);
|
||||
ReadBytes(&WStr[0], WStr.Size() * 2);
|
||||
return WStr;
|
||||
}
|
||||
|
||||
TWideString IInputStream::ReadSizedWString()
|
||||
{
|
||||
u32 StringSize = ReadLong();
|
||||
return ReadWString(StringSize);
|
||||
}
|
||||
|
||||
char IInputStream::PeekByte()
|
||||
{
|
||||
char Val = ReadByte();
|
||||
Seek(-1, SEEK_CUR);
|
||||
return Val;
|
||||
}
|
||||
|
||||
short IInputStream::PeekShort()
|
||||
{
|
||||
short Val = ReadShort();
|
||||
Seek(-2, SEEK_CUR);
|
||||
return Val;
|
||||
}
|
||||
|
||||
long IInputStream::PeekLong()
|
||||
{
|
||||
long Val = ReadLong();
|
||||
Seek(-4, SEEK_CUR);
|
||||
return Val;
|
||||
}
|
||||
|
||||
long long IInputStream::PeekLongLong()
|
||||
{
|
||||
long long Val = ReadLongLong();
|
||||
Seek(-8, SEEK_CUR);
|
||||
return Val;
|
||||
}
|
||||
|
||||
float IInputStream::PeekFloat()
|
||||
{
|
||||
float Val = ReadFloat();
|
||||
Seek(-4, SEEK_CUR);
|
||||
return Val;
|
||||
}
|
||||
|
||||
double IInputStream::PeekDouble()
|
||||
{
|
||||
double Val = ReadDouble();
|
||||
Seek(-8, SEEK_CUR);
|
||||
return Val;
|
||||
}
|
||||
|
||||
long IInputStream::PeekFourCC()
|
||||
{
|
||||
long Val = ReadFourCC();
|
||||
Seek(-4, SEEK_CUR);
|
||||
return Val;
|
||||
}
|
||||
|
||||
bool IInputStream::GoTo(u32 Address)
|
||||
{
|
||||
return Seek(Address, SEEK_SET);
|
||||
}
|
||||
|
||||
bool IInputStream::Skip(s32 SkipAmount)
|
||||
{
|
||||
return Seek(SkipAmount, SEEK_CUR);
|
||||
}
|
||||
|
||||
void IInputStream::SeekToBoundary(u32 Boundary)
|
||||
{
|
||||
u32 Num = Boundary - (Tell() % Boundary);
|
||||
if (Num == Boundary) return;
|
||||
else Seek(Num, SEEK_CUR);
|
||||
}
|
||||
|
||||
void IInputStream::SetEndianness(IOUtil::EEndianness Endianness)
|
||||
{
|
||||
mDataEndianness = Endianness;
|
||||
}
|
||||
|
||||
void IInputStream::SetSourceString(const TString& rkSource)
|
||||
{
|
||||
mDataSource = rkSource;
|
||||
}
|
||||
|
||||
IOUtil::EEndianness IInputStream::GetEndianness() const
|
||||
{
|
||||
return mDataEndianness;
|
||||
}
|
||||
|
||||
TString IInputStream::GetSourceString() const
|
||||
{
|
||||
return mDataSource;
|
||||
}
|
||||
|
||||
bool IInputStream::Seek64(s64 Offset, u32 Origin)
|
||||
{
|
||||
return Seek((s32) Offset, Origin);
|
||||
}
|
||||
|
||||
u64 IInputStream::Tell64() const
|
||||
{
|
||||
return (u64) Tell();
|
||||
}
|
|
@ -1,59 +0,0 @@
|
|||
#ifndef IINPUTSTREAM_H
|
||||
#define IINPUTSTREAM_H
|
||||
|
||||
#include "IOUtil.h"
|
||||
#include "Common/TString.h"
|
||||
#include "Common/types.h"
|
||||
#include <vector>
|
||||
|
||||
class IInputStream
|
||||
{
|
||||
protected:
|
||||
IOUtil::EEndianness mDataEndianness;
|
||||
TString mDataSource;
|
||||
|
||||
public:
|
||||
bool ReadBool();
|
||||
char ReadByte();
|
||||
short ReadShort();
|
||||
long ReadLong();
|
||||
long long ReadLongLong();
|
||||
float ReadFloat();
|
||||
double ReadDouble();
|
||||
long ReadFourCC();
|
||||
TString ReadString();
|
||||
TString ReadString(u32 Count);
|
||||
TString ReadSizedString();
|
||||
TWideString ReadWString();
|
||||
TWideString ReadWString(u32 Count);
|
||||
TWideString ReadSizedWString();
|
||||
|
||||
char PeekByte();
|
||||
short PeekShort();
|
||||
long PeekLong();
|
||||
long long PeekLongLong();
|
||||
float PeekFloat();
|
||||
double PeekDouble();
|
||||
long PeekFourCC();
|
||||
|
||||
bool GoTo(u32 Address);
|
||||
bool Skip(s32 SkipAmount);
|
||||
|
||||
void SeekToBoundary(u32 Boundary);
|
||||
void SetEndianness(IOUtil::EEndianness Endianness);
|
||||
void SetSourceString(const TString& rkSource);
|
||||
IOUtil::EEndianness GetEndianness() const;
|
||||
TString GetSourceString() const;
|
||||
|
||||
virtual ~IInputStream();
|
||||
virtual void ReadBytes(void *pDst, u32 Count) = 0;
|
||||
virtual bool Seek(s32 Offset, u32 Origin) = 0;
|
||||
virtual bool Seek64(s64 Offset, u32 Origin);
|
||||
virtual u32 Tell() const = 0;
|
||||
virtual u64 Tell64() const;
|
||||
virtual bool EoF() const = 0;
|
||||
virtual bool IsValid() const = 0;
|
||||
virtual u32 Size() const = 0;
|
||||
};
|
||||
|
||||
#endif // IINPUTSTREAM_H
|
|
@ -1,79 +0,0 @@
|
|||
#include "IOUtil.h"
|
||||
|
||||
namespace IOUtil
|
||||
{
|
||||
EEndianness FindSystemEndianness()
|
||||
{
|
||||
// Memory layout for a 32-bit value of 1:
|
||||
// 0x01000000 - Little Endian
|
||||
// 0x00000001 - Big Endian
|
||||
long EndianTest = 1;
|
||||
if (*(char*)&EndianTest == 1) return eLittleEndian;
|
||||
else return eBigEndian;
|
||||
}
|
||||
const EEndianness kSystemEndianness = FindSystemEndianness();
|
||||
|
||||
void SwapBytes(short& rVal)
|
||||
{
|
||||
rVal = (((rVal & 0x00FF) << 8) |
|
||||
((rVal & 0xFF00) >> 8));
|
||||
}
|
||||
|
||||
void SwapBytes(unsigned short& rVal)
|
||||
{
|
||||
rVal = (((rVal & 0x00FF) << 8) |
|
||||
((rVal & 0xFF00) >> 8));
|
||||
}
|
||||
|
||||
void SwapBytes(long& rVal)
|
||||
{
|
||||
rVal = (((rVal & 0x000000FF) << 24) |
|
||||
((rVal & 0x0000FF00) << 8) |
|
||||
((rVal & 0x00FF0000) >> 8) |
|
||||
((rVal & 0xFF000000) >> 24));
|
||||
}
|
||||
|
||||
void SwapBytes(unsigned long& rVal)
|
||||
{
|
||||
rVal = (((rVal & 0x000000FF) << 24) |
|
||||
((rVal & 0x0000FF00) << 8) |
|
||||
((rVal & 0x00FF0000) >> 8) |
|
||||
((rVal & 0xFF000000) >> 24));
|
||||
}
|
||||
|
||||
void SwapBytes(long long& rVal)
|
||||
{
|
||||
rVal = (((rVal & 0x00000000000000FF) << 56) |
|
||||
((rVal & 0x000000000000FF00) << 40) |
|
||||
((rVal & 0x0000000000FF0000) << 24) |
|
||||
((rVal & 0x00000000FF000000) << 8) |
|
||||
((rVal & 0x000000FF00000000) >> 8) |
|
||||
((rVal & 0x0000FF0000000000) >> 24) |
|
||||
((rVal & 0x00FF000000000000) >> 40) |
|
||||
((rVal & 0xFF00000000000000) >> 56));
|
||||
}
|
||||
|
||||
void SwapBytes(unsigned long long& rVal)
|
||||
{
|
||||
rVal = (((rVal & 0x00000000000000FF) << 56) |
|
||||
((rVal & 0x000000000000FF00) << 40) |
|
||||
((rVal & 0x0000000000FF0000) << 24) |
|
||||
((rVal & 0x00000000FF000000) << 8) |
|
||||
((rVal & 0x000000FF00000000) >> 8) |
|
||||
((rVal & 0x0000FF0000000000) >> 24) |
|
||||
((rVal & 0x00FF000000000000) >> 40) |
|
||||
((rVal & 0xFF00000000000000) >> 56));
|
||||
}
|
||||
|
||||
void SwapBytes(float& rVal)
|
||||
{
|
||||
long* pPtr = (long*) &rVal;
|
||||
SwapBytes(*pPtr);
|
||||
}
|
||||
|
||||
void SwapBytes(double& rVal)
|
||||
{
|
||||
long long* pPtr = (long long*) &rVal;
|
||||
SwapBytes(*pPtr);
|
||||
}
|
||||
}
|
|
@ -1,22 +0,0 @@
|
|||
#ifndef IOUTIL_H
|
||||
#define IOUTIL_H
|
||||
|
||||
namespace IOUtil
|
||||
{
|
||||
enum EEndianness {
|
||||
eLittleEndian,
|
||||
eBigEndian
|
||||
};
|
||||
extern const EEndianness kSystemEndianness;
|
||||
|
||||
void SwapBytes(short& rVal);
|
||||
void SwapBytes(unsigned short& rVal);
|
||||
void SwapBytes(long& rVal);
|
||||
void SwapBytes(unsigned long& rVal);
|
||||
void SwapBytes(long long& rVal);
|
||||
void SwapBytes(unsigned long long& rVal);
|
||||
void SwapBytes(float& rVal);
|
||||
void SwapBytes(double& rVal);
|
||||
}
|
||||
|
||||
#endif // IOUTIL_H
|
|
@ -1,137 +0,0 @@
|
|||
#include "IOutputStream.h"
|
||||
|
||||
IOutputStream::~IOutputStream()
|
||||
{
|
||||
}
|
||||
|
||||
void IOutputStream::WriteBool(bool Val)
|
||||
{
|
||||
char ChrVal = (Val ? 1 : 0);
|
||||
WriteBytes(&ChrVal, 1);
|
||||
}
|
||||
|
||||
void IOutputStream::WriteByte(char Val)
|
||||
{
|
||||
WriteBytes(&Val, 1);
|
||||
}
|
||||
|
||||
void IOutputStream::WriteShort(short Val)
|
||||
{
|
||||
if (mDataEndianness != IOUtil::kSystemEndianness) IOUtil::SwapBytes(Val);
|
||||
WriteBytes(&Val, 2);
|
||||
}
|
||||
|
||||
void IOutputStream::WriteLong(long Val)
|
||||
{
|
||||
if (mDataEndianness != IOUtil::kSystemEndianness) IOUtil::SwapBytes(Val);
|
||||
WriteBytes(&Val, 4);
|
||||
}
|
||||
|
||||
void IOutputStream::WriteLongLong(long long Val)
|
||||
{
|
||||
if (mDataEndianness != IOUtil::kSystemEndianness) IOUtil::SwapBytes(Val);
|
||||
WriteBytes(&Val, 8);
|
||||
}
|
||||
|
||||
void IOutputStream::WriteFloat(float Val)
|
||||
{
|
||||
if (mDataEndianness != IOUtil::kSystemEndianness) IOUtil::SwapBytes(Val);
|
||||
WriteBytes(&Val, 4);
|
||||
}
|
||||
|
||||
void IOutputStream::WriteDouble(double Val)
|
||||
{
|
||||
if (mDataEndianness != IOUtil::kSystemEndianness) IOUtil::SwapBytes(Val);
|
||||
WriteBytes(&Val, 8);
|
||||
}
|
||||
|
||||
void IOutputStream::WriteFourCC(long Val)
|
||||
{
|
||||
if (IOUtil::kSystemEndianness == IOUtil::eLittleEndian) IOUtil::SwapBytes(Val);
|
||||
WriteBytes(&Val, 4);
|
||||
}
|
||||
|
||||
void IOutputStream::WriteString(const TString& rkVal, int Count /*= -1*/, bool Terminate /*= true*/)
|
||||
{
|
||||
if (Count < 0)
|
||||
Count = rkVal.Size();
|
||||
|
||||
WriteBytes(rkVal.Data(), Count);
|
||||
|
||||
if (Terminate && (rkVal.IsEmpty() || rkVal[Count-1] != 0))
|
||||
WriteByte(0);
|
||||
}
|
||||
|
||||
void IOutputStream::WriteSizedString(const TString& rkVal)
|
||||
{
|
||||
WriteLong(rkVal.Size());
|
||||
WriteBytes(rkVal.Data(), rkVal.Size());
|
||||
}
|
||||
|
||||
void IOutputStream::WriteWString(const TWideString& rkVal, int Count /*= -1*/, bool Terminate /*= true*/)
|
||||
{
|
||||
if (Count < 0)
|
||||
Count = rkVal.Size();
|
||||
|
||||
for (int ChrIdx = 0; ChrIdx < Count; ChrIdx++)
|
||||
WriteShort(rkVal[ChrIdx]);
|
||||
|
||||
if (Terminate && (rkVal.IsEmpty() || rkVal[Count-1] != 0))
|
||||
WriteShort(0);
|
||||
}
|
||||
|
||||
void IOutputStream::WriteSizedWString(const TWideString& rkVal)
|
||||
{
|
||||
WriteLong(rkVal.Size());
|
||||
|
||||
for (u32 ChrIdx = 0; ChrIdx < rkVal.Size(); ChrIdx++)
|
||||
WriteShort(rkVal[ChrIdx]);
|
||||
}
|
||||
|
||||
bool IOutputStream::GoTo(u32 Address)
|
||||
{
|
||||
return Seek(Address, SEEK_SET);
|
||||
}
|
||||
|
||||
bool IOutputStream::Skip(s32 SkipAmount)
|
||||
{
|
||||
return Seek(SkipAmount, SEEK_CUR);
|
||||
}
|
||||
|
||||
void IOutputStream::WriteToBoundary(u32 Boundary, u8 Fill)
|
||||
{
|
||||
u32 Num = Boundary - (Tell() % Boundary);
|
||||
if (Num == Boundary) return;
|
||||
for (u32 iByte = 0; iByte < Num; iByte++)
|
||||
WriteByte(Fill);
|
||||
}
|
||||
|
||||
void IOutputStream::SetEndianness(IOUtil::EEndianness Endianness)
|
||||
{
|
||||
mDataEndianness = Endianness;
|
||||
}
|
||||
|
||||
void IOutputStream::SetDestString(const TString& rkDest)
|
||||
{
|
||||
mDataDest = rkDest;
|
||||
}
|
||||
|
||||
IOUtil::EEndianness IOutputStream::GetEndianness() const
|
||||
{
|
||||
return mDataEndianness;
|
||||
}
|
||||
|
||||
TString IOutputStream::GetDestString() const
|
||||
{
|
||||
return mDataDest;
|
||||
}
|
||||
|
||||
bool IOutputStream::Seek64(s64 Offset, u32 Origin)
|
||||
{
|
||||
return Seek((s32) Offset, Origin);
|
||||
}
|
||||
|
||||
u64 IOutputStream::Tell64() const
|
||||
{
|
||||
return (u64) (Tell());
|
||||
}
|
|
@ -1,46 +0,0 @@
|
|||
#ifndef IOUTPUTSTREAM_H
|
||||
#define IOUTPUTSTREAM_H
|
||||
|
||||
#include "IOUtil.h"
|
||||
#include "Common/TString.h"
|
||||
|
||||
class IOutputStream
|
||||
{
|
||||
protected:
|
||||
IOUtil::EEndianness mDataEndianness;
|
||||
TString mDataDest;
|
||||
|
||||
public:
|
||||
void WriteBool(bool Val);
|
||||
void WriteByte(char Val);
|
||||
void WriteShort(short Val);
|
||||
void WriteLong(long Val);
|
||||
void WriteLongLong(long long Val);
|
||||
void WriteFloat(float Val);
|
||||
void WriteDouble(double Val);
|
||||
void WriteFourCC(long Val);
|
||||
void WriteString(const TString& rkVal, int Count = -1, bool Terminate = true);
|
||||
void WriteSizedString(const TString& rkVal);
|
||||
void WriteWString(const TWideString& rkVal, int Count = -1, bool Terminate = true);
|
||||
void WriteSizedWString(const TWideString& rkVal);
|
||||
|
||||
bool GoTo(u32 Address);
|
||||
bool Skip(s32 SkipAmount);
|
||||
|
||||
void WriteToBoundary(u32 Boundary, u8 Fill);
|
||||
void SetEndianness(IOUtil::EEndianness Endianness);
|
||||
void SetDestString(const TString& rkDest);
|
||||
IOUtil::EEndianness GetEndianness() const;
|
||||
TString GetDestString() const;
|
||||
|
||||
virtual ~IOutputStream();
|
||||
virtual void WriteBytes(const void *pkSrc, u32 Count) = 0;
|
||||
virtual bool Seek(s32 Offset, u32 Origin) = 0;
|
||||
virtual bool Seek64(s64 Offset, u32 Origin);
|
||||
virtual u32 Tell() const = 0;
|
||||
virtual u64 Tell64() const;
|
||||
virtual bool EoF() const = 0;
|
||||
virtual bool IsValid() const = 0;
|
||||
virtual u32 Size() const = 0;
|
||||
};
|
||||
#endif // COUTPUTSTREAM_H
|
|
@ -1,529 +0,0 @@
|
|||
#include "FileUtil.h"
|
||||
#include "AssertMacro.h"
|
||||
#include "Common/FileIO/CFileInStream.h"
|
||||
|
||||
#include <experimental/filesystem>
|
||||
#include <system_error>
|
||||
|
||||
// These are mostly just wrappers around std::filesystem functions.
|
||||
using namespace std::experimental::filesystem::v1;
|
||||
|
||||
namespace FileUtil
|
||||
{
|
||||
|
||||
#define ToPath(Path) u8path(Path)
|
||||
|
||||
bool Exists(const TString &rkFilePath)
|
||||
{
|
||||
return exists(ToPath(*rkFilePath));
|
||||
}
|
||||
|
||||
bool IsRoot(const TString& rkPath)
|
||||
{
|
||||
// todo: is this actually a good/multiplatform way of checking for root?
|
||||
TString AbsPath = MakeAbsolute(rkPath);
|
||||
TStringList Split = AbsPath.Split("\\/");
|
||||
return (Split.size() <= 1);
|
||||
}
|
||||
|
||||
bool IsFile(const TString& rkFilePath)
|
||||
{
|
||||
return is_regular_file(ToPath(*rkFilePath));
|
||||
}
|
||||
|
||||
bool IsDirectory(const TString& rkDirPath)
|
||||
{
|
||||
return is_directory(ToPath(*rkDirPath));
|
||||
}
|
||||
|
||||
bool IsAbsolute(const TString& rkDirPath)
|
||||
{
|
||||
return ToPath(*rkDirPath).is_absolute();
|
||||
}
|
||||
|
||||
bool IsRelative(const TString& rkDirPath)
|
||||
{
|
||||
return ToPath(*rkDirPath).is_relative();
|
||||
}
|
||||
|
||||
bool IsEmpty(const TString& rkDirPath)
|
||||
{
|
||||
if (!IsDirectory(rkDirPath))
|
||||
{
|
||||
Log::Error("Non-directory path passed to IsEmpty(): " + rkDirPath);
|
||||
return false;
|
||||
}
|
||||
|
||||
return is_empty(ToPath(*rkDirPath));
|
||||
}
|
||||
|
||||
bool MakeDirectory(const TString& rkNewDir)
|
||||
{
|
||||
if (!IsValidPath(rkNewDir, true))
|
||||
{
|
||||
Log::Error("Unable to create directory because name contains illegal characters: " + rkNewDir);
|
||||
return false;
|
||||
}
|
||||
|
||||
return create_directories(ToPath(*rkNewDir));
|
||||
}
|
||||
|
||||
bool CopyFile(const TString& rkOrigPath, const TString& rkNewPath)
|
||||
{
|
||||
if (!IsValidPath(rkNewPath, false))
|
||||
{
|
||||
Log::Error("Unable to copy file because destination name contains illegal characters: " + rkNewPath);
|
||||
return false;
|
||||
}
|
||||
|
||||
MakeDirectory(rkNewPath.GetFileDirectory());
|
||||
std::error_code Error;
|
||||
// call std::filesystem::copy, not std::copy
|
||||
std::experimental::filesystem::copy(ToPath(*rkOrigPath), ToPath(*rkNewPath), Error);
|
||||
return (Error.value() == 0);
|
||||
}
|
||||
|
||||
bool CopyDirectory(const TString& rkOrigPath, const TString& rkNewPath)
|
||||
{
|
||||
if (!IsValidPath(rkNewPath, true))
|
||||
{
|
||||
Log::Error("Unable to copy directory because destination name contains illegal characters: " + rkNewPath);
|
||||
return false;
|
||||
}
|
||||
|
||||
MakeDirectory(rkNewPath.GetFileDirectory());
|
||||
std::error_code Error;
|
||||
// call std::filesystem::copy, not std::copy
|
||||
std::experimental::filesystem::copy(ToPath(*rkOrigPath), ToPath(*rkNewPath), Error);
|
||||
return (Error.value() == 0);
|
||||
}
|
||||
|
||||
bool MoveFile(const TString& rkOldPath, const TString& rkNewPath)
|
||||
{
|
||||
if (!IsValidPath(rkNewPath, false))
|
||||
{
|
||||
Log::Error("Unable to move file because destination name contains illegal characters: " + rkNewPath);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (Exists(rkNewPath))
|
||||
{
|
||||
Log::Error("Unable to move file because there is an existing file at the destination path: " + rkNewPath);
|
||||
return false;
|
||||
}
|
||||
|
||||
std::error_code Error;
|
||||
rename(ToPath(*rkOldPath), ToPath(*rkNewPath), Error);
|
||||
return Error.value() == 0;
|
||||
}
|
||||
|
||||
bool MoveDirectory(const TString& rkOldPath, const TString& rkNewPath)
|
||||
{
|
||||
if (!IsValidPath(rkNewPath, true))
|
||||
{
|
||||
Log::Error("Unable to move directory because destination name contains illegal characters: " + rkNewPath);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (Exists(rkNewPath))
|
||||
{
|
||||
Log::Error("Unable to move directory because there is an existing directory at the destination path: %s" + rkNewPath);
|
||||
return false;
|
||||
}
|
||||
|
||||
std::error_code Error;
|
||||
rename(ToPath(*rkOldPath), ToPath(*rkNewPath), Error);
|
||||
return Error.value() == 0;
|
||||
}
|
||||
|
||||
bool DeleteFile(const TString& rkFilePath)
|
||||
{
|
||||
if (!IsFile(rkFilePath)) return false;
|
||||
return remove(ToPath(*rkFilePath)) == 1;
|
||||
}
|
||||
|
||||
bool DeleteDirectory(const TString& rkDirPath, bool FailIfNotEmpty)
|
||||
{
|
||||
// This is an extremely destructive function, be careful using it!
|
||||
if (!IsDirectory(rkDirPath)) return false;
|
||||
|
||||
// Sanity check - don't delete root
|
||||
bool Root = IsRoot(rkDirPath);
|
||||
|
||||
if (Root)
|
||||
{
|
||||
ASSERT(false);
|
||||
Log::Fatal("Attempted to delete root directory!");
|
||||
return false;
|
||||
}
|
||||
|
||||
// Check if directory is empty
|
||||
if (FailIfNotEmpty && !IsEmpty(rkDirPath))
|
||||
return false;
|
||||
|
||||
// Delete directory
|
||||
std::error_code Error;
|
||||
remove_all(ToPath(*rkDirPath), Error);
|
||||
return (Error.value() == 0);
|
||||
}
|
||||
|
||||
bool ClearDirectory(const TString& rkDirPath)
|
||||
{
|
||||
// This is an extremely destructive function, be careful using it!
|
||||
if (!IsDirectory(rkDirPath)) return false;
|
||||
|
||||
// Sanity check - don't clear root
|
||||
bool Root = IsRoot(rkDirPath);
|
||||
|
||||
if (Root)
|
||||
{
|
||||
ASSERT(false);
|
||||
Log::Fatal("Attempted to clear root directory!");
|
||||
return false;
|
||||
}
|
||||
|
||||
// Delete directory contents
|
||||
TStringList DirContents;
|
||||
GetDirectoryContents(rkDirPath, DirContents, false);
|
||||
|
||||
for (auto It = DirContents.begin(); It != DirContents.end(); It++)
|
||||
{
|
||||
bool Success = false;
|
||||
|
||||
if (IsFile(*It))
|
||||
Success = DeleteFile(*It);
|
||||
else if (IsDirectory(*It))
|
||||
Success = DeleteDirectory(*It, false);
|
||||
|
||||
if (!Success)
|
||||
Log::Error("Failed to delete filesystem object: " + TString(*It));
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
u64 FileSize(const TString &rkFilePath)
|
||||
{
|
||||
return (u64) (Exists(rkFilePath) ? file_size(ToPath(*rkFilePath)) : -1);
|
||||
}
|
||||
|
||||
u64 LastModifiedTime(const TString& rkFilePath)
|
||||
{
|
||||
return (u64) last_write_time(ToPath(*rkFilePath)).time_since_epoch().count();
|
||||
}
|
||||
|
||||
TString WorkingDirectory()
|
||||
{
|
||||
return current_path().string();
|
||||
}
|
||||
|
||||
TString MakeAbsolute(TString Path)
|
||||
{
|
||||
if (!ToPath(*Path).has_root_name())
|
||||
Path = WorkingDirectory() + "/" + Path;
|
||||
|
||||
TStringList Components = Path.Split("/\\");
|
||||
TStringList::iterator Prev;
|
||||
|
||||
for (TStringList::iterator Iter = Components.begin(); Iter != Components.end(); Iter++)
|
||||
{
|
||||
if (*Iter == ".")
|
||||
Iter = Components.erase(Iter);
|
||||
else if (*Iter == "..")
|
||||
Iter = std::prev(Components.erase(Prev, std::next(Iter)));
|
||||
|
||||
Prev = Iter;
|
||||
}
|
||||
|
||||
TString Out;
|
||||
for (auto it = Components.begin(); it != Components.end(); it++)
|
||||
Out += *it + "/";
|
||||
|
||||
return Out;
|
||||
}
|
||||
|
||||
TString MakeRelative(const TString& rkPath, const TString& rkRelativeTo /*= WorkingDirectory()*/)
|
||||
{
|
||||
TString AbsPath = MakeAbsolute(rkPath);
|
||||
TString AbsRelTo = MakeAbsolute(rkRelativeTo);
|
||||
TStringList PathComponents = AbsPath.Split("/\\");
|
||||
TStringList RelToComponents = AbsRelTo.Split("/\\");
|
||||
|
||||
// Find furthest common parent
|
||||
TStringList::iterator PathIter = PathComponents.begin();
|
||||
TStringList::iterator RelToIter = RelToComponents.begin();
|
||||
|
||||
for (; PathIter != PathComponents.end() && RelToIter != RelToComponents.end(); PathIter++, RelToIter++)
|
||||
{
|
||||
if (*PathIter != *RelToIter)
|
||||
break;
|
||||
}
|
||||
|
||||
// If there's no common components, then we can't construct a relative path...
|
||||
if (PathIter == PathComponents.begin())
|
||||
return AbsPath;
|
||||
|
||||
// Construct output path
|
||||
TString Out;
|
||||
|
||||
for (; RelToIter != RelToComponents.end(); RelToIter++)
|
||||
Out += "../";
|
||||
|
||||
for (; PathIter != PathComponents.end(); PathIter++)
|
||||
Out += *PathIter + "/";
|
||||
|
||||
// Attempt to detect if this path is a file as opposed to a directory; if so, remove trailing backslash
|
||||
if (PathComponents.back().Contains('.') && !rkPath.EndsWith('/') && !rkPath.EndsWith('\\'))
|
||||
Out = Out.ChopBack(1);
|
||||
|
||||
return Out;
|
||||
}
|
||||
|
||||
TString SimplifyRelativePath(const TString& rkPath)
|
||||
{
|
||||
TStringList PathComponents = rkPath.Split("/\\");
|
||||
|
||||
TStringList::iterator Iter = PathComponents.begin();
|
||||
TStringList::iterator PrevIter = Iter;
|
||||
|
||||
for (auto Iter = PathComponents.begin(); Iter != PathComponents.end(); PrevIter = Iter, Iter++)
|
||||
{
|
||||
if (*Iter == ".." && *PrevIter != "..")
|
||||
{
|
||||
PrevIter = PathComponents.erase(PrevIter);
|
||||
PrevIter = PathComponents.erase(PrevIter);
|
||||
Iter = PrevIter;
|
||||
Iter--;
|
||||
}
|
||||
}
|
||||
|
||||
TString Out;
|
||||
|
||||
for (auto Iter = PathComponents.begin(); Iter != PathComponents.end(); Iter++)
|
||||
Out += *Iter + '/';
|
||||
|
||||
return Out;
|
||||
}
|
||||
|
||||
u32 MaxFileNameLength()
|
||||
{
|
||||
return 255;
|
||||
}
|
||||
|
||||
static const char gskIllegalNameChars[] = {
|
||||
'<', '>', '\"', '/', '\\', '|', '?', '*', ':'
|
||||
};
|
||||
|
||||
TString SanitizeName(TString Name, bool Directory, bool RootDir /*= false*/)
|
||||
{
|
||||
// Windows only atm
|
||||
if (Directory && (Name == "." || Name == ".."))
|
||||
return Name;
|
||||
|
||||
// Remove illegal characters from path
|
||||
for (u32 iChr = 0; iChr < Name.Size(); iChr++)
|
||||
{
|
||||
char Chr = Name[iChr];
|
||||
bool Remove = false;
|
||||
|
||||
if (Chr >= 0 && Chr <= 31)
|
||||
Remove = true;
|
||||
|
||||
// Allow colon only as the last character of root
|
||||
bool IsLegalColon = (Chr == ':' && RootDir && iChr == Name.Size() - 1);
|
||||
|
||||
if (!IsLegalColon && !IsValidFileNameCharacter(Chr))
|
||||
Remove = true;
|
||||
|
||||
if (Remove)
|
||||
{
|
||||
Name.Remove(iChr, 1);
|
||||
iChr--;
|
||||
}
|
||||
}
|
||||
|
||||
// For directories, space and dot are not allowed at the end of the path
|
||||
if (Directory)
|
||||
{
|
||||
u32 ChopNum = 0;
|
||||
|
||||
for (int iChr = (int) Name.Size() - 1; iChr >= 0; iChr--)
|
||||
{
|
||||
char Chr = Name[iChr];
|
||||
|
||||
if (Chr == ' ' || Chr == '.')
|
||||
ChopNum++;
|
||||
else
|
||||
break;
|
||||
}
|
||||
|
||||
if (ChopNum > 0) Name = Name.ChopBack(ChopNum);
|
||||
}
|
||||
|
||||
// Remove spaces from beginning of path
|
||||
u32 NumLeadingSpaces = 0;
|
||||
while (NumLeadingSpaces < Name.Size() && Name[NumLeadingSpaces] == ' ')
|
||||
NumLeadingSpaces++;
|
||||
|
||||
if (NumLeadingSpaces > 0)
|
||||
Name = Name.ChopFront(NumLeadingSpaces);
|
||||
|
||||
// Ensure the name is below the character limit
|
||||
if (Name.Size() > MaxFileNameLength())
|
||||
{
|
||||
u32 ChopNum = Name.Size() - MaxFileNameLength();
|
||||
Name = Name.ChopBack(ChopNum);
|
||||
}
|
||||
|
||||
return Name;
|
||||
}
|
||||
|
||||
TString SanitizePath(TString Path, bool Directory)
|
||||
{
|
||||
TStringList Components = Path.Split("\\/");
|
||||
u32 CompIdx = 0;
|
||||
Path = "";
|
||||
|
||||
for (auto It = Components.begin(); It != Components.end(); It++)
|
||||
{
|
||||
TString Comp = *It;
|
||||
bool IsDir = Directory || CompIdx < Components.size() - 1;
|
||||
bool IsRoot = CompIdx == 0;
|
||||
Comp = SanitizeName(Comp, IsDir, IsRoot);
|
||||
|
||||
Path += Comp;
|
||||
if (IsDir) Path += '/';
|
||||
CompIdx++;
|
||||
}
|
||||
|
||||
return Path;
|
||||
}
|
||||
|
||||
bool IsValidFileNameCharacter(char Chr)
|
||||
{
|
||||
static const u32 skNumIllegalChars = sizeof(gskIllegalNameChars) / sizeof(char);
|
||||
|
||||
if (Chr >= 0 && Chr <= 31)
|
||||
return false;
|
||||
|
||||
for (u32 BanIdx = 0; BanIdx < skNumIllegalChars; BanIdx++)
|
||||
{
|
||||
if (Chr == gskIllegalNameChars[BanIdx])
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool IsValidName(const TString& rkName, bool Directory, bool RootDir /*= false*/)
|
||||
{
|
||||
// Only accounting for Windows limitations right now. However, this function should
|
||||
// ideally return the same output on all platforms to ensure projects are cross platform.
|
||||
if (rkName.IsEmpty())
|
||||
return false;
|
||||
|
||||
if (rkName.Size() > MaxFileNameLength())
|
||||
return false;
|
||||
|
||||
if (Directory && (rkName == "." || rkName == ".."))
|
||||
return true;
|
||||
|
||||
// Check for banned characters
|
||||
for (u32 iChr = 0; iChr < rkName.Size(); iChr++)
|
||||
{
|
||||
char Chr = rkName[iChr];
|
||||
|
||||
// Allow colon only as the last character of root
|
||||
bool IsLegalColon = (Chr == ':' && RootDir && iChr == rkName.Size() - 1);
|
||||
|
||||
if (!IsLegalColon && !IsValidFileNameCharacter(Chr))
|
||||
return false;
|
||||
}
|
||||
|
||||
if (Directory && (rkName.Back() == ' ' || rkName.Back() == '.'))
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool IsValidPath(const TString& rkPath, bool Directory)
|
||||
{
|
||||
// Only accounting for Windows limitations right now. However, this function should
|
||||
// ideally return the same output on all platforms to ensure projects are cross platform.
|
||||
TStringList Components = rkPath.Split("\\/");
|
||||
|
||||
// Validate other components
|
||||
u32 CompIdx = 0;
|
||||
|
||||
for (auto It = Components.begin(); It != Components.end(); It++)
|
||||
{
|
||||
bool IsRoot = CompIdx == 0;
|
||||
bool IsDir = Directory || CompIdx < (Components.size() - 1);
|
||||
|
||||
if (!IsValidName(*It, IsDir, IsRoot))
|
||||
return false;
|
||||
|
||||
CompIdx++;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void GetDirectoryContents(TString DirPath, TStringList& rOut, bool Recursive /*= true*/, bool IncludeFiles /*= true*/, bool IncludeDirs /*= true*/)
|
||||
{
|
||||
if (IsDirectory(DirPath))
|
||||
{
|
||||
DirPath.Replace("\\", "/");
|
||||
bool IncludeAll = IncludeFiles && IncludeDirs;
|
||||
|
||||
auto AddFileLambda = [IncludeFiles, IncludeDirs, IncludeAll, &rOut](const TString& rkPath) -> void {
|
||||
bool ShouldAddFile = IncludeAll || (IncludeFiles && IsFile(rkPath)) || (IncludeDirs && IsDirectory(rkPath));
|
||||
|
||||
if (ShouldAddFile)
|
||||
rOut.push_back(rkPath);
|
||||
};
|
||||
|
||||
if (Recursive)
|
||||
{
|
||||
for (recursive_directory_iterator It(ToPath(*DirPath)); It != recursive_directory_iterator(); ++It)
|
||||
{
|
||||
AddFileLambda(It->path().string());
|
||||
}
|
||||
}
|
||||
|
||||
else
|
||||
{
|
||||
for (directory_iterator It(ToPath(*DirPath)); It != directory_iterator(); ++It)
|
||||
{
|
||||
AddFileLambda(It->path().string());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
TString FindFileExtension(const TString& rkDir, const TString& rkName)
|
||||
{
|
||||
for (directory_iterator It(ToPath(*rkDir)); It != directory_iterator(); ++It)
|
||||
{
|
||||
TString Name = It->path().filename().string();
|
||||
if (Name.GetFileName(false) == rkName) return Name.GetFileExtension();
|
||||
}
|
||||
|
||||
return "";
|
||||
}
|
||||
|
||||
bool LoadFileToString(const TString& rkFilePath, TString& rOut)
|
||||
{
|
||||
CFileInStream File(rkFilePath);
|
||||
|
||||
if (File.IsValid())
|
||||
{
|
||||
rOut = TString(File.Size());
|
||||
File.ReadBytes(&rOut[0], rOut.Size());
|
||||
return true;
|
||||
}
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
|
@ -1,44 +0,0 @@
|
|||
#ifndef FILEUTIL
|
||||
#define FILEUTIL
|
||||
|
||||
#include "Flags.h"
|
||||
#include "TString.h"
|
||||
|
||||
namespace FileUtil
|
||||
{
|
||||
|
||||
bool Exists(const TString& rkFilePath);
|
||||
bool IsRoot(const TString& rkPath);
|
||||
bool IsFile(const TString& rkFilePath);
|
||||
bool IsDirectory(const TString& rkDirPath);
|
||||
bool IsAbsolute(const TString& rkDirPath);
|
||||
bool IsRelative(const TString& rkDirPath);
|
||||
bool IsEmpty(const TString& rkDirPath);
|
||||
bool MakeDirectory(const TString& rkNewDir);
|
||||
bool CopyFile(const TString& rkOrigPath, const TString& rkNewPath);
|
||||
bool CopyDirectory(const TString& rkOrigPath, const TString& rkNewPath);
|
||||
bool MoveFile(const TString& rkOldPath, const TString& rkNewPath);
|
||||
bool MoveDirectory(const TString& rkOldPath, const TString& rkNewPath);
|
||||
bool DeleteFile(const TString& rkFilePath);
|
||||
bool DeleteDirectory(const TString& rkDirPath, bool FailIfNotEmpty); // This is an extremely destructive function, be careful using it!
|
||||
bool ClearDirectory(const TString& rkDirPath); // This is an extremely destructive function, be careful using it!
|
||||
u64 FileSize(const TString& rkFilePath);
|
||||
u64 LastModifiedTime(const TString& rkFilePath);
|
||||
TString WorkingDirectory();
|
||||
TString MakeAbsolute(TString Path);
|
||||
TString MakeRelative(const TString& rkPath, const TString& rkRelativeTo = WorkingDirectory());
|
||||
TString SimplifyRelativePath(const TString& rkPath);
|
||||
u32 MaxFileNameLength();
|
||||
TString SanitizeName(TString Name, bool Directory, bool RootDir = false);
|
||||
TString SanitizePath(TString Path, bool Directory);
|
||||
bool IsValidFileNameCharacter(char Chr);
|
||||
bool IsValidName(const TString& rkName, bool Directory, bool RootDir = false);
|
||||
bool IsValidPath(const TString& rkPath, bool Directory);
|
||||
void GetDirectoryContents(TString DirPath, TStringList& rOut, bool Recursive = true, bool IncludeFiles = true, bool IncludeDirs = true);
|
||||
TString FindFileExtension(const TString& rkDir, const TString& rkName);
|
||||
bool LoadFileToString(const TString& rkFilePath, TString& rOut);
|
||||
|
||||
}
|
||||
|
||||
#endif // FILEUTIL
|
||||
|
|
@ -1,62 +0,0 @@
|
|||
#ifndef FLAGS_H
|
||||
#define FLAGS_H
|
||||
|
||||
#include "types.h"
|
||||
#include "Common/Serialization/IArchive.h"
|
||||
|
||||
template<typename FlagEnum>
|
||||
class TFlags
|
||||
{
|
||||
u32 mValue;
|
||||
|
||||
public:
|
||||
TFlags() : mValue(0) {}
|
||||
TFlags(int Val) : mValue(Val) {}
|
||||
TFlags(u32 Val) : mValue(Val) {}
|
||||
TFlags(FlagEnum Val) : mValue((u32) Val) {}
|
||||
|
||||
inline operator int() const { return mValue; }
|
||||
inline bool operator!() const { return !mValue; }
|
||||
inline TFlags operator~() const { return TFlags(FlagEnum(~mValue)); }
|
||||
|
||||
inline void operator&=(int Mask) { mValue &= Mask; }
|
||||
inline void operator&=(u32 Mask) { mValue &= Mask; }
|
||||
inline void operator|=(TFlags Flags) { mValue |= Flags.mValue; }
|
||||
inline void operator|=(FlagEnum Flag) { mValue |= (u32) Flag; }
|
||||
|
||||
inline TFlags operator|(TFlags Flags) const { return TFlags(FlagEnum(mValue | Flags.mValue)); }
|
||||
inline TFlags operator|(FlagEnum Flag) const { return TFlags(FlagEnum(mValue | (u32) Flag)); }
|
||||
inline TFlags operator&(int Mask) const { return TFlags(FlagEnum(mValue & Mask)); }
|
||||
inline TFlags operator&(u32 Mask) const { return TFlags(FlagEnum(mValue & Mask)); }
|
||||
inline TFlags operator&(FlagEnum Flag) const { return TFlags(FlagEnum(mValue & (u32) Flag)); }
|
||||
|
||||
inline bool HasFlag(FlagEnum Flag) const { return ((mValue & (u32) Flag) != 0); }
|
||||
inline bool HasAnyFlags(TFlags Flags) const { return ((mValue & Flags) != 0); }
|
||||
inline bool HasAllFlags(TFlags Flags) const { return ((mValue & Flags) == Flags); }
|
||||
inline void SetFlag(FlagEnum Flag) { mValue |= (u32) Flag; }
|
||||
inline void SetFlag(TFlags Flags) { mValue |= Flags; }
|
||||
inline void ClearFlag(FlagEnum Flag) { mValue &= ~((u32) Flag); }
|
||||
inline void ClearFlag(TFlags Flags) { mValue &= ~Flags; }
|
||||
|
||||
inline void Serialize(IArchive& rArc) { rArc.SerializePrimitive(mValue, SH_HexDisplay); }
|
||||
};
|
||||
#define DECLARE_FLAGS(Enum, FlagTypeName) typedef TFlags<Enum> FlagTypeName;
|
||||
|
||||
// Alternate version for enum class flags
|
||||
#define DECLARE_FLAGS_ENUMCLASS(Enum, FlagTypeName) \
|
||||
DECLARE_FLAGS(Enum, FlagTypeName) \
|
||||
inline int operator|(Enum Left, Enum Right) \
|
||||
{ \
|
||||
return (int) Left | (int) Right; \
|
||||
} \
|
||||
inline int operator&(Enum Left, Enum Right) \
|
||||
{ \
|
||||
return (int) Left & (int) Right; \
|
||||
} \
|
||||
inline int operator~(Enum Value) \
|
||||
{ \
|
||||
return ~((int) Value); \
|
||||
} \
|
||||
|
||||
#endif // FLAGS_H
|
||||
|
|
@ -1,128 +0,0 @@
|
|||
#include "CCRC32.h"
|
||||
|
||||
const u32 gkCrcTable[] = {
|
||||
0x00000000, 0x77073096, 0xee0e612c, 0x990951ba, 0x076dc419, 0x706af48f,
|
||||
0xe963a535, 0x9e6495a3, 0x0edb8832, 0x79dcb8a4, 0xe0d5e91e, 0x97d2d988,
|
||||
0x09b64c2b, 0x7eb17cbd, 0xe7b82d07, 0x90bf1d91, 0x1db71064, 0x6ab020f2,
|
||||
0xf3b97148, 0x84be41de, 0x1adad47d, 0x6ddde4eb, 0xf4d4b551, 0x83d385c7,
|
||||
0x136c9856, 0x646ba8c0, 0xfd62f97a, 0x8a65c9ec, 0x14015c4f, 0x63066cd9,
|
||||
0xfa0f3d63, 0x8d080df5, 0x3b6e20c8, 0x4c69105e, 0xd56041e4, 0xa2677172,
|
||||
0x3c03e4d1, 0x4b04d447, 0xd20d85fd, 0xa50ab56b, 0x35b5a8fa, 0x42b2986c,
|
||||
0xdbbbc9d6, 0xacbcf940, 0x32d86ce3, 0x45df5c75, 0xdcd60dcf, 0xabd13d59,
|
||||
0x26d930ac, 0x51de003a, 0xc8d75180, 0xbfd06116, 0x21b4f4b5, 0x56b3c423,
|
||||
0xcfba9599, 0xb8bda50f, 0x2802b89e, 0x5f058808, 0xc60cd9b2, 0xb10be924,
|
||||
0x2f6f7c87, 0x58684c11, 0xc1611dab, 0xb6662d3d, 0x76dc4190, 0x01db7106,
|
||||
0x98d220bc, 0xefd5102a, 0x71b18589, 0x06b6b51f, 0x9fbfe4a5, 0xe8b8d433,
|
||||
0x7807c9a2, 0x0f00f934, 0x9609a88e, 0xe10e9818, 0x7f6a0dbb, 0x086d3d2d,
|
||||
0x91646c97, 0xe6635c01, 0x6b6b51f4, 0x1c6c6162, 0x856530d8, 0xf262004e,
|
||||
0x6c0695ed, 0x1b01a57b, 0x8208f4c1, 0xf50fc457, 0x65b0d9c6, 0x12b7e950,
|
||||
0x8bbeb8ea, 0xfcb9887c, 0x62dd1ddf, 0x15da2d49, 0x8cd37cf3, 0xfbd44c65,
|
||||
0x4db26158, 0x3ab551ce, 0xa3bc0074, 0xd4bb30e2, 0x4adfa541, 0x3dd895d7,
|
||||
0xa4d1c46d, 0xd3d6f4fb, 0x4369e96a, 0x346ed9fc, 0xad678846, 0xda60b8d0,
|
||||
0x44042d73, 0x33031de5, 0xaa0a4c5f, 0xdd0d7cc9, 0x5005713c, 0x270241aa,
|
||||
0xbe0b1010, 0xc90c2086, 0x5768b525, 0x206f85b3, 0xb966d409, 0xce61e49f,
|
||||
0x5edef90e, 0x29d9c998, 0xb0d09822, 0xc7d7a8b4, 0x59b33d17, 0x2eb40d81,
|
||||
0xb7bd5c3b, 0xc0ba6cad, 0xedb88320, 0x9abfb3b6, 0x03b6e20c, 0x74b1d29a,
|
||||
0xead54739, 0x9dd277af, 0x04db2615, 0x73dc1683, 0xe3630b12, 0x94643b84,
|
||||
0x0d6d6a3e, 0x7a6a5aa8, 0xe40ecf0b, 0x9309ff9d, 0x0a00ae27, 0x7d079eb1,
|
||||
0xf00f9344, 0x8708a3d2, 0x1e01f268, 0x6906c2fe, 0xf762575d, 0x806567cb,
|
||||
0x196c3671, 0x6e6b06e7, 0xfed41b76, 0x89d32be0, 0x10da7a5a, 0x67dd4acc,
|
||||
0xf9b9df6f, 0x8ebeeff9, 0x17b7be43, 0x60b08ed5, 0xd6d6a3e8, 0xa1d1937e,
|
||||
0x38d8c2c4, 0x4fdff252, 0xd1bb67f1, 0xa6bc5767, 0x3fb506dd, 0x48b2364b,
|
||||
0xd80d2bda, 0xaf0a1b4c, 0x36034af6, 0x41047a60, 0xdf60efc3, 0xa867df55,
|
||||
0x316e8eef, 0x4669be79, 0xcb61b38c, 0xbc66831a, 0x256fd2a0, 0x5268e236,
|
||||
0xcc0c7795, 0xbb0b4703, 0x220216b9, 0x5505262f, 0xc5ba3bbe, 0xb2bd0b28,
|
||||
0x2bb45a92, 0x5cb36a04, 0xc2d7ffa7, 0xb5d0cf31, 0x2cd99e8b, 0x5bdeae1d,
|
||||
0x9b64c2b0, 0xec63f226, 0x756aa39c, 0x026d930a, 0x9c0906a9, 0xeb0e363f,
|
||||
0x72076785, 0x05005713, 0x95bf4a82, 0xe2b87a14, 0x7bb12bae, 0x0cb61b38,
|
||||
0x92d28e9b, 0xe5d5be0d, 0x7cdcefb7, 0x0bdbdf21, 0x86d3d2d4, 0xf1d4e242,
|
||||
0x68ddb3f8, 0x1fda836e, 0x81be16cd, 0xf6b9265b, 0x6fb077e1, 0x18b74777,
|
||||
0x88085ae6, 0xff0f6a70, 0x66063bca, 0x11010b5c, 0x8f659eff, 0xf862ae69,
|
||||
0x616bffd3, 0x166ccf45, 0xa00ae278, 0xd70dd2ee, 0x4e048354, 0x3903b3c2,
|
||||
0xa7672661, 0xd06016f7, 0x4969474d, 0x3e6e77db, 0xaed16a4a, 0xd9d65adc,
|
||||
0x40df0b66, 0x37d83bf0, 0xa9bcae53, 0xdebb9ec5, 0x47b2cf7f, 0x30b5ffe9,
|
||||
0xbdbdf21c, 0xcabac28a, 0x53b39330, 0x24b4a3a6, 0xbad03605, 0xcdd70693,
|
||||
0x54de5729, 0x23d967bf, 0xb3667a2e, 0xc4614ab8, 0x5d681b02, 0x2a6f2b94,
|
||||
0xb40bbe37, 0xc30c8ea1, 0x5a05df1b, 0x2d02ef8d
|
||||
};
|
||||
|
||||
/** Default constructor, initializes the hash to the default value */
|
||||
CCRC32::CCRC32()
|
||||
: mHash( 0xFFFFFFFF )
|
||||
{
|
||||
}
|
||||
|
||||
/** Allows the hash to be initialized to an arbitrary value */
|
||||
CCRC32::CCRC32(u32 InitialValue)
|
||||
: mHash( InitialValue )
|
||||
{
|
||||
}
|
||||
|
||||
/** Hash arbitrary data */
|
||||
void CCRC32::Hash(const void* pkData, int Size)
|
||||
{
|
||||
const u8* pkCastData = static_cast<const u8*>(pkData);
|
||||
|
||||
while (Size--)
|
||||
{
|
||||
mHash = gkCrcTable[(mHash ^ *pkCastData++) & 0xFF] ^ (mHash >> 8);
|
||||
}
|
||||
}
|
||||
|
||||
/** Retrieve the final output hash. (You can keep adding data to the hash after calling this.) */
|
||||
u32 CCRC32::Digest() const
|
||||
{
|
||||
return mHash;
|
||||
}
|
||||
|
||||
/** Convenience hash methods */
|
||||
void CCRC32::Hash(u8 v)
|
||||
{
|
||||
Hash(&v, 1);
|
||||
}
|
||||
|
||||
void CCRC32::Hash(u16 v)
|
||||
{
|
||||
Hash(&v, 2);
|
||||
}
|
||||
|
||||
void CCRC32::Hash(u32 v)
|
||||
{
|
||||
Hash(&v, 4);
|
||||
}
|
||||
|
||||
void CCRC32::Hash(u64 v)
|
||||
{
|
||||
Hash(&v, 8);
|
||||
}
|
||||
|
||||
void CCRC32::Hash(float v)
|
||||
{
|
||||
Hash(&v, 4);
|
||||
}
|
||||
|
||||
void CCRC32::Hash(double v)
|
||||
{
|
||||
Hash(&v, 8);
|
||||
}
|
||||
|
||||
void CCRC32::Hash(char v)
|
||||
{
|
||||
Hash(&v, 1);
|
||||
}
|
||||
|
||||
void CCRC32::Hash(const char* pkString)
|
||||
{
|
||||
while (*pkString)
|
||||
{
|
||||
Hash(pkString++, 1);
|
||||
}
|
||||
}
|
||||
|
||||
/** Static */
|
||||
u32 CCRC32::StaticHashString(const char* pkString)
|
||||
{
|
||||
CCRC32 Hasher;
|
||||
Hasher.Hash(pkString);
|
||||
return Hasher.Digest();
|
||||
}
|
|
@ -1,41 +0,0 @@
|
|||
#ifndef CCRC32_H
|
||||
#define CCRC32_H
|
||||
|
||||
#include "Common/TString.h"
|
||||
#include "Common/types.h"
|
||||
|
||||
/**
|
||||
* CRC32 hash implementation
|
||||
*/
|
||||
class CCRC32
|
||||
{
|
||||
/** Current hash value */
|
||||
u32 mHash;
|
||||
|
||||
public:
|
||||
/** Default constructor, initializes the hash to the default value */
|
||||
CCRC32();
|
||||
|
||||
/** Allows the hash to be initialized to an arbitrary value */
|
||||
CCRC32(u32 InitialValue);
|
||||
|
||||
/** Hash arbitrary data */
|
||||
void Hash(const void* pkData, int Size);
|
||||
|
||||
/** Retrieve the final output hash. (You can keep adding data to the hash after calling this.) */
|
||||
u32 Digest() const;
|
||||
|
||||
/** Convenience hash methods */
|
||||
void Hash(u8 v);
|
||||
void Hash(u16 v);
|
||||
void Hash(u32 v);
|
||||
void Hash(u64 v);
|
||||
void Hash(float v);
|
||||
void Hash(double v);
|
||||
void Hash(char v);
|
||||
void Hash(const char* pkString);
|
||||
|
||||
static u32 StaticHashString(const char* pkString);
|
||||
};
|
||||
|
||||
#endif // CCRC32_H
|
|
@ -1,68 +0,0 @@
|
|||
#ifndef CFNV1A_H
|
||||
#define CFNV1A_H
|
||||
|
||||
#include "Common/types.h"
|
||||
#include "Common/TString.h"
|
||||
|
||||
class CFNV1A
|
||||
{
|
||||
public:
|
||||
enum EHashLength {
|
||||
e32Bit, e64Bit
|
||||
};
|
||||
|
||||
private:
|
||||
u64 mHash;
|
||||
EHashLength mHashLength;
|
||||
|
||||
static const u64 skFNVOffsetBasis32 = 0x811C9DC5;
|
||||
static const u64 skFNVOffsetBasis64 = 0xCBF29CE484222325;
|
||||
static const u64 skFNVPrime32 = 0x1000193;
|
||||
static const u64 skFNVPrime64 = 0x100000001B3;
|
||||
|
||||
public:
|
||||
CFNV1A(EHashLength Length)
|
||||
{
|
||||
if (Length == e32Bit)
|
||||
Init32();
|
||||
else
|
||||
Init64();
|
||||
}
|
||||
|
||||
void Init32()
|
||||
{
|
||||
mHashLength = e32Bit;
|
||||
mHash = skFNVOffsetBasis32;
|
||||
}
|
||||
|
||||
void Init64()
|
||||
{
|
||||
mHashLength = e64Bit;
|
||||
mHash = skFNVOffsetBasis64;
|
||||
}
|
||||
|
||||
void HashData(const void *pkData, u32 Size)
|
||||
{
|
||||
const char *pkCharData = (const char*) pkData;
|
||||
u64 FNVPrime = (mHashLength == e32Bit) ? skFNVPrime32 : skFNVPrime64;
|
||||
|
||||
for (u32 iByte = 0; iByte < Size; iByte++)
|
||||
{
|
||||
mHash ^= *pkCharData;
|
||||
mHash *= FNVPrime;
|
||||
pkCharData++;
|
||||
}
|
||||
}
|
||||
|
||||
inline u32 GetHash32() { return (u32) mHash; }
|
||||
inline u64 GetHash64() { return mHash; }
|
||||
|
||||
// Convenience functions
|
||||
inline void HashByte(const u8& rkVal) { HashData(&rkVal, 1); }
|
||||
inline void HashShort(const u16& rkVal) { HashData(&rkVal, 2); }
|
||||
inline void HashLong(const u32& rkVal) { HashData(&rkVal, 4); }
|
||||
inline void HashFloat(const float& rkVal) { HashData(&rkVal, 4); }
|
||||
inline void HashString(const TString& rkVal) { HashData(rkVal.Data(), rkVal.Size()); }
|
||||
};
|
||||
|
||||
#endif // CFNV1A_H
|
|
@ -1,150 +0,0 @@
|
|||
#include "CTimer.h"
|
||||
#include "Log.h"
|
||||
#include "TString.h"
|
||||
|
||||
#include <ctime>
|
||||
#include <iostream>
|
||||
|
||||
namespace Log
|
||||
{
|
||||
|
||||
TStringList gErrorLog;
|
||||
TString gLogFilename;
|
||||
FILE *gpLogFile;
|
||||
|
||||
double gAppStartTime = CTimer::GlobalTime();
|
||||
|
||||
bool gInitialized = false;
|
||||
TStringList gPreInitLogs;
|
||||
|
||||
bool InitLog(const TString& rkFilename)
|
||||
{
|
||||
fopen_s(&gpLogFile, *rkFilename, "w");
|
||||
gLogFilename = rkFilename;
|
||||
|
||||
if (!gpLogFile)
|
||||
{
|
||||
TString FileName = rkFilename.GetFileName(false);
|
||||
TString Extension = rkFilename.GetFileExtension();
|
||||
int Num = 0;
|
||||
|
||||
while (!gpLogFile)
|
||||
{
|
||||
if (Num > 999) break;
|
||||
TString NewFilename = FileName + "_" + TString::FromInt32(Num, 0, 10) + "." + Extension;
|
||||
fopen_s(&gpLogFile, *NewFilename, "w");
|
||||
Num++;
|
||||
}
|
||||
|
||||
if (!gpLogFile)
|
||||
return false;
|
||||
}
|
||||
|
||||
// Print initial message to log
|
||||
time_t RawTime;
|
||||
time(&RawTime);
|
||||
|
||||
tm pTimeInfo;
|
||||
localtime_s(&pTimeInfo, &RawTime);
|
||||
|
||||
char Buffer[80];
|
||||
strftime(Buffer, 80, "%m/%d/%y %H:%M:%S", &pTimeInfo);
|
||||
|
||||
fprintf(gpLogFile, "Opened log file at %s\n", Buffer);
|
||||
fflush(gpLogFile);
|
||||
|
||||
#ifdef APP_FULL_NAME
|
||||
// Print app name and version
|
||||
fprintf(gpLogFile, APP_FULL_NAME"\n");
|
||||
#endif
|
||||
|
||||
// Print any messages that were attempted before we initialized
|
||||
if (!gPreInitLogs.empty())
|
||||
{
|
||||
for (auto it = gPreInitLogs.begin(); it != gPreInitLogs.end(); it++)
|
||||
Write(*it);
|
||||
}
|
||||
|
||||
gInitialized = true;
|
||||
return true;
|
||||
}
|
||||
|
||||
void Write(const TString& rkMessage)
|
||||
{
|
||||
double Time = CTimer::GlobalTime() - gAppStartTime;
|
||||
|
||||
if (!gInitialized)
|
||||
gPreInitLogs.push_back(rkMessage);
|
||||
|
||||
else if (gpLogFile)
|
||||
{
|
||||
fprintf(gpLogFile, "[%08.3f] %s\n", Time, *rkMessage);
|
||||
fflush(gpLogFile);
|
||||
}
|
||||
|
||||
std::cout << std::fixed << std::setprecision(3)
|
||||
<< "[" << Time << "] " << rkMessage << "\n";
|
||||
}
|
||||
|
||||
void Error(const TString& rkMessage)
|
||||
{
|
||||
TString FullMessage = "ERROR: " + rkMessage;
|
||||
Write(FullMessage);
|
||||
gErrorLog.push_back(FullMessage);
|
||||
}
|
||||
|
||||
void Warning(const TString& rkMessage)
|
||||
{
|
||||
TString FullMessage = "Warning: " + rkMessage;
|
||||
Write(FullMessage);
|
||||
gErrorLog.push_back(FullMessage);
|
||||
}
|
||||
|
||||
void Fatal(const TString& rkMessage)
|
||||
{
|
||||
TString FullMessage = "FATAL ERROR: " + rkMessage;
|
||||
Write(FullMessage);
|
||||
abort();
|
||||
}
|
||||
|
||||
void FileWrite(const TString& rkFilename, const TString& rkMessage)
|
||||
{
|
||||
Write(rkFilename + " : " + rkMessage);
|
||||
}
|
||||
|
||||
void FileWrite(const TString& rkFilename, u32 Offset, const TString& rkMessage)
|
||||
{
|
||||
Write(rkFilename + " : " + TString::HexString(Offset, 0) + " - " + rkMessage);
|
||||
}
|
||||
|
||||
void FileError(const TString& rkFilename, const TString& rkMessage)
|
||||
{
|
||||
Error(rkFilename + " : " + rkMessage);
|
||||
}
|
||||
|
||||
void FileError(const TString& rkFilename, u32 Offset, const TString& rkMessage)
|
||||
{
|
||||
Error(rkFilename + " : " + TString::HexString(Offset, 0) + " - " + rkMessage);
|
||||
}
|
||||
|
||||
void FileWarning(const TString& rkFilename, const TString& rkMessage)
|
||||
{
|
||||
Warning(rkFilename + " : " + rkMessage);
|
||||
}
|
||||
|
||||
void FileWarning(const TString& rkFilename, u32 Offset, const TString& rkMessage)
|
||||
{
|
||||
Warning(rkFilename + " : " + TString::HexString(Offset, 0) + " - " + rkMessage);
|
||||
}
|
||||
|
||||
const TStringList& GetErrorLog()
|
||||
{
|
||||
return gErrorLog;
|
||||
}
|
||||
|
||||
void ClearErrorLog()
|
||||
{
|
||||
gErrorLog.clear();
|
||||
}
|
||||
|
||||
}
|
|
@ -1,26 +0,0 @@
|
|||
#ifndef INFO
|
||||
#define INFO
|
||||
|
||||
#include <Common/TString.h>
|
||||
|
||||
namespace Log
|
||||
{
|
||||
|
||||
bool InitLog(const TString& rkFilename);
|
||||
void Write(const TString& rkMessage);
|
||||
void Error(const TString& rkMessage);
|
||||
void Warning(const TString& rkMessage);
|
||||
void Fatal(const TString& rkMessage);
|
||||
void FileWrite(const TString& rkFilename, const TString& rkMessage);
|
||||
void FileWrite(const TString& rkFilename, unsigned long Offset, const TString& rkMessage);
|
||||
void FileError(const TString& rkFilename, const TString& rkMessage);
|
||||
void FileError(const TString& rkFilename, unsigned long Offset, const TString& rkMessage);
|
||||
void FileWarning(const TString& rkFilename, const TString& rkMessage);
|
||||
void FileWarning(const TString& rkFilename, unsigned long Offset, const TString& rkMessage);
|
||||
const TStringList& GetErrorLog();
|
||||
void ClearErrorLog();
|
||||
|
||||
}
|
||||
|
||||
#endif // INFO
|
||||
|
|
@ -1,97 +0,0 @@
|
|||
#ifndef NBASICS_H
|
||||
#define NBASICS_H
|
||||
|
||||
#include "types.h"
|
||||
#include <vector>
|
||||
|
||||
namespace NBasics
|
||||
{
|
||||
|
||||
/** Remove an element from a container */
|
||||
template<typename T, typename ContainerT>
|
||||
bool ContainerRemoveOne(ContainerT& Container, const T& kElement)
|
||||
{
|
||||
for (auto Iter = Container.begin(); Iter != Container.end(); Iter++)
|
||||
{
|
||||
if (*Iter == kElement)
|
||||
{
|
||||
Container.erase(Iter);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
inline bool VectorRemoveOne(std::vector<T>& Vector, const T& kElement)
|
||||
{
|
||||
return ContainerRemoveOne< T, std::vector<T> >(Vector, kElement);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
inline bool ListRemoveOne(std::list<T>& List, const T& kElement)
|
||||
{
|
||||
return ContainerRemoveOne< T, std::list<T> >(List, kElement);
|
||||
}
|
||||
|
||||
/** Remove all occurrences of an element from a container. Returns the number of elements that were removed. */
|
||||
template<typename T, typename ContainerT>
|
||||
int ContainerRemoveAll(ContainerT& Container, const T& kElement)
|
||||
{
|
||||
int NumRemoved = 0;
|
||||
|
||||
for (auto Iter = Container.begin(); Iter != Container.end(); Iter++)
|
||||
{
|
||||
if (*Iter == kElement)
|
||||
{
|
||||
Iter = Container.erase(Iter);
|
||||
NumRemoved++;
|
||||
}
|
||||
}
|
||||
|
||||
return NumRemoved;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
inline int VectorRemoveAll(std::vector<T>& Vector, const T& kElement)
|
||||
{
|
||||
return ContainerRemoveAll< T, std::vector<T> >(Vector, kElement);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
inline int ListRemoveAll(std::list<T>& List, const T& kElement)
|
||||
{
|
||||
return ContainerRemoveAll< T, std::list<T> >(List, kElement);
|
||||
}
|
||||
|
||||
/** Returns whether the vector contains the given element */
|
||||
template<typename T>
|
||||
bool VectorContains(std::vector<T>& Vector, const T& kElement)
|
||||
{
|
||||
for (auto Iter = Vector.begin(); Iter != Vector.end(); Iter++)
|
||||
{
|
||||
if (*Iter == kElement)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/** Adds an element to a vector only if it is not already present */
|
||||
template<typename T>
|
||||
bool VectorAddUnique(std::vector<T>& Vector, const T& kElement)
|
||||
{
|
||||
if (!VectorContains(Vector, kElement))
|
||||
{
|
||||
Vector.push_back(kElement);
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#endif // NBASICS_H
|
|
@ -1,5 +0,0 @@
|
|||
#include "IArchive.h"
|
||||
#include "CBinaryReader.h"
|
||||
#include "CBinaryWriter.h"
|
||||
#include "CBasicBinaryReader.h"
|
||||
#include "CBasicBinaryWriter.h"
|
|
@ -1,93 +0,0 @@
|
|||
#ifndef CBASICBINARYREADER
|
||||
#define CBASICBINARYREADER
|
||||
|
||||
#include "IArchive.h"
|
||||
#include "CSerialVersion.h"
|
||||
#include "Common/CFourCC.h"
|
||||
#include "Common/FileIO/IInputStream.h"
|
||||
|
||||
// This is a basic binary reader that doesn't do any checks on parameter names.
|
||||
// This is the fastest serializer, but it relies entirely on parameter order so
|
||||
// changes to file structure will break old versions of the file. Use carefully!
|
||||
class CBasicBinaryReader : public IArchive
|
||||
{
|
||||
IInputStream *mpStream;
|
||||
bool mMagicValid;
|
||||
bool mOwnsStream;
|
||||
|
||||
public:
|
||||
CBasicBinaryReader(const TString& rkFilename, u32 Magic)
|
||||
: IArchive()
|
||||
, mOwnsStream(true)
|
||||
{
|
||||
mArchiveFlags = AF_Binary | AF_Reader | AF_NoSkipping;
|
||||
mpStream = new CFileInStream(rkFilename, IOUtil::eBigEndian);
|
||||
|
||||
if (mpStream->IsValid())
|
||||
{
|
||||
mMagicValid = (mpStream->ReadLong() == Magic);
|
||||
SerializeVersion();
|
||||
}
|
||||
}
|
||||
|
||||
CBasicBinaryReader(IInputStream *pStream, const CSerialVersion& rkVersion)
|
||||
: IArchive()
|
||||
, mMagicValid(true)
|
||||
, mOwnsStream(false)
|
||||
{
|
||||
mArchiveFlags = AF_Binary | AF_Reader | AF_NoSkipping;
|
||||
|
||||
ASSERT(pStream->IsValid());
|
||||
mpStream = pStream;
|
||||
SetVersion(rkVersion);
|
||||
}
|
||||
|
||||
CBasicBinaryReader(void *pData, u32 DataSize, const CSerialVersion& rkVersion, IOUtil::EEndianness Endian = IOUtil::kSystemEndianness)
|
||||
: IArchive()
|
||||
, mMagicValid(true)
|
||||
, mOwnsStream(true)
|
||||
{
|
||||
mArchiveFlags = AF_Binary | AF_Reader | AF_NoSkipping;
|
||||
mpStream = new CMemoryInStream(pData, DataSize, Endian);
|
||||
SetVersion(rkVersion);
|
||||
}
|
||||
|
||||
~CBasicBinaryReader()
|
||||
{
|
||||
if (mOwnsStream) delete mpStream;
|
||||
}
|
||||
|
||||
inline bool IsValid() const { return mpStream->IsValid(); }
|
||||
|
||||
// Interface
|
||||
virtual bool IsReader() const { return true; }
|
||||
virtual bool IsWriter() const { return false; }
|
||||
virtual bool IsTextFormat() const { return false; }
|
||||
|
||||
virtual bool ParamBegin(const char*, u32) { return true; }
|
||||
virtual void ParamEnd() { }
|
||||
|
||||
virtual bool PreSerializePointer(void*& Pointer, u32 Flags) { return ArchiveVersion() >= eArVer_Refactor ? mpStream->ReadBool() : true; }
|
||||
virtual void SerializeContainerSize(u32& rSize, const TString&, u32 Flags) { SerializePrimitive(rSize, Flags); }
|
||||
virtual void SerializeBulkData(void* pData, u32 Size, u32 Flags) { mpStream->ReadBytes(pData, Size); }
|
||||
|
||||
virtual void SerializePrimitive(bool& rValue, u32 Flags) { rValue = mpStream->ReadBool(); }
|
||||
virtual void SerializePrimitive(char& rValue, u32 Flags) { rValue = mpStream->ReadByte(); }
|
||||
virtual void SerializePrimitive(s8& rValue, u32 Flags) { rValue = mpStream->ReadByte(); }
|
||||
virtual void SerializePrimitive(u8& rValue, u32 Flags) { rValue = mpStream->ReadByte(); }
|
||||
virtual void SerializePrimitive(s16& rValue, u32 Flags) { rValue = mpStream->ReadShort(); }
|
||||
virtual void SerializePrimitive(u16& rValue, u32 Flags) { rValue = mpStream->ReadShort(); }
|
||||
virtual void SerializePrimitive(s32& rValue, u32 Flags) { rValue = mpStream->ReadLong(); }
|
||||
virtual void SerializePrimitive(u32& rValue, u32 Flags) { rValue = mpStream->ReadLong(); }
|
||||
virtual void SerializePrimitive(s64& rValue, u32 Flags) { rValue = mpStream->ReadLongLong(); }
|
||||
virtual void SerializePrimitive(u64& rValue, u32 Flags) { rValue = mpStream->ReadLongLong(); }
|
||||
virtual void SerializePrimitive(float& rValue, u32 Flags) { rValue = mpStream->ReadFloat(); }
|
||||
virtual void SerializePrimitive(double& rValue, u32 Flags) { rValue = mpStream->ReadDouble(); }
|
||||
virtual void SerializePrimitive(TString& rValue, u32 Flags) { rValue = mpStream->ReadSizedString(); }
|
||||
virtual void SerializePrimitive(TWideString& rValue, u32 Flags) { rValue = mpStream->ReadSizedWString(); }
|
||||
virtual void SerializePrimitive(CFourCC& rValue, u32 Flags) { rValue = CFourCC(*mpStream); }
|
||||
virtual void SerializePrimitive(CAssetID& rValue, u32 Flags) { rValue = CAssetID(*mpStream, mGame); }
|
||||
};
|
||||
|
||||
#endif // CBASICBINARYREADER
|
||||
|
|
@ -1,104 +0,0 @@
|
|||
#ifndef CBASICBINARYWRITER
|
||||
#define CBASICBINARYWRITER
|
||||
|
||||
#include "IArchive.h"
|
||||
#include "Common/CFourCC.h"
|
||||
#include "Common/FileIO/IOutputStream.h"
|
||||
|
||||
// This is a basic binary reader that doesn't do any checks on parameter names.
|
||||
// This is the fastest serializer, but it relies entirely on parameter order so
|
||||
// changes to file structure will break old versions of the file. Use carefully!
|
||||
class CBasicBinaryWriter : public IArchive
|
||||
{
|
||||
IOutputStream *mpStream;
|
||||
u32 mMagic;
|
||||
bool mOwnsStream;
|
||||
|
||||
public:
|
||||
CBasicBinaryWriter(const TString& rkFilename, u32 Magic, u16 FileVersion, EGame Game)
|
||||
: IArchive()
|
||||
, mMagic(Magic)
|
||||
, mOwnsStream(true)
|
||||
{
|
||||
mArchiveFlags = AF_Binary | AF_Writer | AF_NoSkipping;
|
||||
mpStream = new CFileOutStream(rkFilename, IOUtil::eBigEndian);
|
||||
|
||||
if (mpStream->IsValid())
|
||||
{
|
||||
mpStream->WriteLong(0); // Magic is written after the rest of the file is successfully saved
|
||||
SetVersion(skCurrentArchiveVersion, FileVersion, Game);
|
||||
SerializeVersion();
|
||||
}
|
||||
}
|
||||
|
||||
CBasicBinaryWriter(IOutputStream *pStream, u16 FileVersion, EGame Game)
|
||||
: IArchive()
|
||||
, mOwnsStream(false)
|
||||
{
|
||||
ASSERT(pStream->IsValid());
|
||||
mArchiveFlags = AF_Binary | AF_Writer | AF_NoSkipping;
|
||||
mpStream = pStream;
|
||||
SetVersion(skCurrentArchiveVersion, FileVersion, Game);
|
||||
}
|
||||
|
||||
CBasicBinaryWriter(IOutputStream *pStream, const CSerialVersion& rkVersion)
|
||||
: IArchive()
|
||||
, mOwnsStream(false)
|
||||
{
|
||||
ASSERT(pStream->IsValid());
|
||||
mArchiveFlags = AF_Binary | AF_Writer | AF_NoSkipping;
|
||||
mpStream = pStream;
|
||||
SetVersion(rkVersion);
|
||||
}
|
||||
|
||||
~CBasicBinaryWriter()
|
||||
{
|
||||
// Write magic and delete stream
|
||||
if (mOwnsStream)
|
||||
{
|
||||
mpStream->GoTo(0);
|
||||
mpStream->WriteLong(mMagic);
|
||||
delete mpStream;
|
||||
}
|
||||
}
|
||||
|
||||
inline bool IsValid() const { return mpStream->IsValid(); }
|
||||
|
||||
// Interface
|
||||
virtual bool IsReader() const { return false; }
|
||||
virtual bool IsWriter() const { return true; }
|
||||
virtual bool IsTextFormat() const { return false; }
|
||||
|
||||
virtual bool ParamBegin(const char*, u32) { return true; }
|
||||
virtual void ParamEnd() { }
|
||||
|
||||
virtual bool PreSerializePointer(void*& Pointer, u32 Flags)
|
||||
{
|
||||
bool ValidPtr = (Pointer != nullptr);
|
||||
mpStream->WriteBool(ValidPtr);
|
||||
return ValidPtr;
|
||||
}
|
||||
|
||||
virtual void SerializeContainerSize(u32& rSize, const TString&) { mpStream->WriteLong(rSize); }
|
||||
|
||||
virtual void SerializePrimitive(bool& rValue, u32 Flags) { mpStream->WriteBool(rValue); }
|
||||
virtual void SerializePrimitive(char& rValue, u32 Flags) { mpStream->WriteByte(rValue); }
|
||||
virtual void SerializePrimitive(s8& rValue, u32 Flags) { mpStream->WriteByte(rValue); }
|
||||
virtual void SerializePrimitive(u8& rValue, u32 Flags) { mpStream->WriteByte(rValue); }
|
||||
virtual void SerializePrimitive(s16& rValue, u32 Flags) { mpStream->WriteShort(rValue); }
|
||||
virtual void SerializePrimitive(u16& rValue, u32 Flags) { mpStream->WriteShort(rValue); }
|
||||
virtual void SerializePrimitive(s32& rValue, u32 Flags) { mpStream->WriteLong(rValue); }
|
||||
virtual void SerializePrimitive(u32& rValue, u32 Flags) { mpStream->WriteLong(rValue); }
|
||||
virtual void SerializePrimitive(s64& rValue, u32 Flags) { mpStream->WriteLongLong(rValue); }
|
||||
virtual void SerializePrimitive(u64& rValue, u32 Flags) { mpStream->WriteLongLong(rValue); }
|
||||
virtual void SerializePrimitive(float& rValue, u32 Flags) { mpStream->WriteFloat(rValue); }
|
||||
virtual void SerializePrimitive(double& rValue, u32 Flags) { mpStream->WriteDouble(rValue); }
|
||||
virtual void SerializePrimitive(TString& rValue, u32 Flags) { mpStream->WriteSizedString(rValue); }
|
||||
virtual void SerializePrimitive(TWideString& rValue, u32 Flags) { mpStream->WriteSizedWString(rValue); }
|
||||
virtual void SerializePrimitive(CFourCC& rValue, u32 Flags) { rValue.Write(*mpStream); }
|
||||
virtual void SerializePrimitive(CAssetID& rValue, u32 Flags) { rValue.Write(*mpStream, CAssetID::GameIDLength(Game())); }
|
||||
virtual void SerializeBulkData(void* pData, u32 Size, u32 Flags) { mpStream->WriteBytes(pData, Size); }
|
||||
};
|
||||
|
||||
#endif // CBASICBINARYWRITER
|
||||
|
|
@ -1,188 +0,0 @@
|
|||
#ifndef CBINARYREADER
|
||||
#define CBINARYREADER
|
||||
|
||||
#include "IArchive.h"
|
||||
#include "CSerialVersion.h"
|
||||
#include "Common/CFourCC.h"
|
||||
|
||||
class CBinaryReader : public IArchive
|
||||
{
|
||||
struct SBinaryParm
|
||||
{
|
||||
u32 Offset;
|
||||
u32 Size;
|
||||
u32 NumChildren;
|
||||
u32 ChildIndex;
|
||||
};
|
||||
std::vector<SBinaryParm> mBinaryParmStack;
|
||||
|
||||
IInputStream *mpStream;
|
||||
bool mMagicValid;
|
||||
bool mOwnsStream;
|
||||
bool mInAttribute;
|
||||
|
||||
public:
|
||||
CBinaryReader(const TString& rkFilename, u32 Magic)
|
||||
: IArchive()
|
||||
, mOwnsStream(true)
|
||||
, mInAttribute(false)
|
||||
{
|
||||
mArchiveFlags = AF_Reader | AF_Binary;
|
||||
mpStream = new CFileInStream(rkFilename, IOUtil::eBigEndian);
|
||||
|
||||
if (mpStream->IsValid())
|
||||
{
|
||||
mMagicValid = (mpStream->ReadLong() == Magic);
|
||||
}
|
||||
|
||||
InitParamStack();
|
||||
SerializeVersion();
|
||||
}
|
||||
|
||||
CBinaryReader(IInputStream *pStream, const CSerialVersion& rkVersion)
|
||||
: IArchive()
|
||||
, mMagicValid(true)
|
||||
, mOwnsStream(false)
|
||||
, mInAttribute(false)
|
||||
{
|
||||
ASSERT(pStream && pStream->IsValid());
|
||||
mArchiveFlags = AF_Reader | AF_Binary;
|
||||
mpStream = pStream;
|
||||
SetVersion(rkVersion);
|
||||
|
||||
InitParamStack();
|
||||
}
|
||||
|
||||
~CBinaryReader()
|
||||
{
|
||||
if (mOwnsStream) delete mpStream;
|
||||
}
|
||||
|
||||
inline bool IsValid() const { return mpStream->IsValid() && mMagicValid; }
|
||||
|
||||
private:
|
||||
void InitParamStack()
|
||||
{
|
||||
mpStream->Skip(4); // Skip root ID (which is always -1)
|
||||
u32 Size = ReadSize();
|
||||
u32 Offset = mpStream->Tell();
|
||||
u32 NumChildren = ReadSize();
|
||||
mBinaryParmStack.push_back( SBinaryParm { Offset, Size, NumChildren, 0 } );
|
||||
mBinaryParmStack.reserve(20);
|
||||
}
|
||||
|
||||
public:
|
||||
// Interface
|
||||
u32 ReadSize()
|
||||
{
|
||||
return (mArchiveVersion < eArVer_32BitBinarySize ? (u32) mpStream->ReadShort() : mpStream->ReadLong());
|
||||
}
|
||||
|
||||
virtual bool ParamBegin(const char *pkName, u32 Flags)
|
||||
{
|
||||
// If this is the parent parameter's first child, then read the child count
|
||||
if (mBinaryParmStack.back().NumChildren == 0xFFFFFFFF)
|
||||
{
|
||||
mBinaryParmStack.back().NumChildren = ReadSize();
|
||||
}
|
||||
|
||||
// Save current offset
|
||||
u32 Offset = mpStream->Tell();
|
||||
u32 ParamID = TString(pkName).Hash32();
|
||||
|
||||
// Check the next parameter ID first and check whether it's a match for the current parameter
|
||||
if (mBinaryParmStack.back().ChildIndex < mBinaryParmStack.back().NumChildren)
|
||||
{
|
||||
u32 NextID = mpStream->ReadLong();
|
||||
u32 NextSize = ReadSize();
|
||||
|
||||
// Does the next parameter ID match the current one?
|
||||
if (NextID == ParamID || (Flags & SH_IgnoreName))
|
||||
{
|
||||
mBinaryParmStack.push_back( SBinaryParm { mpStream->Tell(), NextSize, 0xFFFFFFFF, 0 } );
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
// It's not a match - return to the parent parameter's first child and check all children to find a match
|
||||
if (!mBinaryParmStack.empty())
|
||||
{
|
||||
u32 ParentOffset = mBinaryParmStack.back().Offset;
|
||||
u32 NumChildren = mBinaryParmStack.back().NumChildren;
|
||||
mpStream->GoTo(ParentOffset);
|
||||
|
||||
for (u32 ChildIdx = 0; ChildIdx < NumChildren; ChildIdx++)
|
||||
{
|
||||
u32 ChildID = mpStream->ReadLong();
|
||||
u32 ChildSize = ReadSize();
|
||||
|
||||
if (ChildID != ParamID)
|
||||
mpStream->Skip(ChildSize);
|
||||
else
|
||||
{
|
||||
mBinaryParmStack.back().ChildIndex = ChildIdx;
|
||||
mBinaryParmStack.push_back( SBinaryParm { mpStream->Tell(), ChildSize, 0xFFFFFFFF, 0 } );
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// None of the children were a match - this parameter isn't in the file
|
||||
mpStream->GoTo(Offset);
|
||||
return false;
|
||||
}
|
||||
|
||||
virtual void ParamEnd()
|
||||
{
|
||||
// Make sure we're at the end of the parameter
|
||||
SBinaryParm& rParam = mBinaryParmStack.back();
|
||||
u32 EndOffset = rParam.Offset + rParam.Size;
|
||||
mpStream->GoTo(EndOffset);
|
||||
mBinaryParmStack.pop_back();
|
||||
|
||||
// Increment parent child index
|
||||
if (!mBinaryParmStack.empty())
|
||||
mBinaryParmStack.back().ChildIndex++;
|
||||
}
|
||||
|
||||
virtual bool PreSerializePointer(void*& Pointer, u32 Flags)
|
||||
{
|
||||
if (ArchiveVersion() >= eArVer_Refactor)
|
||||
{
|
||||
bool ValidPtr = (Pointer != nullptr);
|
||||
*this << SerialParameter("PointerValid", ValidPtr);
|
||||
return ValidPtr;
|
||||
}
|
||||
else
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
virtual void SerializeContainerSize(u32& rSize, const TString& /*rkElemName*/)
|
||||
{
|
||||
// Mostly handled by ParamBegin, we just need to return the size correctly so the container can be resized
|
||||
rSize = (mArchiveVersion < eArVer_32BitBinarySize ? (u32) mpStream->PeekShort() : mpStream->PeekLong());
|
||||
}
|
||||
|
||||
virtual void SerializePrimitive(bool& rValue, u32 Flags) { rValue = mpStream->ReadBool(); }
|
||||
virtual void SerializePrimitive(char& rValue, u32 Flags) { rValue = mpStream->ReadByte(); }
|
||||
virtual void SerializePrimitive(s8& rValue, u32 Flags) { rValue = mpStream->ReadByte(); }
|
||||
virtual void SerializePrimitive(u8& rValue, u32 Flags) { rValue = mpStream->ReadByte(); }
|
||||
virtual void SerializePrimitive(s16& rValue, u32 Flags) { rValue = mpStream->ReadShort(); }
|
||||
virtual void SerializePrimitive(u16& rValue, u32 Flags) { rValue = mpStream->ReadShort(); }
|
||||
virtual void SerializePrimitive(s32& rValue, u32 Flags) { rValue = mpStream->ReadLong(); }
|
||||
virtual void SerializePrimitive(u32& rValue, u32 Flags) { rValue = mpStream->ReadLong(); }
|
||||
virtual void SerializePrimitive(s64& rValue, u32 Flags) { rValue = mpStream->ReadLongLong(); }
|
||||
virtual void SerializePrimitive(u64& rValue, u32 Flags) { rValue = mpStream->ReadLongLong(); }
|
||||
virtual void SerializePrimitive(float& rValue, u32 Flags) { rValue = mpStream->ReadFloat(); }
|
||||
virtual void SerializePrimitive(double& rValue, u32 Flags) { rValue = mpStream->ReadDouble(); }
|
||||
virtual void SerializePrimitive(TString& rValue, u32 Flags) { rValue = mpStream->ReadSizedString(); }
|
||||
virtual void SerializePrimitive(TWideString& rValue, u32 Flags) { rValue = mpStream->ReadSizedWString(); }
|
||||
virtual void SerializePrimitive(CFourCC& rValue, u32 Flags) { rValue = CFourCC(*mpStream); }
|
||||
virtual void SerializePrimitive(CAssetID& rValue, u32 Flags) { rValue = CAssetID(*mpStream, Game()); }
|
||||
virtual void SerializeBulkData(void* pData, u32 Size, u32 Flags) { mpStream->ReadBytes(pData, Size); }
|
||||
};
|
||||
|
||||
#endif // CBINARYREADER
|
||||
|
|
@ -1,167 +0,0 @@
|
|||
#ifndef CBINARYWRITER
|
||||
#define CBINARYWRITER
|
||||
|
||||
#include "IArchive.h"
|
||||
#include "Common/CFourCC.h"
|
||||
|
||||
class CBinaryWriter : public IArchive
|
||||
{
|
||||
struct SParameter
|
||||
{
|
||||
u32 Offset;
|
||||
u32 NumSubParams;
|
||||
};
|
||||
std::vector<SParameter> mParamStack;
|
||||
|
||||
IOutputStream *mpStream;
|
||||
u32 mMagic;
|
||||
bool mOwnsStream;
|
||||
|
||||
public:
|
||||
CBinaryWriter(const TString& rkFilename, u32 Magic, u16 FileVersion = 0, EGame Game = EGame::Invalid)
|
||||
: IArchive()
|
||||
, mMagic(Magic)
|
||||
, mOwnsStream(true)
|
||||
{
|
||||
mArchiveFlags = AF_Writer | AF_Binary;
|
||||
mpStream = new CFileOutStream(rkFilename, IOUtil::eBigEndian);
|
||||
|
||||
if (mpStream->IsValid())
|
||||
{
|
||||
mpStream->WriteLong(0); // Magic is written after the rest of the file has been successfully written
|
||||
SetVersion(skCurrentArchiveVersion, FileVersion, Game);
|
||||
}
|
||||
|
||||
InitParamStack();
|
||||
SerializeVersion();
|
||||
}
|
||||
|
||||
CBinaryWriter(IOutputStream *pStream, u16 FileVersion = 0, EGame Game = EGame::Invalid)
|
||||
: IArchive()
|
||||
, mMagic(0)
|
||||
, mOwnsStream(false)
|
||||
{
|
||||
ASSERT(pStream && pStream->IsValid());
|
||||
mArchiveFlags = AF_Writer | AF_Binary;
|
||||
mpStream = pStream;
|
||||
SetVersion(skCurrentArchiveVersion, FileVersion, Game);
|
||||
InitParamStack();
|
||||
}
|
||||
|
||||
CBinaryWriter(IOutputStream *pStream, const CSerialVersion& rkVersion)
|
||||
: IArchive()
|
||||
, mMagic(0)
|
||||
, mOwnsStream(false)
|
||||
{
|
||||
ASSERT(pStream && pStream->IsValid());
|
||||
mArchiveFlags = AF_Writer | AF_Binary;
|
||||
mpStream = pStream;
|
||||
SetVersion(rkVersion);
|
||||
InitParamStack();
|
||||
}
|
||||
|
||||
~CBinaryWriter()
|
||||
{
|
||||
// Ensure all params have been finished
|
||||
ASSERT(mParamStack.size() == 1);
|
||||
|
||||
// Finish root param
|
||||
ParamEnd();
|
||||
|
||||
// Write magic and delete stream
|
||||
if (mOwnsStream)
|
||||
{
|
||||
mpStream->GoTo(0);
|
||||
mpStream->WriteLong(mMagic);
|
||||
delete mpStream;
|
||||
}
|
||||
}
|
||||
|
||||
inline bool IsValid() const { return mpStream->IsValid(); }
|
||||
|
||||
private:
|
||||
void InitParamStack()
|
||||
{
|
||||
mParamStack.reserve(20);
|
||||
mpStream->WriteLong(0xFFFFFFFF);
|
||||
mpStream->WriteLong(0); // Size filler
|
||||
mParamStack.push_back( SParameter { mpStream->Tell(), 0 } );
|
||||
}
|
||||
|
||||
public:
|
||||
// Interface
|
||||
virtual bool ParamBegin(const char *pkName, u32 Flags)
|
||||
{
|
||||
// Update parent param
|
||||
mParamStack.back().NumSubParams++;
|
||||
|
||||
if (mParamStack.back().NumSubParams == 1)
|
||||
mpStream->WriteLong(-1); // Sub-param count filler
|
||||
|
||||
// Write param metadata
|
||||
u32 ParamID = TString(pkName).Hash32();
|
||||
mpStream->WriteLong(ParamID);
|
||||
mpStream->WriteLong(-1); // Param size filler
|
||||
|
||||
// Add new param to the stack
|
||||
mParamStack.push_back( SParameter { mpStream->Tell(), 0 } );
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
virtual void ParamEnd()
|
||||
{
|
||||
// Write param size
|
||||
SParameter& rParam = mParamStack.back();
|
||||
u32 StartOffset = rParam.Offset;
|
||||
u32 EndOffset = mpStream->Tell();
|
||||
u32 ParamSize = (EndOffset - StartOffset);
|
||||
|
||||
mpStream->GoTo(StartOffset - 4);
|
||||
mpStream->WriteLong(ParamSize);
|
||||
|
||||
// Write param child count
|
||||
if (rParam.NumSubParams > 0 || mParamStack.size() == 1)
|
||||
{
|
||||
mpStream->WriteLong(rParam.NumSubParams);
|
||||
}
|
||||
|
||||
mpStream->GoTo(EndOffset);
|
||||
mParamStack.pop_back();
|
||||
}
|
||||
|
||||
virtual bool PreSerializePointer(void*& Pointer, u32 Flags)
|
||||
{
|
||||
bool ValidPtr = (Pointer != nullptr);
|
||||
*this << SerialParameter("PointerValid", ValidPtr);
|
||||
return ValidPtr;
|
||||
}
|
||||
|
||||
virtual void SerializeContainerSize(u32& rSize, const TString& /*rkElemName*/)
|
||||
{
|
||||
// Normally handled by ParamBegin and ParamEnd but we need to do something here to account for zero-sized containers
|
||||
if (rSize == 0)
|
||||
mpStream->WriteLong(0);
|
||||
}
|
||||
|
||||
virtual void SerializePrimitive(bool& rValue, u32 Flags) { mpStream->WriteBool(rValue); }
|
||||
virtual void SerializePrimitive(char& rValue, u32 Flags) { mpStream->WriteByte(rValue); }
|
||||
virtual void SerializePrimitive(s8& rValue, u32 Flags) { mpStream->WriteByte(rValue); }
|
||||
virtual void SerializePrimitive(u8& rValue, u32 Flags) { mpStream->WriteByte(rValue); }
|
||||
virtual void SerializePrimitive(s16& rValue, u32 Flags) { mpStream->WriteShort(rValue); }
|
||||
virtual void SerializePrimitive(u16& rValue, u32 Flags) { mpStream->WriteShort(rValue); }
|
||||
virtual void SerializePrimitive(s32& rValue, u32 Flags) { mpStream->WriteLong(rValue); }
|
||||
virtual void SerializePrimitive(u32& rValue, u32 Flags) { mpStream->WriteLong(rValue); }
|
||||
virtual void SerializePrimitive(s64& rValue, u32 Flags) { mpStream->WriteLongLong(rValue); }
|
||||
virtual void SerializePrimitive(u64& rValue, u32 Flags) { mpStream->WriteLongLong(rValue); }
|
||||
virtual void SerializePrimitive(float& rValue, u32 Flags) { mpStream->WriteFloat(rValue); }
|
||||
virtual void SerializePrimitive(double& rValue, u32 Flags) { mpStream->WriteDouble(rValue); }
|
||||
virtual void SerializePrimitive(TString& rValue, u32 Flags) { mpStream->WriteSizedString(rValue); }
|
||||
virtual void SerializePrimitive(TWideString& rValue, u32 Flags) { mpStream->WriteSizedWString(rValue); }
|
||||
virtual void SerializePrimitive(CFourCC& rValue, u32 Flags) { rValue.Write(*mpStream); }
|
||||
virtual void SerializePrimitive(CAssetID& rValue, u32 Flags) { rValue.Write(*mpStream, CAssetID::GameIDLength(Game())); }
|
||||
virtual void SerializeBulkData(void* pData, u32 Size, u32 Flags) { mpStream->WriteBytes(pData, Size); }
|
||||
};
|
||||
|
||||
#endif // CBINARYWRITER
|
||||
|
|
@ -1,34 +0,0 @@
|
|||
#include "CSerialVersion.h"
|
||||
#include "Common/CFourCC.h"
|
||||
|
||||
CSerialVersion::CSerialVersion()
|
||||
{
|
||||
}
|
||||
|
||||
CSerialVersion::CSerialVersion(u16 ArchiveVer, u16 FileVer, EGame Game)
|
||||
: mArchiveVersion(ArchiveVer)
|
||||
, mFileVersion(FileVer)
|
||||
, mGame(Game)
|
||||
{
|
||||
}
|
||||
|
||||
CSerialVersion::CSerialVersion(IInputStream& rInput)
|
||||
{
|
||||
Read(rInput);
|
||||
}
|
||||
|
||||
void CSerialVersion::Read(IInputStream& rInput)
|
||||
{
|
||||
mArchiveVersion = rInput.ReadShort();
|
||||
mFileVersion = rInput.ReadShort();
|
||||
CFourCC GameID(rInput);
|
||||
mGame = GameFrom4CC(GameID);
|
||||
}
|
||||
|
||||
void CSerialVersion::Write(IOutputStream& rOutput)
|
||||
{
|
||||
rOutput.WriteShort(mArchiveVersion);
|
||||
rOutput.WriteShort(mFileVersion);
|
||||
CFourCC GameID = GameTo4CC(mGame);
|
||||
GameID.Write(rOutput);
|
||||
}
|
|
@ -1,27 +0,0 @@
|
|||
#ifndef CSERIALVERSION
|
||||
#define CSERIALVERSION
|
||||
|
||||
#include "Common/EGame.h"
|
||||
#include "Common/FileIO.h"
|
||||
#include "Common/types.h"
|
||||
|
||||
class CSerialVersion
|
||||
{
|
||||
u16 mArchiveVersion;
|
||||
u16 mFileVersion;
|
||||
EGame mGame;
|
||||
|
||||
public:
|
||||
CSerialVersion();
|
||||
CSerialVersion(u16 ArchiveVer, u16 FileVer, EGame Game);
|
||||
CSerialVersion(IInputStream& rInput);
|
||||
void Read(IInputStream& rInput);
|
||||
void Write(IOutputStream& rOutput);
|
||||
|
||||
inline u16 ArchiveVersion() const { return mArchiveVersion; }
|
||||
inline u16 FileVersion() const { return mFileVersion; }
|
||||
inline EGame Game() const { return mGame; }
|
||||
};
|
||||
|
||||
#endif // CSERIALVERSION
|
||||
|
|
@ -1,168 +0,0 @@
|
|||
#ifndef CXMLREADER
|
||||
#define CXMLREADER
|
||||
|
||||
#include "IArchive.h"
|
||||
#include <tinyxml2.h>
|
||||
|
||||
class CXMLReader : public IArchive
|
||||
{
|
||||
tinyxml2::XMLDocument mDoc;
|
||||
tinyxml2::XMLElement *mpCurElem; // Points to the next element being read
|
||||
const char* mpAttribute; // Name of the parameter we are reading from an attribute
|
||||
bool mJustEndedParam; // Indicates we just ended a primitive parameter
|
||||
|
||||
public:
|
||||
CXMLReader(const TString& rkFileName)
|
||||
: IArchive()
|
||||
, mpAttribute(nullptr)
|
||||
, mJustEndedParam(false)
|
||||
{
|
||||
mArchiveFlags = AF_Reader | AF_Text;
|
||||
|
||||
// Load XML and set current element to the root element; read version
|
||||
mDoc.LoadFile(*rkFileName);
|
||||
mpCurElem = mDoc.FirstChildElement();
|
||||
|
||||
if (mpCurElem != nullptr)
|
||||
{
|
||||
SerializeVersion();
|
||||
}
|
||||
else
|
||||
{
|
||||
Log::Error("Failed to open XML for read: " + rkFileName);
|
||||
}
|
||||
}
|
||||
|
||||
inline bool IsValid() const
|
||||
{
|
||||
return mpCurElem != nullptr;
|
||||
}
|
||||
|
||||
// Interface
|
||||
virtual bool IsReader() const { return true; }
|
||||
virtual bool IsWriter() const { return false; }
|
||||
virtual bool IsTextFormat() const { return true; }
|
||||
|
||||
virtual bool ParamBegin(const char *pkName, u32 Flags)
|
||||
{
|
||||
ASSERT(IsValid());
|
||||
ASSERT(!mpAttribute); // Attributes cannot have sub-children
|
||||
|
||||
// Store as an attribute if requested
|
||||
if (Flags & SH_Attribute)
|
||||
{
|
||||
mpAttribute = mpCurElem->Attribute(pkName);
|
||||
return mpAttribute != nullptr;
|
||||
}
|
||||
|
||||
// Push new parent if needed
|
||||
if (!mJustEndedParam)
|
||||
{
|
||||
tinyxml2::XMLElement *pChild = mpCurElem->FirstChildElement();
|
||||
if (!pChild) return false;
|
||||
else mpCurElem = pChild;
|
||||
}
|
||||
|
||||
// Verify the current element matches the name of the next serialized parameter.
|
||||
if ( (Flags & SH_IgnoreName) || strcmp(mpCurElem->Name(), pkName) == 0 )
|
||||
{
|
||||
mJustEndedParam = false;
|
||||
return true;
|
||||
}
|
||||
|
||||
// It didn't match, so we'll try to find a sibling element that does match.
|
||||
// Iterate over all sibling elements - if we find a match we will continue
|
||||
// reading from that point on. Otherwise we can't load this parameter.
|
||||
tinyxml2::XMLElement *pSearchElem = mpCurElem->Parent()->FirstChildElement();
|
||||
|
||||
while (pSearchElem)
|
||||
{
|
||||
if ( strcmp(pSearchElem->Name(), pkName) == 0 )
|
||||
{
|
||||
mpCurElem = pSearchElem;
|
||||
mJustEndedParam = false;
|
||||
return true;
|
||||
}
|
||||
|
||||
pSearchElem = pSearchElem->NextSiblingElement();
|
||||
}
|
||||
|
||||
// We couldn't find a matching element, so we can't load this parameter.
|
||||
// If we pushed a parent earlier, undo it.
|
||||
if (!mJustEndedParam)
|
||||
mpCurElem = mpCurElem->Parent()->ToElement();
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
virtual void ParamEnd()
|
||||
{
|
||||
if (mpAttribute)
|
||||
mpAttribute = nullptr;
|
||||
|
||||
else
|
||||
{
|
||||
if (mJustEndedParam)
|
||||
mpCurElem = mpCurElem->Parent()->ToElement();
|
||||
|
||||
tinyxml2::XMLElement *pElem = mpCurElem->NextSiblingElement();
|
||||
if (pElem)
|
||||
mpCurElem = pElem;
|
||||
|
||||
mJustEndedParam = true;
|
||||
}
|
||||
}
|
||||
|
||||
protected:
|
||||
TString ReadParam()
|
||||
{
|
||||
return TString( mpAttribute ? mpAttribute : mpCurElem->GetText() );
|
||||
}
|
||||
|
||||
public:
|
||||
virtual void SerializeArraySize(u32& Value)
|
||||
{
|
||||
Value = 0;
|
||||
|
||||
for (tinyxml2::XMLElement *pElem = mpCurElem->FirstChildElement(); pElem; pElem = pElem->NextSiblingElement())
|
||||
Value++;
|
||||
}
|
||||
|
||||
virtual bool PreSerializePointer(void*& InPointer, u32 Flags)
|
||||
{
|
||||
return mpCurElem->GetText() == nullptr || strcmp(mpCurElem->GetText(), "NULL") != 0;
|
||||
}
|
||||
|
||||
virtual void SerializePrimitive(bool& rValue, u32 Flags) { rValue = (ReadParam() == "true" ? true : false); }
|
||||
virtual void SerializePrimitive(char& rValue, u32 Flags) { rValue = ReadParam().Front(); }
|
||||
virtual void SerializePrimitive(s8& rValue, u32 Flags) { rValue = (s8) ReadParam().ToInt32( (Flags & SH_HexDisplay) ? 16 : 10 ); }
|
||||
virtual void SerializePrimitive(u8& rValue, u32 Flags) { rValue = (u8) ReadParam().ToInt32( (Flags & SH_HexDisplay) ? 16 : 10 ); }
|
||||
virtual void SerializePrimitive(s16& rValue, u32 Flags) { rValue = (s16) ReadParam().ToInt32( (Flags & SH_HexDisplay) ? 16 : 10 ); }
|
||||
virtual void SerializePrimitive(u16& rValue, u32 Flags) { rValue = (u16) ReadParam().ToInt32( (Flags & SH_HexDisplay) ? 16 : 10 ); }
|
||||
virtual void SerializePrimitive(s32& rValue, u32 Flags) { rValue = (s32) ReadParam().ToInt32( (Flags & SH_HexDisplay) ? 16 : 10 ); }
|
||||
virtual void SerializePrimitive(u32& rValue, u32 Flags) { rValue = (u32) ReadParam().ToInt32( (Flags & SH_HexDisplay) ? 16 : 10 ); }
|
||||
virtual void SerializePrimitive(s64& rValue, u32 Flags) { rValue = (s64) ReadParam().ToInt64( (Flags & SH_HexDisplay) ? 16 : 10 ); }
|
||||
virtual void SerializePrimitive(u64& rValue, u32 Flags) { rValue = (u64) ReadParam().ToInt64( (Flags & SH_HexDisplay) ? 16 : 10 ); }
|
||||
virtual void SerializePrimitive(float& rValue, u32 Flags) { rValue = ReadParam().ToFloat(); }
|
||||
virtual void SerializePrimitive(double& rValue, u32 Flags) { rValue = (double) ReadParam().ToFloat(); }
|
||||
virtual void SerializePrimitive(TString& rValue, u32 Flags) { rValue = ReadParam(); }
|
||||
virtual void SerializePrimitive(TWideString& rValue, u32 Flags) { rValue = ReadParam().ToUTF16(); }
|
||||
virtual void SerializePrimitive(CFourCC& rValue, u32 Flags) { rValue = CFourCC( ReadParam() ); }
|
||||
virtual void SerializePrimitive(CAssetID& rValue, u32 Flags) { rValue = CAssetID::FromString( ReadParam() ); }
|
||||
|
||||
virtual void SerializeBulkData(void* pData, u32 Size, u32 Flags)
|
||||
{
|
||||
char* pCharData = (char*) pData;
|
||||
TString StringData = ReadParam();
|
||||
ASSERT(StringData.Size() == Size*2);
|
||||
|
||||
for (u32 ByteIdx = 0; ByteIdx < Size; ByteIdx++)
|
||||
{
|
||||
*pCharData = (char) StringData.SubString(ByteIdx*2, 2).ToInt32(16);
|
||||
pCharData++;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
#endif // CXMLREADER
|
||||
|
|
@ -1,172 +0,0 @@
|
|||
#ifndef CXMLWRITER
|
||||
#define CXMLWRITER
|
||||
|
||||
#include "IArchive.h"
|
||||
#include "Common/CFourCC.h"
|
||||
#include <iostream>
|
||||
#include <tinyxml2.h>
|
||||
|
||||
class CXMLWriter : public IArchive
|
||||
{
|
||||
tinyxml2::XMLDocument mDoc;
|
||||
tinyxml2::XMLElement *mpCurElem;
|
||||
TString mOutFilename;
|
||||
const char* mpAttributeName;
|
||||
bool mSaved;
|
||||
|
||||
public:
|
||||
CXMLWriter(const TString& rkFileName, const TString& rkRootName, u16 FileVersion = 0, EGame Game = EGame::Invalid)
|
||||
: IArchive()
|
||||
, mOutFilename(rkFileName)
|
||||
, mpAttributeName(nullptr)
|
||||
, mSaved(false)
|
||||
{
|
||||
mArchiveFlags = AF_Writer | AF_Text;
|
||||
SetVersion(skCurrentArchiveVersion, FileVersion, Game);
|
||||
|
||||
// Create declaration and root node
|
||||
tinyxml2::XMLDeclaration *pDecl = mDoc.NewDeclaration();
|
||||
mDoc.LinkEndChild(pDecl);
|
||||
|
||||
mpCurElem = mDoc.NewElement(*rkRootName);
|
||||
mDoc.LinkEndChild(mpCurElem);
|
||||
|
||||
// Write version data
|
||||
SerializeVersion();
|
||||
}
|
||||
|
||||
~CXMLWriter()
|
||||
{
|
||||
if (!mSaved)
|
||||
{
|
||||
bool SaveSuccess = Save();
|
||||
ASSERT(SaveSuccess);
|
||||
}
|
||||
}
|
||||
|
||||
inline bool Save()
|
||||
{
|
||||
if (mSaved)
|
||||
{
|
||||
Log::Error("Attempted to save XML twice!");
|
||||
return false;
|
||||
}
|
||||
|
||||
tinyxml2::XMLError Error = mDoc.SaveFile(*mOutFilename);
|
||||
mSaved = true;
|
||||
|
||||
if (Error != tinyxml2::XML_SUCCESS)
|
||||
{
|
||||
Log::Error("Failed to save XML file: " + mOutFilename);
|
||||
return false;
|
||||
}
|
||||
else
|
||||
return true;
|
||||
}
|
||||
|
||||
inline bool IsValid() const
|
||||
{
|
||||
return mpCurElem != nullptr && !mSaved;
|
||||
}
|
||||
|
||||
// Interface
|
||||
virtual bool ParamBegin(const char *pkName, u32 Flags)
|
||||
{
|
||||
ASSERT(IsValid());
|
||||
ASSERT(!mpAttributeName); // Attributes cannot have sub-children
|
||||
|
||||
// Read as attribute if needed
|
||||
if (Flags & SH_Attribute)
|
||||
{
|
||||
mpAttributeName = pkName;
|
||||
}
|
||||
else
|
||||
{
|
||||
tinyxml2::XMLElement *pElem = mDoc.NewElement(pkName);
|
||||
mpCurElem->LinkEndChild(pElem);
|
||||
mpCurElem = pElem;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
virtual void ParamEnd()
|
||||
{
|
||||
if (mpAttributeName)
|
||||
{
|
||||
mpAttributeName = nullptr;
|
||||
}
|
||||
else
|
||||
{
|
||||
// If we didn't save any sub parameters, remove the element.
|
||||
tinyxml2::XMLElement* pParent = mpCurElem->Parent()->ToElement();
|
||||
|
||||
if ( mpCurElem->FirstAttribute() == nullptr
|
||||
&& mpCurElem->FirstChild() == nullptr
|
||||
&& mpCurElem->GetText() == nullptr )
|
||||
{
|
||||
pParent->DeleteChild(mpCurElem);
|
||||
}
|
||||
|
||||
mpCurElem = pParent;
|
||||
}
|
||||
}
|
||||
|
||||
protected:
|
||||
void WriteParam(const char *pkValue)
|
||||
{
|
||||
if (mpAttributeName)
|
||||
mpCurElem->SetAttribute(mpAttributeName, pkValue);
|
||||
else
|
||||
mpCurElem->SetText(pkValue);
|
||||
}
|
||||
|
||||
public:
|
||||
virtual bool PreSerializePointer(void*& Pointer, u32 Flags)
|
||||
{
|
||||
if (!Pointer)
|
||||
{
|
||||
mpCurElem->SetText("NULL");
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
virtual void SerializeArraySize(u32& Value)
|
||||
{
|
||||
// Do nothing. Reader obtains container size from number of child elements
|
||||
}
|
||||
|
||||
virtual void SerializePrimitive(bool& rValue, u32 Flags) { WriteParam(rValue ? "true" : "false"); }
|
||||
virtual void SerializePrimitive(char& rValue, u32 Flags) { WriteParam(*TString(rValue)); }
|
||||
virtual void SerializePrimitive(s8& rValue, u32 Flags) { WriteParam( (Flags & SH_HexDisplay) ? *TString::HexString((u8&) rValue, 0) : *TString::FromInt32(rValue, 0, 10) ); }
|
||||
virtual void SerializePrimitive(u8& rValue, u32 Flags) { WriteParam( (Flags & SH_HexDisplay) ? *TString::HexString((u8&) rValue, 0) : *TString::FromInt32(rValue, 0, 10) ); }
|
||||
virtual void SerializePrimitive(s16& rValue, u32 Flags) { WriteParam( (Flags & SH_HexDisplay) ? *TString::HexString((u16&) rValue, 0) : *TString::FromInt32(rValue, 0, 10) ); }
|
||||
virtual void SerializePrimitive(u16& rValue, u32 Flags) { WriteParam( (Flags & SH_HexDisplay) ? *TString::HexString((u16&) rValue, 0) : *TString::FromInt32(rValue, 0, 10) ); }
|
||||
virtual void SerializePrimitive(s32& rValue, u32 Flags) { WriteParam( (Flags & SH_HexDisplay) ? *TString::HexString((u32&) rValue, 0) : *TString::FromInt32(rValue, 0, 10) ); }
|
||||
virtual void SerializePrimitive(u32& rValue, u32 Flags) { WriteParam( (Flags & SH_HexDisplay) ? *TString::HexString((u32&) rValue, 0) : *TString::FromInt32(rValue, 0, 10) ); }
|
||||
virtual void SerializePrimitive(s64& rValue, u32 Flags) { WriteParam( *TString::FromInt64(rValue, 0, (Flags & SH_HexDisplay) ? 16 : 10) ); }
|
||||
virtual void SerializePrimitive(u64& rValue, u32 Flags) { WriteParam( *TString::FromInt64(rValue, 0, (Flags & SH_HexDisplay) ? 16 : 10) ); }
|
||||
virtual void SerializePrimitive(float& rValue, u32 Flags) { WriteParam( *TString::FromFloat(rValue, 1, true) ); }
|
||||
virtual void SerializePrimitive(double& rValue, u32 Flags) { WriteParam( *TString::FromFloat((float) rValue, 1, true) ); }
|
||||
virtual void SerializePrimitive(TString& rValue, u32 Flags) { WriteParam( *rValue ); }
|
||||
virtual void SerializePrimitive(TWideString& rValue, u32 Flags) { WriteParam( *rValue.ToUTF8() ); }
|
||||
virtual void SerializePrimitive(CFourCC& rValue, u32 Flags) { WriteParam( *rValue.ToString() ); }
|
||||
virtual void SerializePrimitive(CAssetID& rValue, u32 Flags) { WriteParam( *rValue.ToString( CAssetID::GameIDLength(Game()) ) ); }
|
||||
|
||||
virtual void SerializeBulkData(void* pData, u32 Size, u32 Flags)
|
||||
{
|
||||
char* pCharData = (char*) pData;
|
||||
TString OutString(Size*2);
|
||||
|
||||
for (u32 ByteIdx = 0; ByteIdx < Size; ByteIdx++)
|
||||
{
|
||||
//@todo: sloooooow. maybe replace with a LUT?
|
||||
sprintf(&OutString[ByteIdx*2], "%02X", pCharData[ByteIdx]);
|
||||
}
|
||||
|
||||
WriteParam(*OutString);
|
||||
}
|
||||
};
|
||||
|
||||
#endif // CXMLWRITER
|
File diff suppressed because it is too large
Load Diff
|
@ -1,3 +0,0 @@
|
|||
#include "IArchive.h"
|
||||
#include "CXMLReader.h"
|
||||
#include "CXMLWriter.h"
|
|
@ -1,129 +0,0 @@
|
|||
#include "TString.h"
|
||||
#include "Hash/CCRC32.h"
|
||||
#include "Hash/CFNV1A.h"
|
||||
#include "FileIO/IOUtil.h"
|
||||
#include <codecvt>
|
||||
#include <locale>
|
||||
|
||||
// ************ TString ************
|
||||
u32 TString::Hash32() const
|
||||
{
|
||||
CCRC32 Hash;
|
||||
Hash.Hash(**this);
|
||||
return Hash.Digest();
|
||||
}
|
||||
|
||||
u64 TString::Hash64() const
|
||||
{
|
||||
// todo: replace with MD5
|
||||
CFNV1A Hash(CFNV1A::e64Bit);
|
||||
Hash.HashString(*this);
|
||||
return Hash.GetHash64();
|
||||
}
|
||||
|
||||
TWideString TString::ToUTF16() const
|
||||
{
|
||||
TWideString Out;
|
||||
Out.Reserve(Size());
|
||||
|
||||
const char *pkCStr = CString();
|
||||
|
||||
while (pkCStr[0])
|
||||
{
|
||||
// Step 1: decode UTF-8 code point
|
||||
wchar_t CodePoint;
|
||||
|
||||
// One byte
|
||||
if ((pkCStr[0] & 0x80) == 0)
|
||||
{
|
||||
CodePoint = pkCStr[0] & 0x7FFFFFFF;
|
||||
pkCStr++;
|
||||
}
|
||||
|
||||
// Two bytes
|
||||
else if ((pkCStr[0] & 0xE0) == 0xC0)
|
||||
{
|
||||
CodePoint = (((pkCStr[0] & 0x1F) << 6) |
|
||||
(pkCStr[1] & 0x3F));
|
||||
pkCStr += 2;
|
||||
}
|
||||
|
||||
// Three bytes
|
||||
else if ((pkCStr[0] & 0xF0) == 0xE0)
|
||||
{
|
||||
CodePoint = (((pkCStr[0] & 0xF) << 12) |
|
||||
((pkCStr[1] & 0x3F) << 6) |
|
||||
(pkCStr[2] & 0x3F));
|
||||
pkCStr += 3;
|
||||
}
|
||||
|
||||
// Four bytes
|
||||
else if ((pkCStr[0] & 0xF8) == 0xF0)
|
||||
{
|
||||
CodePoint = (((pkCStr[0] & 0x7) << 18) |
|
||||
((pkCStr[1] & 0x3F) << 12) |
|
||||
((pkCStr[2] & 0x3F) << 6) |
|
||||
(pkCStr[3] & 0x3F));
|
||||
pkCStr += 4;
|
||||
}
|
||||
|
||||
// Five bytes
|
||||
else if ((pkCStr[0] & 0xFC) == 0xF8)
|
||||
{
|
||||
CodePoint = (((pkCStr[0] & 0x3) << 24) |
|
||||
((pkCStr[1] & 0x3F) << 18) |
|
||||
((pkCStr[2] & 0x3F) << 12) |
|
||||
((pkCStr[3] & 0x3F) << 6) |
|
||||
(pkCStr[4] & 0x3F));
|
||||
pkCStr += 5;
|
||||
}
|
||||
|
||||
// Six bytes
|
||||
else if ((pkCStr[0] & 0xFE) == 0xFC)
|
||||
{
|
||||
CodePoint = (((pkCStr[0] & 0x1) << 30) |
|
||||
((pkCStr[1] & 0x3F) << 24) |
|
||||
((pkCStr[2] & 0x3F) << 18) |
|
||||
((pkCStr[3] & 0x3F) << 12) |
|
||||
((pkCStr[4] & 0x3F) << 6) |
|
||||
(pkCStr[5] & 0x3F));
|
||||
pkCStr += 6;
|
||||
}
|
||||
|
||||
// Invalid?
|
||||
else
|
||||
{
|
||||
CodePoint = pkCStr[0];
|
||||
pkCStr++;
|
||||
}
|
||||
|
||||
// Step 2: Append to output string
|
||||
if ( ((CodePoint >= 0) && (CodePoint <= 0xD7FF)) ||
|
||||
((CodePoint >= 0xE000) && (CodePoint <= 0xFFFF)) )
|
||||
Out.Append((wchar_t) (CodePoint & 0xFFFF));
|
||||
}
|
||||
|
||||
Out.Shrink();
|
||||
return Out;
|
||||
}
|
||||
|
||||
// ************ TWideString ************
|
||||
u32 TWideString::Hash32() const
|
||||
{
|
||||
CFNV1A Hash(CFNV1A::e32Bit);
|
||||
Hash.HashData(Data(), Size() * sizeof(wchar_t));
|
||||
return Hash.GetHash32();
|
||||
}
|
||||
|
||||
u64 TWideString::Hash64() const
|
||||
{
|
||||
CFNV1A Hash(CFNV1A::e64Bit);
|
||||
Hash.HashData(Data(), Size() * sizeof(wchar_t));
|
||||
return Hash.GetHash64();
|
||||
}
|
||||
|
||||
TString TWideString::ToUTF8() const
|
||||
{
|
||||
std::wstring_convert<std::codecvt_utf8_utf16<wchar_t>> Convert;
|
||||
return TString( Convert.to_bytes(ToStdString()) );
|
||||
}
|
1130
src/Common/TString.h
1130
src/Common/TString.h
File diff suppressed because it is too large
Load Diff
|
@ -1,13 +0,0 @@
|
|||
#ifndef TYPES_H
|
||||
#define TYPES_H
|
||||
|
||||
typedef unsigned char u8;
|
||||
typedef unsigned short u16;
|
||||
typedef unsigned long u32;
|
||||
typedef unsigned long long u64;
|
||||
typedef signed char s8;
|
||||
typedef signed short s16;
|
||||
typedef signed long s32;
|
||||
typedef signed long long s64;
|
||||
|
||||
#endif // TYPES_H
|
|
@ -1,201 +0,0 @@
|
|||
#include "CAABox.h"
|
||||
#include "CRay.h"
|
||||
#include "CTransform4f.h"
|
||||
#include "MathUtil.h"
|
||||
#include <float.h>
|
||||
|
||||
CAABox::CAABox()
|
||||
: mMin(CVector3f::skInfinite)
|
||||
, mMax(-CVector3f::skInfinite)
|
||||
{
|
||||
}
|
||||
|
||||
CAABox::CAABox(const CVector3f& rkMin, const CVector3f& rkMax)
|
||||
: mMin(rkMin)
|
||||
, mMax(rkMax)
|
||||
{
|
||||
}
|
||||
|
||||
CAABox::CAABox(IInputStream& rInput)
|
||||
: mMin(rInput)
|
||||
, mMax(rInput)
|
||||
{
|
||||
}
|
||||
|
||||
void CAABox::Serialize(IArchive& rArc)
|
||||
{
|
||||
rArc << SerialParameter("Min", mMin)
|
||||
<< SerialParameter("Max", mMax);
|
||||
}
|
||||
|
||||
void CAABox::Write(IOutputStream& rOutput)
|
||||
{
|
||||
mMin.Write(rOutput);
|
||||
mMax.Write(rOutput);
|
||||
}
|
||||
|
||||
CVector3f CAABox::Center() const
|
||||
{
|
||||
return (mMax - ((mMax - mMin) * 0.5f));
|
||||
}
|
||||
|
||||
CVector3f CAABox::Size() const
|
||||
{
|
||||
return (mMax - mMin);
|
||||
}
|
||||
|
||||
CVector3f CAABox::Min() const
|
||||
{
|
||||
return mMin;
|
||||
}
|
||||
|
||||
CVector3f CAABox::Max() const
|
||||
{
|
||||
return mMax;
|
||||
}
|
||||
|
||||
void CAABox::SetMin(const CVector3f& rkMin)
|
||||
{
|
||||
mMin = rkMin;
|
||||
}
|
||||
|
||||
void CAABox::SetMax(const CVector3f& rkMax)
|
||||
{
|
||||
mMax = rkMax;
|
||||
}
|
||||
|
||||
bool CAABox::IsNull() const
|
||||
{
|
||||
return (Size() == CVector3f::skZero);
|
||||
}
|
||||
|
||||
bool CAABox::IsInfinite() const
|
||||
{
|
||||
return (Size() == CVector3f::skInfinite);
|
||||
}
|
||||
|
||||
void CAABox::ExpandBounds(const CVector3f& rkVtx)
|
||||
{
|
||||
// take an input vertex coordinate and expand the bounding box to fit it, if necessary
|
||||
if (rkVtx.X < mMin.X) mMin.X = rkVtx.X;
|
||||
if (rkVtx.X > mMax.X) mMax.X = rkVtx.X;
|
||||
if (rkVtx.Y < mMin.Y) mMin.Y = rkVtx.Y;
|
||||
if (rkVtx.Y > mMax.Y) mMax.Y = rkVtx.Y;
|
||||
if (rkVtx.Z < mMin.Z) mMin.Z = rkVtx.Z;
|
||||
if (rkVtx.Z > mMax.Z) mMax.Z = rkVtx.Z;
|
||||
}
|
||||
|
||||
void CAABox::ExpandBounds(const CAABox& rkAABox)
|
||||
{
|
||||
ExpandBounds(rkAABox.mMin);
|
||||
ExpandBounds(rkAABox.mMax);
|
||||
}
|
||||
|
||||
void CAABox::ExpandBy(const CVector3f& rkAmount)
|
||||
{
|
||||
CVector3f halfAmount = rkAmount / 2.f;
|
||||
mMin -= halfAmount;
|
||||
mMax += halfAmount;
|
||||
}
|
||||
|
||||
CAABox CAABox::Transformed(const CTransform4f& rkTransform) const
|
||||
{
|
||||
CAABox AABox;
|
||||
|
||||
AABox.ExpandBounds(rkTransform * CVector3f(mMin.X, mMin.Y, mMin.Z));
|
||||
AABox.ExpandBounds(rkTransform * CVector3f(mMin.X, mMin.Y, mMax.Z));
|
||||
AABox.ExpandBounds(rkTransform * CVector3f(mMin.X, mMax.Y, mMax.Z));
|
||||
AABox.ExpandBounds(rkTransform * CVector3f(mMin.X, mMax.Y, mMin.Z));
|
||||
AABox.ExpandBounds(rkTransform * CVector3f(mMax.X, mMin.Y, mMin.Z));
|
||||
AABox.ExpandBounds(rkTransform * CVector3f(mMax.X, mMin.Y, mMax.Z));
|
||||
AABox.ExpandBounds(rkTransform * CVector3f(mMax.X, mMax.Y, mMax.Z));
|
||||
AABox.ExpandBounds(rkTransform * CVector3f(mMax.X, mMax.Y, mMin.Z));
|
||||
|
||||
return AABox;
|
||||
}
|
||||
|
||||
bool CAABox::IsPointInBox(const CVector3f& rkPoint) const
|
||||
{
|
||||
return ( ((rkPoint.X >= mMin.X) && (rkPoint.X <= mMax.X)) &&
|
||||
((rkPoint.Y >= mMin.Y) && (rkPoint.Y <= mMax.Y)) &&
|
||||
((rkPoint.Z >= mMin.Z) && (rkPoint.Z <= mMax.Z)) );
|
||||
}
|
||||
|
||||
CVector3f CAABox::ClosestPointAlongVector(const CVector3f& rkDir) const
|
||||
{
|
||||
CVector3f out;
|
||||
out.X = (rkDir.X >= 0.f) ? mMin.X : mMax.X;
|
||||
out.Y = (rkDir.Y >= 0.f) ? mMin.Y : mMax.Y;
|
||||
out.Z = (rkDir.Z >= 0.f) ? mMin.Z : mMax.Z;
|
||||
return out;
|
||||
}
|
||||
|
||||
CVector3f CAABox::FurthestPointAlongVector(const CVector3f& rkDir) const
|
||||
{
|
||||
CVector3f out;
|
||||
out.X = (rkDir.X >= 0.f) ? mMax.X : mMin.X;
|
||||
out.Y = (rkDir.Y >= 0.f) ? mMax.Y : mMin.Y;
|
||||
out.Z = (rkDir.Z >= 0.f) ? mMax.Z : mMin.Z;
|
||||
return out;
|
||||
}
|
||||
|
||||
// ************ INTERSECTION TESTS ************
|
||||
// These tests are kinda bad and probably inaccurate, they need rewrites
|
||||
bool CAABox::IntersectsAABox(const CAABox& rkAABox)
|
||||
{
|
||||
return ((mMax > rkAABox.mMin) && (mMin < rkAABox.mMax));
|
||||
}
|
||||
|
||||
bool CAABox::IntersectsSphere(const CVector3f& rkSphereCenter, float SphereRadius)
|
||||
{
|
||||
// Placeholder for proper sphere intersection test
|
||||
// Generate an AABox for the sphere and do an AABox/AABox intersection test instead
|
||||
return IntersectsAABox(CAABox(rkSphereCenter - SphereRadius, rkSphereCenter + SphereRadius));
|
||||
}
|
||||
|
||||
std::pair<bool,float> CAABox::IntersectsRay(const CRay& rkRay) const
|
||||
{
|
||||
return Math::RayBoxIntersection(rkRay, *this);
|
||||
}
|
||||
|
||||
// ************ OPERATORS ************
|
||||
CAABox CAABox::operator+(const CVector3f& rkTranslate) const
|
||||
{
|
||||
return CAABox(mMin + rkTranslate, mMax + rkTranslate);
|
||||
}
|
||||
|
||||
void CAABox::operator+=(const CVector3f& rkTranslate)
|
||||
{
|
||||
*this = *this + rkTranslate;
|
||||
}
|
||||
|
||||
CAABox CAABox::operator*(float Scalar) const
|
||||
{
|
||||
return CAABox(mMin * Scalar, mMax * Scalar);
|
||||
}
|
||||
|
||||
void CAABox::operator*=(float Scalar)
|
||||
{
|
||||
*this = *this * Scalar;
|
||||
}
|
||||
|
||||
bool CAABox::operator==(const CAABox& rkOther) const
|
||||
{
|
||||
return ((mMin == rkOther.mMin) && (mMax == rkOther.mMax));
|
||||
}
|
||||
|
||||
bool CAABox::operator!=(const CAABox& rkOther) const
|
||||
{
|
||||
return (!(*this == rkOther));
|
||||
}
|
||||
|
||||
// ************ CONSTANTS ************
|
||||
|
||||
// min set to float maximum, max set to float minimum; ideal for creating an AABox from scratch
|
||||
const CAABox CAABox::skInfinite = CAABox(CVector3f(FLT_MAX), CVector3f(-FLT_MAX));
|
||||
|
||||
// a 1x1x1 bounding box
|
||||
const CAABox CAABox::skOne = CAABox( CVector3f(-0.5f, -0.5f, -0.5f), CVector3f(0.5f, 0.5f, 0.5f) );
|
||||
|
||||
// a 0x0x0 bounding box
|
||||
const CAABox CAABox::skZero = CAABox(CVector3f(0), CVector3f(0));
|
|
@ -1,60 +0,0 @@
|
|||
#ifndef CAABOX_H
|
||||
#define CAABOX_H
|
||||
|
||||
#include "CVector3f.h"
|
||||
#include <Common/FileIO/IInputStream.h>
|
||||
#include <Common/FileIO/IOutputStream.h>
|
||||
#include <Common/Serialization/IArchive.h>
|
||||
#include <utility>
|
||||
|
||||
class CRay;
|
||||
class CRayIntersection;
|
||||
|
||||
class CAABox
|
||||
{
|
||||
CVector3f mMin, mMax;
|
||||
|
||||
public:
|
||||
CAABox();
|
||||
CAABox(const CVector3f& rkMin, const CVector3f& rkMax);
|
||||
CAABox(IInputStream& rInput);
|
||||
void Serialize(IArchive& rArc);
|
||||
void Write(IOutputStream& rOutput);
|
||||
CVector3f Center() const;
|
||||
CVector3f Size() const;
|
||||
CVector3f Min() const;
|
||||
CVector3f Max() const;
|
||||
void SetMin(const CVector3f& rkMin);
|
||||
void SetMax(const CVector3f& rkMax);
|
||||
bool IsNull() const;
|
||||
bool IsInfinite() const;
|
||||
|
||||
void ExpandBounds(const CVector3f& rkVtx);
|
||||
void ExpandBounds(const CAABox& rkAABox);
|
||||
void ExpandBy(const CVector3f& rkAmount);
|
||||
CAABox Transformed(const CTransform4f& rkTransform) const;
|
||||
|
||||
bool IsPointInBox(const CVector3f& rkPoint) const;
|
||||
CVector3f ClosestPointAlongVector(const CVector3f& rkDir) const;
|
||||
CVector3f FurthestPointAlongVector(const CVector3f& rkDir) const;
|
||||
|
||||
// Intersection Tests
|
||||
bool IntersectsAABox(const CAABox& rkAABox);
|
||||
bool IntersectsSphere(const CVector3f& rkSphereCenter, float SphereRadius);
|
||||
std::pair<bool,float> IntersectsRay(const CRay& rkRay) const;
|
||||
|
||||
// Operators
|
||||
CAABox operator+(const CVector3f& rkTranslate) const;
|
||||
void operator+=(const CVector3f& rkTranslate);
|
||||
CAABox operator*(float Scalar) const;
|
||||
void operator*=(float Scalar);
|
||||
bool operator==(const CAABox& rkOther) const;
|
||||
bool operator!=(const CAABox& rkOther) const;
|
||||
|
||||
// Constants
|
||||
static const CAABox skInfinite;
|
||||
static const CAABox skOne;
|
||||
static const CAABox skZero;
|
||||
};
|
||||
|
||||
#endif // CAABOX_H
|
|
@ -1,92 +0,0 @@
|
|||
#include "CFrustumPlanes.h"
|
||||
#include "MathUtil.h"
|
||||
#include "Common/types.h"
|
||||
|
||||
CFrustumPlanes::CFrustumPlanes()
|
||||
{
|
||||
}
|
||||
|
||||
const CPlane& CFrustumPlanes::GetPlane(EFrustumSide Side) const
|
||||
{
|
||||
return mPlanes[Side];
|
||||
}
|
||||
|
||||
void CFrustumPlanes::SetPlanes(const CVector3f& rkPosition, const CVector3f& rkDirection, float FieldOfView, float AspectRatio, float Near, float Far)
|
||||
{
|
||||
// Calculate up/right vectors
|
||||
CVector3f Right = rkDirection.Cross(CVector3f::skUp).Normalized();
|
||||
CVector3f Up = Right.Cross(rkDirection).Normalized();
|
||||
|
||||
// Calculate dimensions of near plane
|
||||
float NearHeight = 2 * tanf(Math::DegreesToRadians(FieldOfView) / 2.f) * Near;
|
||||
float NearWidth = NearHeight * AspectRatio;
|
||||
|
||||
// Define the planes
|
||||
CVector3f NearCenter = rkPosition + (rkDirection * Near);
|
||||
mPlanes[eNearPlane].Redefine(rkDirection, NearCenter);
|
||||
|
||||
CVector3f FarCenter = rkPosition + (rkDirection * Far);
|
||||
mPlanes[eFarPlane].Redefine(-rkDirection, FarCenter);
|
||||
|
||||
CVector3f MidRight = NearCenter + (Right * (NearWidth / 2.f));
|
||||
CVector3f RightNormal = Up.Cross((MidRight - rkPosition).Normalized());
|
||||
mPlanes[eRightPlane].Redefine(RightNormal, rkPosition);
|
||||
|
||||
CVector3f MidLeft = NearCenter - (Right * (NearWidth / 2.f));
|
||||
CVector3f LeftNormal = (MidLeft - rkPosition).Normalized().Cross(Up);
|
||||
mPlanes[eLeftPlane].Redefine(LeftNormal, rkPosition);
|
||||
|
||||
CVector3f MidTop = NearCenter + (Up * (NearHeight / 2.f));
|
||||
CVector3f TopNormal = (MidTop - rkPosition).Normalized().Cross(Right);
|
||||
mPlanes[eTopPlane].Redefine(TopNormal, rkPosition);
|
||||
|
||||
CVector3f MidBottom = NearCenter - (Up * (NearHeight / 2.f));
|
||||
CVector3f BottomNormal = Right.Cross((MidBottom - rkPosition).Normalized());
|
||||
mPlanes[eBottomPlane].Redefine(BottomNormal, rkPosition);
|
||||
}
|
||||
|
||||
bool CFrustumPlanes::PointInFrustum(const CVector3f& rkPoint) const
|
||||
{
|
||||
for (u32 iPlane = 0; iPlane < 6; iPlane++)
|
||||
{
|
||||
const CPlane& rkPlane = mPlanes[iPlane];
|
||||
|
||||
if (rkPlane.Normal().Dot(rkPoint) + rkPlane.Dist() < 0.f)
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CFrustumPlanes::BoxInFrustum(const CAABox& rkBox) const
|
||||
{
|
||||
CVector3f Min = rkBox.Min();
|
||||
CVector3f Max = rkBox.Max();
|
||||
|
||||
CVector3f Points[8];
|
||||
Points[0] = Min;
|
||||
Points[1] = Max;
|
||||
Points[2] = CVector3f(Min.X, Min.Y, Max.Z);
|
||||
Points[3] = CVector3f(Min.X, Max.Y, Min.Z);
|
||||
Points[4] = CVector3f(Min.X, Max.Y, Max.Z);
|
||||
Points[5] = CVector3f(Max.X, Min.Y, Max.Z);
|
||||
Points[6] = CVector3f(Max.X, Max.Y, Min.Z);
|
||||
Points[7] = CVector3f(Max.X, Min.Y, Min.Z);
|
||||
|
||||
for (u32 iPlane = 0; iPlane < 6; iPlane++)
|
||||
{
|
||||
const CPlane& rkPlane = mPlanes[iPlane];
|
||||
int NumPoints = 0;
|
||||
|
||||
for (u32 iPoint = 0; iPoint < 8; iPoint++)
|
||||
{
|
||||
if (rkPlane.Normal().Dot(Points[iPoint]) + rkPlane.Dist() < 0.f)
|
||||
NumPoints++;
|
||||
else
|
||||
break;
|
||||
}
|
||||
|
||||
if (NumPoints == 8) return false;
|
||||
}
|
||||
return true;
|
||||
}
|
|
@ -1,29 +0,0 @@
|
|||
#ifndef CFRUSTUMPLANES_H
|
||||
#define CFRUSTUMPLANES_H
|
||||
|
||||
#include "CAABox.h"
|
||||
#include "CPlane.h"
|
||||
#include "CVector3f.h"
|
||||
|
||||
class CFrustumPlanes
|
||||
{
|
||||
public:
|
||||
enum EFrustumSide
|
||||
{
|
||||
eNearPlane = 0, eFarPlane = 1,
|
||||
eTopPlane = 2, eBottomPlane = 3,
|
||||
eLeftPlane = 4, eRightPlane = 5
|
||||
};
|
||||
|
||||
private:
|
||||
CPlane mPlanes[6];
|
||||
|
||||
public:
|
||||
CFrustumPlanes();
|
||||
const CPlane& GetPlane(EFrustumSide Side) const;
|
||||
void SetPlanes(const CVector3f& rkPosition, const CVector3f& rkDirection, float FieldOfView, float AspectRatio, float Near, float Far);
|
||||
bool PointInFrustum(const CVector3f& rkPoint) const;
|
||||
bool BoxInFrustum(const CAABox& rkBox) const;
|
||||
};
|
||||
|
||||
#endif // CFRUSTUMPLANES_H
|
|
@ -1,217 +0,0 @@
|
|||
#include "CMatrix4f.h"
|
||||
#include "CQuaternion.h"
|
||||
#include "CVector3f.h"
|
||||
#include "CVector4f.h"
|
||||
#include "CTransform4f.h"
|
||||
|
||||
CMatrix4f::CMatrix4f()
|
||||
{
|
||||
}
|
||||
|
||||
CMatrix4f::CMatrix4f(float Diagonal)
|
||||
{
|
||||
*this = skZero;
|
||||
m[0][0] = Diagonal;
|
||||
m[1][1] = Diagonal;
|
||||
m[2][2] = Diagonal;
|
||||
m[3][3] = Diagonal;
|
||||
}
|
||||
|
||||
CMatrix4f::CMatrix4f(float m00, float m01, float m02, float m03,
|
||||
float m10, float m11, float m12, float m13,
|
||||
float m20, float m21, float m22, float m23,
|
||||
float m30, float m31, float m32, float m33)
|
||||
{
|
||||
m[0][0] = m00;
|
||||
m[0][1] = m01;
|
||||
m[0][2] = m02;
|
||||
m[0][3] = m03;
|
||||
m[1][0] = m10;
|
||||
m[1][1] = m11;
|
||||
m[1][2] = m12;
|
||||
m[1][3] = m13;
|
||||
m[2][0] = m20;
|
||||
m[2][1] = m21;
|
||||
m[2][2] = m22;
|
||||
m[2][3] = m23;
|
||||
m[3][0] = m30;
|
||||
m[3][1] = m31;
|
||||
m[3][2] = m32;
|
||||
m[3][3] = m33;
|
||||
}
|
||||
|
||||
// ************ MATH ************
|
||||
CMatrix4f CMatrix4f::Transpose() const
|
||||
{
|
||||
return CMatrix4f(m[0][0], m[1][0], m[2][0], m[3][0],
|
||||
m[0][1], m[1][1], m[2][1], m[3][1],
|
||||
m[0][2], m[1][2], m[2][2], m[3][2],
|
||||
m[0][3], m[1][3], m[2][3], m[3][3]);
|
||||
}
|
||||
|
||||
CMatrix4f CMatrix4f::Inverse() const
|
||||
{
|
||||
// Copied from Ogre.
|
||||
// todo after developing a better understanding of the math - rewrite
|
||||
float m00 = m[0][0], m01 = m[0][1], m02 = m[0][2], m03 = m[0][3];
|
||||
float m10 = m[1][0], m11 = m[1][1], m12 = m[1][2], m13 = m[1][3];
|
||||
float m20 = m[2][0], m21 = m[2][1], m22 = m[2][2], m23 = m[2][3];
|
||||
float m30 = m[3][0], m31 = m[3][1], m32 = m[3][2], m33 = m[3][3];
|
||||
|
||||
float v0 = m20 * m31 - m21 * m30;
|
||||
float v1 = m20 * m32 - m22 * m30;
|
||||
float v2 = m20 * m33 - m23 * m30;
|
||||
float v3 = m21 * m32 - m22 * m31;
|
||||
float v4 = m21 * m33 - m23 * m31;
|
||||
float v5 = m22 * m33 - m23 * m32;
|
||||
|
||||
float t00 = + (v5 * m11 - v4 * m12 + v3 * m13);
|
||||
float t10 = - (v5 * m10 - v2 * m12 + v1 * m13);
|
||||
float t20 = + (v4 * m10 - v2 * m11 + v0 * m13);
|
||||
float t30 = - (v3 * m10 - v1 * m11 + v0 * m12);
|
||||
|
||||
float invDet = 1 / (t00 * m00 + t10 * m01 + t20 * m02 + t30 * m03);
|
||||
|
||||
float d00 = t00 * invDet;
|
||||
float d10 = t10 * invDet;
|
||||
float d20 = t20 * invDet;
|
||||
float d30 = t30 * invDet;
|
||||
|
||||
float d01 = - (v5 * m01 - v4 * m02 + v3 * m03) * invDet;
|
||||
float d11 = + (v5 * m00 - v2 * m02 + v1 * m03) * invDet;
|
||||
float d21 = - (v4 * m00 - v2 * m01 + v0 * m03) * invDet;
|
||||
float d31 = + (v3 * m00 - v1 * m01 + v0 * m02) * invDet;
|
||||
|
||||
v0 = m10 * m31 - m11 * m30;
|
||||
v1 = m10 * m32 - m12 * m30;
|
||||
v2 = m10 * m33 - m13 * m30;
|
||||
v3 = m11 * m32 - m12 * m31;
|
||||
v4 = m11 * m33 - m13 * m31;
|
||||
v5 = m12 * m33 - m13 * m32;
|
||||
|
||||
float d02 = + (v5 * m01 - v4 * m02 + v3 * m03) * invDet;
|
||||
float d12 = - (v5 * m00 - v2 * m02 + v1 * m03) * invDet;
|
||||
float d22 = + (v4 * m00 - v2 * m01 + v0 * m03) * invDet;
|
||||
float d32 = - (v3 * m00 - v1 * m01 + v0 * m02) * invDet;
|
||||
|
||||
v0 = m21 * m10 - m20 * m11;
|
||||
v1 = m22 * m10 - m20 * m12;
|
||||
v2 = m23 * m10 - m20 * m13;
|
||||
v3 = m22 * m11 - m21 * m12;
|
||||
v4 = m23 * m11 - m21 * m13;
|
||||
v5 = m23 * m12 - m22 * m13;
|
||||
|
||||
float d03 = - (v5 * m01 - v4 * m02 + v3 * m03) * invDet;
|
||||
float d13 = + (v5 * m00 - v2 * m02 + v1 * m03) * invDet;
|
||||
float d23 = - (v4 * m00 - v2 * m01 + v0 * m03) * invDet;
|
||||
float d33 = + (v3 * m00 - v1 * m01 + v0 * m02) * invDet;
|
||||
|
||||
return CMatrix4f(
|
||||
d00, d01, d02, d03,
|
||||
d10, d11, d12, d13,
|
||||
d20, d21, d22, d23,
|
||||
d30, d31, d32, d33);
|
||||
}
|
||||
|
||||
float CMatrix4f::Determinant() const
|
||||
{
|
||||
float AA = m[1][1] * ((m[2][2] * m[3][3]) - (m[2][3] * m[3][2]));
|
||||
float AB = m[1][2] * ((m[2][1] * m[3][3]) - (m[2][3] * m[3][1]));
|
||||
float AC = m[1][3] * ((m[2][1] * m[3][2]) - (m[2][2] * m[3][1]));
|
||||
float A = m[0][0] * (AA - AB + AC);
|
||||
|
||||
float BA = m[1][0] * ((m[2][2] * m[3][3]) - (m[2][3] * m[3][2]));
|
||||
float BB = m[1][2] * ((m[2][0] * m[3][3]) - (m[2][3] * m[3][0]));
|
||||
float BC = m[1][3] * ((m[2][0] * m[3][2]) - (m[2][2] * m[3][0]));
|
||||
float B = m[0][1] * (BA - BB + BC);
|
||||
|
||||
float CA = m[1][0] * ((m[2][1] * m[3][3]) - (m[2][3] * m[3][1]));
|
||||
float CB = m[1][1] * ((m[2][0] * m[3][3]) - (m[2][3] * m[3][0]));
|
||||
float CC = m[1][3] * ((m[2][0] * m[3][1]) - (m[2][1] * m[3][0]));
|
||||
float C = m[0][2] * (CA - CB + CC);
|
||||
|
||||
float DA = m[1][0] * ((m[2][1] * m[3][2]) - (m[2][2] * m[3][1]));
|
||||
float DB = m[1][1] * ((m[2][0] * m[3][2]) - (m[2][2] * m[3][0]));
|
||||
float DC = m[1][2] * ((m[2][0] * m[3][1]) - (m[2][1] * m[3][0]));
|
||||
float D = m[0][3] * (DA - DB + DC);
|
||||
|
||||
return (A - B + C - D);
|
||||
}
|
||||
|
||||
// ************ OPERATORS ************
|
||||
CVector3f CMatrix4f::operator*(const CVector3f& rkVec) const
|
||||
{
|
||||
// For vec3 multiplication, the vector w component is considered to be 1.0
|
||||
CVector3f out;
|
||||
float w = (m[3][0] * rkVec.X) + (m[3][1] * rkVec.Y) + (m[3][2] * rkVec.Z) + m[3][3];
|
||||
out.X = ((m[0][0] * rkVec.X) + (m[0][1] * rkVec.Y) + (m[0][2] * rkVec.Z) + m[0][3]) / w;
|
||||
out.Y = ((m[1][0] * rkVec.X) + (m[1][1] * rkVec.Y) + (m[1][2] * rkVec.Z) + m[1][3]) / w;
|
||||
out.Z = ((m[2][0] * rkVec.X) + (m[2][1] * rkVec.Y) + (m[2][2] * rkVec.Z) + m[1][3]) / w;
|
||||
return out;
|
||||
}
|
||||
|
||||
CVector4f CMatrix4f::operator*(const CVector4f& rkVec) const
|
||||
{
|
||||
CVector4f out;
|
||||
out.X = (m[0][0] * rkVec.X) + (m[0][1] * rkVec.Y) + (m[0][2] * rkVec.Z) + (m[0][3] * rkVec.W);
|
||||
out.Y = (m[1][0] * rkVec.X) + (m[1][1] * rkVec.Y) + (m[1][2] * rkVec.Z) + (m[1][3] * rkVec.W);
|
||||
out.Z = (m[2][0] * rkVec.X) + (m[2][1] * rkVec.Y) + (m[2][2] * rkVec.Z) + (m[2][3] * rkVec.W);
|
||||
out.W = (m[3][0] * rkVec.X) + (m[3][1] * rkVec.Y) + (m[3][2] * rkVec.Z) + (m[3][3] * rkVec.W);
|
||||
return out;
|
||||
}
|
||||
|
||||
CMatrix4f CMatrix4f::operator*(const CTransform4f& rkMtx) const
|
||||
{
|
||||
// CTransform4f is a 3x4 matrix with an implicit fourth row of {0, 0, 0, 1}
|
||||
CMatrix4f out;
|
||||
out[0][0] = (m[0][0] * rkMtx[0][0]) + (m[0][1] * rkMtx[1][0]) + (m[0][2] * rkMtx[2][0]);
|
||||
out[0][1] = (m[0][0] * rkMtx[0][1]) + (m[0][1] * rkMtx[1][1]) + (m[0][2] * rkMtx[2][1]);
|
||||
out[0][2] = (m[0][0] * rkMtx[0][2]) + (m[0][1] * rkMtx[1][2]) + (m[0][2] * rkMtx[2][2]);
|
||||
out[0][3] = (m[0][0] * rkMtx[0][3]) + (m[0][1] * rkMtx[1][3]) + (m[0][2] * rkMtx[2][3]) + m[0][3];
|
||||
out[1][0] = (m[1][0] * rkMtx[0][0]) + (m[1][1] * rkMtx[1][0]) + (m[1][2] * rkMtx[2][0]);
|
||||
out[1][1] = (m[1][0] * rkMtx[0][1]) + (m[1][1] * rkMtx[1][1]) + (m[1][2] * rkMtx[2][1]);
|
||||
out[1][2] = (m[1][0] * rkMtx[0][2]) + (m[1][1] * rkMtx[1][2]) + (m[1][2] * rkMtx[2][2]);
|
||||
out[1][3] = (m[1][0] * rkMtx[0][3]) + (m[1][1] * rkMtx[1][3]) + (m[1][2] * rkMtx[2][3]) + m[1][3];
|
||||
out[2][0] = (m[2][0] * rkMtx[0][0]) + (m[2][1] * rkMtx[1][0]) + (m[2][2] * rkMtx[2][0]);
|
||||
out[2][1] = (m[2][0] * rkMtx[0][1]) + (m[2][1] * rkMtx[1][1]) + (m[2][2] * rkMtx[2][1]);
|
||||
out[2][2] = (m[2][0] * rkMtx[0][2]) + (m[2][1] * rkMtx[1][2]) + (m[2][2] * rkMtx[2][2]);
|
||||
out[2][3] = (m[2][0] * rkMtx[0][3]) + (m[2][1] * rkMtx[1][3]) + (m[2][2] * rkMtx[2][3]) + m[2][3];
|
||||
out[3][0] = (m[3][0] * rkMtx[0][0]) + (m[3][1] * rkMtx[1][0]) + (m[3][2] * rkMtx[2][0]);
|
||||
out[3][1] = (m[3][0] * rkMtx[0][1]) + (m[3][1] * rkMtx[1][1]) + (m[3][2] * rkMtx[2][1]);
|
||||
out[3][2] = (m[3][0] * rkMtx[0][2]) + (m[3][1] * rkMtx[1][2]) + (m[3][2] * rkMtx[2][2]);
|
||||
out[3][3] = (m[3][0] * rkMtx[0][3]) + (m[3][1] * rkMtx[1][3]) + (m[3][2] * rkMtx[2][3]) + m[3][3];
|
||||
return out;
|
||||
}
|
||||
|
||||
CMatrix4f CMatrix4f::operator*(const CMatrix4f& rkMtx) const
|
||||
{
|
||||
CMatrix4f out;
|
||||
out[0][0] = (m[0][0] * rkMtx[0][0]) + (m[0][1] * rkMtx[1][0]) + (m[0][2] * rkMtx[2][0]) + (m[0][3] * rkMtx[3][0]);
|
||||
out[0][1] = (m[0][0] * rkMtx[0][1]) + (m[0][1] * rkMtx[1][1]) + (m[0][2] * rkMtx[2][1]) + (m[0][3] * rkMtx[3][1]);
|
||||
out[0][2] = (m[0][0] * rkMtx[0][2]) + (m[0][1] * rkMtx[1][2]) + (m[0][2] * rkMtx[2][2]) + (m[0][3] * rkMtx[3][2]);
|
||||
out[0][3] = (m[0][0] * rkMtx[0][3]) + (m[0][1] * rkMtx[1][3]) + (m[0][2] * rkMtx[2][3]) + (m[0][3] * rkMtx[3][3]);
|
||||
out[1][0] = (m[1][0] * rkMtx[0][0]) + (m[1][1] * rkMtx[1][0]) + (m[1][2] * rkMtx[2][0]) + (m[1][3] * rkMtx[3][0]);
|
||||
out[1][1] = (m[1][0] * rkMtx[0][1]) + (m[1][1] * rkMtx[1][1]) + (m[1][2] * rkMtx[2][1]) + (m[1][3] * rkMtx[3][1]);
|
||||
out[1][2] = (m[1][0] * rkMtx[0][2]) + (m[1][1] * rkMtx[1][2]) + (m[1][2] * rkMtx[2][2]) + (m[1][3] * rkMtx[3][2]);
|
||||
out[1][3] = (m[1][0] * rkMtx[0][3]) + (m[1][1] * rkMtx[1][3]) + (m[1][2] * rkMtx[2][3]) + (m[1][3] * rkMtx[3][3]);
|
||||
out[2][0] = (m[2][0] * rkMtx[0][0]) + (m[2][1] * rkMtx[1][0]) + (m[2][2] * rkMtx[2][0]) + (m[2][3] * rkMtx[3][0]);
|
||||
out[2][1] = (m[2][0] * rkMtx[0][1]) + (m[2][1] * rkMtx[1][1]) + (m[2][2] * rkMtx[2][1]) + (m[2][3] * rkMtx[3][1]);
|
||||
out[2][2] = (m[2][0] * rkMtx[0][2]) + (m[2][1] * rkMtx[1][2]) + (m[2][2] * rkMtx[2][2]) + (m[2][3] * rkMtx[3][2]);
|
||||
out[2][3] = (m[2][0] * rkMtx[0][3]) + (m[2][1] * rkMtx[1][3]) + (m[2][2] * rkMtx[2][3]) + (m[2][3] * rkMtx[3][3]);
|
||||
out[3][0] = (m[3][0] * rkMtx[0][0]) + (m[3][1] * rkMtx[1][0]) + (m[3][2] * rkMtx[2][0]) + (m[3][3] * rkMtx[3][0]);
|
||||
out[3][1] = (m[3][0] * rkMtx[0][1]) + (m[3][1] * rkMtx[1][1]) + (m[3][2] * rkMtx[2][1]) + (m[3][3] * rkMtx[3][1]);
|
||||
out[3][2] = (m[3][0] * rkMtx[0][2]) + (m[3][1] * rkMtx[1][2]) + (m[3][2] * rkMtx[2][2]) + (m[3][3] * rkMtx[3][2]);
|
||||
out[3][3] = (m[3][0] * rkMtx[0][3]) + (m[3][1] * rkMtx[1][3]) + (m[3][2] * rkMtx[2][3]) + (m[3][3] * rkMtx[3][3]);
|
||||
return out;
|
||||
}
|
||||
|
||||
// ************ CONSTANT ************
|
||||
const CMatrix4f CMatrix4f::skZero(0.0f, 0.0f, 0.0f, 0.0f,
|
||||
0.0f, 0.0f, 0.0f, 0.0f,
|
||||
0.0f, 0.0f, 0.0f, 0.0f,
|
||||
0.0f, 0.0f, 0.0f, 0.0f);
|
||||
|
||||
const CMatrix4f CMatrix4f::skIdentity(1.0f, 0.0f, 0.0f, 0.0f,
|
||||
0.0f, 1.0f, 0.0f, 0.0f,
|
||||
0.0f, 0.0f, 1.0f, 0.0f,
|
||||
0.0f, 0.0f, 0.0f, 1.0f);
|
|
@ -1,55 +0,0 @@
|
|||
#ifndef CMATRIX4_H
|
||||
#define CMATRIX4_H
|
||||
|
||||
class CQuaternion;
|
||||
class CVector3f;
|
||||
class CVector4f;
|
||||
class CTransform4f;
|
||||
|
||||
class CMatrix4f
|
||||
{
|
||||
protected:
|
||||
union
|
||||
{
|
||||
float m[4][4];
|
||||
float _m[16];
|
||||
};
|
||||
|
||||
public:
|
||||
CMatrix4f();
|
||||
CMatrix4f(float Diagonal);
|
||||
CMatrix4f(float m00, float m01, float m02, float m03,
|
||||
float m10, float m11, float m12, float m13,
|
||||
float m20, float m21, float m22, float m23,
|
||||
float m30, float m31, float m32, float m33);
|
||||
|
||||
// Math
|
||||
CMatrix4f Transpose() const;
|
||||
CMatrix4f Inverse() const;
|
||||
float Determinant() const;
|
||||
|
||||
// Operators
|
||||
inline float* operator[](long Index);
|
||||
inline const float* operator[](long Index) const;
|
||||
CVector3f operator*(const CVector3f& rkVec) const;
|
||||
CVector4f operator*(const CVector4f& rkVec) const;
|
||||
CQuaternion operator*(const CQuaternion& rkQuat) const;
|
||||
CMatrix4f operator*(const CTransform4f& rkMtx) const;
|
||||
CMatrix4f operator*(const CMatrix4f& rkMtx) const;
|
||||
|
||||
// Constants
|
||||
static const CMatrix4f skZero;
|
||||
static const CMatrix4f skIdentity;
|
||||
};
|
||||
|
||||
inline float* CMatrix4f::operator[](long Index)
|
||||
{
|
||||
return m[Index];
|
||||
}
|
||||
|
||||
inline const float* CMatrix4f::operator[](long Index) const
|
||||
{
|
||||
return m[Index];
|
||||
}
|
||||
|
||||
#endif // CMATRIX4_H
|
|
@ -1,39 +0,0 @@
|
|||
#ifndef CPLANE_H
|
||||
#define CPLANE_H
|
||||
|
||||
#include "CVector3f.h"
|
||||
|
||||
class CPlane
|
||||
{
|
||||
CVector3f mNormal;
|
||||
float mDist;
|
||||
|
||||
public:
|
||||
CPlane()
|
||||
: mNormal(CVector3f::skUp)
|
||||
, mDist(0.f)
|
||||
{}
|
||||
|
||||
CPlane(const CVector3f& rkNormal, float Dist)
|
||||
: mNormal(rkNormal)
|
||||
, mDist(Dist)
|
||||
{}
|
||||
|
||||
CPlane(const CVector3f& rkNormal, const CVector3f& rkOrigin)
|
||||
{
|
||||
Redefine(rkNormal, rkOrigin);
|
||||
}
|
||||
|
||||
void Redefine(const CVector3f& rkNormal, const CVector3f& rkOrigin)
|
||||
{
|
||||
mNormal = rkNormal;
|
||||
mDist = -rkNormal.Dot(rkOrigin);
|
||||
}
|
||||
|
||||
CVector3f Normal() const { return mNormal; }
|
||||
float Dist() const { return mDist; }
|
||||
void SetNormal(const CVector3f& rkNormal) { mNormal = rkNormal; }
|
||||
void SetDist(float Dist) { mDist = Dist; }
|
||||
};
|
||||
|
||||
#endif // CPLANE_H
|
|
@ -1,260 +0,0 @@
|
|||
#include "CQuaternion.h"
|
||||
#include "CMatrix4f.h"
|
||||
#include "MathUtil.h"
|
||||
#include <cmath>
|
||||
#include <math.h>
|
||||
|
||||
CQuaternion::CQuaternion()
|
||||
: W(1.f)
|
||||
, X(0.f)
|
||||
, Y(0.f)
|
||||
, Z(0.f)
|
||||
{
|
||||
}
|
||||
|
||||
CQuaternion::CQuaternion(float _W, float _X, float _Y, float _Z)
|
||||
: W(_W)
|
||||
, X(_X)
|
||||
, Y(_Y)
|
||||
, Z(_Z)
|
||||
{
|
||||
}
|
||||
|
||||
CQuaternion::CQuaternion(IInputStream& rInput)
|
||||
: W(rInput.ReadFloat())
|
||||
, X(rInput.ReadFloat())
|
||||
, Y(rInput.ReadFloat())
|
||||
, Z(rInput.ReadFloat())
|
||||
{
|
||||
}
|
||||
|
||||
CVector3f CQuaternion::XAxis() const
|
||||
{
|
||||
return (*this * CVector3f::skUnitX);
|
||||
}
|
||||
|
||||
CVector3f CQuaternion::YAxis() const
|
||||
{
|
||||
return (*this * CVector3f::skUnitY);
|
||||
}
|
||||
|
||||
CVector3f CQuaternion::ZAxis() const
|
||||
{
|
||||
return (*this * CVector3f::skUnitZ);
|
||||
}
|
||||
|
||||
CQuaternion CQuaternion::Normalized() const
|
||||
{
|
||||
float Norm = Math::Sqrt( (W * W) + (X * X) + (Y * Y) + (Z * Z) );
|
||||
return CQuaternion(W/Norm, X/Norm, Y/Norm, Z/Norm);
|
||||
}
|
||||
|
||||
CQuaternion CQuaternion::Inverse() const
|
||||
{
|
||||
float Norm = (W * W) + (X * X) + (Y * Y) + (Z * Z);
|
||||
|
||||
if (Norm > 0.f)
|
||||
{
|
||||
float InvNorm = 1.f / Norm;
|
||||
return CQuaternion( W * InvNorm, -X * InvNorm, -Y * InvNorm, -Z * InvNorm);
|
||||
}
|
||||
else
|
||||
return CQuaternion::skZero;
|
||||
}
|
||||
|
||||
CQuaternion CQuaternion::Lerp(const CQuaternion& rkRight, float t) const
|
||||
{
|
||||
CQuaternion Out( Math::Lerp<float>(W, rkRight.W, t), Math::Lerp<float>(X, rkRight.X, t),
|
||||
Math::Lerp<float>(Y, rkRight.Y, t), Math::Lerp<float>(Z, rkRight.Z, t) );
|
||||
|
||||
return Out.Normalized();
|
||||
}
|
||||
|
||||
CQuaternion CQuaternion::Slerp(const CQuaternion& rkRight, float t) const
|
||||
{
|
||||
// http://www.euclideanspace.com/maths/algebra/realNormedAlgebra/quaternions/slerp/
|
||||
float CosHalfTheta = (W * rkRight.W) + (X * rkRight.X) + (Y * rkRight.Y) + (Z * rkRight.Z);
|
||||
|
||||
if (Math::Abs(CosHalfTheta) >= 1.f)
|
||||
{
|
||||
// Fall back on lerp in this situation.
|
||||
return Lerp(rkRight, t);
|
||||
}
|
||||
|
||||
float ScalarA, ScalarB;
|
||||
float SinHalfTheta = Math::Sqrt(1.f - (CosHalfTheta * CosHalfTheta));
|
||||
|
||||
if (Math::Abs(SinHalfTheta) < 0.001f)
|
||||
{
|
||||
ScalarA = 0.5f;
|
||||
ScalarB = 0.5f;
|
||||
}
|
||||
|
||||
else
|
||||
{
|
||||
float HalfTheta = acosf(CosHalfTheta);
|
||||
ScalarA = sinf((1.f - t) * HalfTheta) / SinHalfTheta;
|
||||
ScalarB = sinf(t * HalfTheta) / SinHalfTheta;
|
||||
}
|
||||
|
||||
return CQuaternion( (W * ScalarA) + (rkRight.W * ScalarB),
|
||||
(X * ScalarA) + (rkRight.X * ScalarB),
|
||||
(Y * ScalarA) + (rkRight.Y * ScalarB),
|
||||
(Z * ScalarA) + (rkRight.Z * ScalarB) );
|
||||
}
|
||||
|
||||
CVector3f CQuaternion::ToEuler() const
|
||||
{
|
||||
// There is more than one way to do this conversion, based on rotation order.
|
||||
// But since we only care about the rotation order used in Retro games, which is consistent,
|
||||
// we can just have a single conversion function. Handy!
|
||||
// https://en.wikipedia.org/wiki/Conversion_between_quaternions_and_Euler_angles
|
||||
|
||||
float EulerX = atan2f(2 * (W*X + Y*Z), 1 - (2 * (Math::Pow(X,2) + Math::Pow(Y,2))));
|
||||
float EulerY = asinf(2 * (W*Y - Z*X));
|
||||
float EulerZ = atan2f(2 * (W*Z + X*Y), 1 - (2 * (Math::Pow(Y,2) + Math::Pow(Z,2))));
|
||||
return CVector3f(Math::RadiansToDegrees(EulerX), Math::RadiansToDegrees(EulerY), Math::RadiansToDegrees(EulerZ));
|
||||
}
|
||||
|
||||
// ************ OPERATORS ************
|
||||
CVector3f CQuaternion::operator*(const CVector3f& rkVec) const
|
||||
{
|
||||
CVector3f uv, uuv;
|
||||
CVector3f qvec(X, Y, Z);
|
||||
uv = qvec.Cross(rkVec);
|
||||
uuv = qvec.Cross(uv);
|
||||
uv *= (2.0f * W);
|
||||
uuv *= 2.0f;
|
||||
|
||||
return rkVec + uv + uuv;
|
||||
}
|
||||
|
||||
CQuaternion CQuaternion::operator*(const CQuaternion& rkOther) const
|
||||
{
|
||||
CQuaternion out;
|
||||
out.W = (-X * rkOther.X) - (Y * rkOther.Y) - (Z * rkOther.Z) + (W * rkOther.W);
|
||||
out.X = ( X * rkOther.W) + (Y * rkOther.Z) - (Z * rkOther.Y) + (W * rkOther.X);
|
||||
out.Y = (-X * rkOther.Z) + (Y * rkOther.W) + (Z * rkOther.X) + (W * rkOther.Y);
|
||||
out.Z = ( X * rkOther.Y) - (Y * rkOther.X) + (Z * rkOther.W) + (W * rkOther.Z);
|
||||
return out;
|
||||
}
|
||||
|
||||
void CQuaternion::operator *= (const CQuaternion& rkOther)
|
||||
{
|
||||
*this = *this * rkOther;
|
||||
}
|
||||
|
||||
CQuaternion CQuaternion::operator*(const CTransform4f& rkMtx) const
|
||||
{
|
||||
return *this * rkMtx.ExtractRotation();
|
||||
}
|
||||
|
||||
void CQuaternion::operator *= (const CTransform4f& rkMtx)
|
||||
{
|
||||
*this = *this * rkMtx;
|
||||
}
|
||||
|
||||
// ************ STATIC ************
|
||||
CQuaternion CQuaternion::FromEuler(CVector3f Euler)
|
||||
{
|
||||
/**
|
||||
* The commented-out code below might be faster but the conversion isn't completely correct
|
||||
* So in lieu of fixing it I'm using axis angles to convert from Eulers instead
|
||||
* I'm not sure what the difference is performance-wise but the result is 100% accurate
|
||||
*/
|
||||
/*CQuaternion quat;
|
||||
|
||||
// Convert from degrees to radians
|
||||
float pi = 3.14159265358979323846f;
|
||||
euler = euler * pi / 180;
|
||||
|
||||
// Convert to quaternion
|
||||
float c1 = cos(euler.x / 2);
|
||||
float c2 = cos(euler.y / 2);
|
||||
float c3 = cos(euler.z / 2);
|
||||
float s1 = sin(euler.x / 2);
|
||||
float s2 = sin(euler.y / 2);
|
||||
float s3 = sin(euler.z / 2);
|
||||
|
||||
quat.w = (c1 * c2 * c3) - (s1 * s2 * s3);
|
||||
quat.x = -((s1 * c2 * c3) + (c1 * s2 * s3));
|
||||
quat.y = ((c1 * s2 * c3) - (s1 * c2 * s3));
|
||||
quat.z = ((s1 * s2 * c3) + (c1 * c2 * s3));*/
|
||||
|
||||
CQuaternion X = CQuaternion::FromAxisAngle(Math::DegreesToRadians(Euler.X), CVector3f(1,0,0));
|
||||
CQuaternion Y = CQuaternion::FromAxisAngle(Math::DegreesToRadians(Euler.Y), CVector3f(0,1,0));
|
||||
CQuaternion Z = CQuaternion::FromAxisAngle(Math::DegreesToRadians(Euler.Z), CVector3f(0,0,1));
|
||||
CQuaternion Quat = Z * Y * X;
|
||||
|
||||
return Quat;
|
||||
}
|
||||
|
||||
CQuaternion CQuaternion::FromAxisAngle(float Angle, CVector3f Axis)
|
||||
{
|
||||
CQuaternion Quat;
|
||||
Axis = Axis.Normalized();
|
||||
|
||||
float sa = sinf(Angle / 2);
|
||||
Quat.W = cosf(Angle / 2);
|
||||
Quat.X = Axis.X * sa;
|
||||
Quat.Y = Axis.Y * sa;
|
||||
Quat.Z = Axis.Z * sa;
|
||||
return Quat;
|
||||
|
||||
}
|
||||
|
||||
CQuaternion CQuaternion::FromRotationMatrix(const CMatrix4f& rkRotMtx)
|
||||
{
|
||||
// http://www.euclideanspace.com/maths/geometry/rotations/conversions/matrixToQuaternion/
|
||||
CQuaternion Out;
|
||||
float Trace = rkRotMtx[0][0] + rkRotMtx[1][1] + rkRotMtx[2][2];
|
||||
|
||||
if (Trace > 0.f)
|
||||
{
|
||||
float s = Math::Sqrt(Trace + 1.f) * 2; // s = 4*w
|
||||
Out.W = 0.25f * s;
|
||||
Out.X = (rkRotMtx[2][1] - rkRotMtx[1][2]) / s;
|
||||
Out.Y = (rkRotMtx[0][2] - rkRotMtx[2][0]) / s;
|
||||
Out.Z = (rkRotMtx[1][0] - rkRotMtx[0][1]) / s;
|
||||
}
|
||||
|
||||
else if ((rkRotMtx[0][0] > rkRotMtx[1][1]) && (rkRotMtx[0][0] > rkRotMtx[2][2]))
|
||||
{
|
||||
float s = Math::Sqrt(1.f + rkRotMtx[0][0] - rkRotMtx[1][1] - rkRotMtx[2][2]) * 2; // s = 4*x
|
||||
Out.W = (rkRotMtx[2][1] - rkRotMtx[1][2]) / s;
|
||||
Out.X = 0.25f * s;
|
||||
Out.Y = (rkRotMtx[0][1] + rkRotMtx[1][0]) / s;
|
||||
Out.Z = (rkRotMtx[0][2] + rkRotMtx[2][0]) / s;
|
||||
}
|
||||
|
||||
else if (rkRotMtx[1][1] > rkRotMtx[2][2]) {
|
||||
float s = Math::Sqrt(1.f + rkRotMtx[1][1] - rkRotMtx[0][0] - rkRotMtx[2][2]) * 2; // s = 4*y
|
||||
Out.W = (rkRotMtx[0][2] - rkRotMtx[2][0]) / s;
|
||||
Out.X = (rkRotMtx[0][1] + rkRotMtx[1][0]) / s;
|
||||
Out.Y = 0.25f * s;
|
||||
Out.Z = (rkRotMtx[1][2] + rkRotMtx[2][1]) / s;
|
||||
}
|
||||
|
||||
else {
|
||||
float s = Math::Sqrt(1.f + rkRotMtx[2][2] - rkRotMtx[0][0] - rkRotMtx[1][1]) * 2; // S=4*qz
|
||||
Out.W = (rkRotMtx[1][0] - rkRotMtx[0][1]) / s;
|
||||
Out.X = (rkRotMtx[0][2] + rkRotMtx[2][0]) / s;
|
||||
Out.Y = (rkRotMtx[1][2] + rkRotMtx[2][1]) / s;
|
||||
Out.Z = 0.25f * s;
|
||||
}
|
||||
|
||||
return Out;
|
||||
}
|
||||
|
||||
CQuaternion CQuaternion::FromAxes(const CVector3f& rkX, const CVector3f& rkY, const CVector3f& rkZ)
|
||||
{
|
||||
CMatrix4f RotMtx(rkX.X, rkY.X, rkZ.X, 0.f,
|
||||
rkX.Y, rkY.Y, rkZ.Y, 0.f,
|
||||
rkX.Z, rkY.Z, rkZ.Z, 0.f,
|
||||
0.f, 0.f, 0.f, 1.f);
|
||||
|
||||
return CQuaternion::FromRotationMatrix(RotMtx);
|
||||
}
|
||||
|
||||
CQuaternion CQuaternion::skIdentity = CQuaternion(1.f, 0.f, 0.f, 0.f);
|
||||
CQuaternion CQuaternion::skZero = CQuaternion(0.f, 0.f, 0.f, 0.f);
|
|
@ -1,41 +0,0 @@
|
|||
#ifndef CQUATERNION_H
|
||||
#define CQUATERNION_H
|
||||
|
||||
#include "CVector3f.h"
|
||||
|
||||
class CQuaternion
|
||||
{
|
||||
public:
|
||||
float W, X, Y, Z;
|
||||
|
||||
CQuaternion();
|
||||
CQuaternion(float _W, float _X, float _Y, float _Z);
|
||||
CQuaternion(IInputStream& rInput);
|
||||
|
||||
CVector3f XAxis() const;
|
||||
CVector3f YAxis() const;
|
||||
CVector3f ZAxis() const;
|
||||
CQuaternion Normalized() const;
|
||||
CQuaternion Inverse() const;
|
||||
CQuaternion Lerp(const CQuaternion& rkRight, float t) const;
|
||||
CQuaternion Slerp(const CQuaternion& rkRight, float t) const;
|
||||
CVector3f ToEuler() const;
|
||||
|
||||
// Operators
|
||||
CVector3f operator*(const CVector3f& rkVec) const;
|
||||
CQuaternion operator*(const CQuaternion& rkOther) const;
|
||||
void operator *= (const CQuaternion& rkOther);
|
||||
CQuaternion operator*(const CTransform4f& rkMtx) const;
|
||||
void operator *= (const CTransform4f& rkMtx);
|
||||
|
||||
// Static
|
||||
static CQuaternion FromEuler(CVector3f Euler);
|
||||
static CQuaternion FromAxisAngle(float Angle, CVector3f Axis);
|
||||
static CQuaternion FromRotationMatrix(const CMatrix4f& rkRotMtx);
|
||||
static CQuaternion FromAxes(const CVector3f& rkX, const CVector3f& rkY, const CVector3f& rkZ);
|
||||
|
||||
static CQuaternion skIdentity;
|
||||
static CQuaternion skZero;
|
||||
};
|
||||
|
||||
#endif // CQUATERNION_H
|
|
@ -1,37 +0,0 @@
|
|||
#ifndef CRAY_H
|
||||
#define CRAY_H
|
||||
|
||||
#include "CTransform4f.h"
|
||||
#include "CVector3f.h"
|
||||
|
||||
class CRay
|
||||
{
|
||||
CVector3f mOrigin;
|
||||
CVector3f mDirection;
|
||||
|
||||
public:
|
||||
CRay() {}
|
||||
|
||||
CRay(const CVector3f& rkOrigin, const CVector3f& rkDirection)
|
||||
: mOrigin(rkOrigin), mDirection(rkDirection) {}
|
||||
|
||||
const CVector3f& Origin() const { return mOrigin; }
|
||||
const CVector3f& Direction() const { return mDirection; }
|
||||
void SetOrigin(const CVector3f& rkOrigin) { mOrigin = rkOrigin; }
|
||||
void SetDirection(const CVector3f& rkDirection) { mDirection = rkDirection; }
|
||||
|
||||
CRay Transformed(const CTransform4f& rkMatrix) const
|
||||
{
|
||||
CRay Out;
|
||||
Out.mOrigin = rkMatrix * mOrigin;
|
||||
|
||||
CVector3f Point = rkMatrix * (mOrigin + mDirection);
|
||||
Out.mDirection = (Point - Out.mOrigin).Normalized();
|
||||
|
||||
return Out;
|
||||
}
|
||||
|
||||
CVector3f PointOnRay(float Distance) const { return mOrigin + (mDirection * Distance); }
|
||||
};
|
||||
|
||||
#endif // CRAY_H
|
|
@ -1,333 +0,0 @@
|
|||
#include "CTransform4f.h"
|
||||
#include "CVector3f.h"
|
||||
#include "CVector4f.h"
|
||||
#include "CQuaternion.h"
|
||||
#include "CMatrix4f.h"
|
||||
|
||||
// ************ CONSTRUCTRS ************
|
||||
CTransform4f::CTransform4f()
|
||||
{
|
||||
*this = skIdentity;
|
||||
}
|
||||
|
||||
CTransform4f::CTransform4f(const CMatrix4f& rkMtx)
|
||||
{
|
||||
for (int iRow = 0; iRow < 3; iRow++)
|
||||
for (int iCol = 0; iCol < 4; iCol++)
|
||||
m[iRow][iCol] = rkMtx[iRow][iCol];
|
||||
|
||||
SetupRow4();
|
||||
}
|
||||
|
||||
CTransform4f::CTransform4f(IInputStream& rInput)
|
||||
{
|
||||
for (int iVal = 0; iVal < 12; iVal++)
|
||||
_m[iVal] = rInput.ReadFloat();
|
||||
|
||||
SetupRow4();
|
||||
}
|
||||
|
||||
CTransform4f::CTransform4f(float Diagonal)
|
||||
{
|
||||
*this = skZero;
|
||||
m[0][0] = Diagonal;
|
||||
m[1][1] = Diagonal;
|
||||
m[2][2] = Diagonal;
|
||||
m[3][3] = 1.f;
|
||||
}
|
||||
|
||||
CTransform4f::CTransform4f(float m00, float m01, float m02, float m03,
|
||||
float m10, float m11, float m12, float m13,
|
||||
float m20, float m21, float m22, float m23)
|
||||
{
|
||||
m[0][0] = m00;
|
||||
m[0][1] = m01;
|
||||
m[0][2] = m02;
|
||||
m[0][3] = m03;
|
||||
m[1][0] = m10;
|
||||
m[1][1] = m11;
|
||||
m[1][2] = m12;
|
||||
m[1][3] = m13;
|
||||
m[2][0] = m20;
|
||||
m[2][1] = m21;
|
||||
m[2][2] = m22;
|
||||
m[2][3] = m23;
|
||||
SetupRow4();
|
||||
}
|
||||
|
||||
CTransform4f::CTransform4f(CVector3f Position, CQuaternion Rotation, CVector3f Scale)
|
||||
{
|
||||
*this = skIdentity;
|
||||
this->Scale(Scale);
|
||||
Rotate(Rotation);
|
||||
Translate(Position);
|
||||
}
|
||||
|
||||
CTransform4f::CTransform4f(CVector3f Position, CVector3f Rotation, CVector3f Scale)
|
||||
{
|
||||
*this = skIdentity;
|
||||
this->Scale(Scale);
|
||||
Rotate(Rotation);
|
||||
Translate(Position);
|
||||
}
|
||||
|
||||
void CTransform4f::Serialize(IArchive& rOut)
|
||||
{
|
||||
rOut << SerialParameter("Row0Col0", m[0][0]) << SerialParameter("Row0Col1", m[0][1]) << SerialParameter("Row0Col2", m[0][2]) << SerialParameter("Row0Col3", m[0][3])
|
||||
<< SerialParameter("Row1Col0", m[1][0]) << SerialParameter("Row1Col1", m[1][1]) << SerialParameter("Row1Col2", m[1][2]) << SerialParameter("Row1Col3", m[1][3])
|
||||
<< SerialParameter("Row2Col0", m[2][0]) << SerialParameter("Row2Col1", m[2][1]) << SerialParameter("Row2Col2", m[2][2]) << SerialParameter("Row2Col3", m[2][3]);
|
||||
}
|
||||
|
||||
void CTransform4f::Write(IOutputStream& rOut)
|
||||
{
|
||||
for (int iFlt = 0; iFlt < 12; iFlt++)
|
||||
rOut.WriteFloat(_m[iFlt]);
|
||||
}
|
||||
|
||||
// ************ MATH ************
|
||||
void CTransform4f::Translate(CVector3f Translation)
|
||||
{
|
||||
CTransform4f TranslateMtx = CTransform4f::TranslationMatrix(Translation);
|
||||
*this = TranslateMtx * *this;
|
||||
}
|
||||
|
||||
void CTransform4f::Translate(float XTrans, float YTrans, float ZTrans)
|
||||
{
|
||||
Translate(CVector3f(XTrans, YTrans, ZTrans));
|
||||
}
|
||||
|
||||
void CTransform4f::Rotate(CQuaternion Rotation)
|
||||
{
|
||||
CTransform4f RotateMtx = CTransform4f::RotationMatrix(Rotation);
|
||||
*this = RotateMtx * *this;
|
||||
}
|
||||
|
||||
void CTransform4f::Rotate(CVector3f Rotation)
|
||||
{
|
||||
CQuaternion quat = CQuaternion::FromEuler(Rotation);
|
||||
Rotate(quat);
|
||||
}
|
||||
|
||||
void CTransform4f::Rotate(float XRot, float YRot, float ZRot)
|
||||
{
|
||||
Rotate(CVector3f(XRot, YRot, ZRot));
|
||||
}
|
||||
|
||||
void CTransform4f::Scale(CVector3f Scale)
|
||||
{
|
||||
CTransform4f ScaleMtx = CTransform4f::ScaleMatrix(Scale);
|
||||
*this = ScaleMtx * *this;
|
||||
}
|
||||
|
||||
void CTransform4f::Scale(float XScale, float YScale, float ZScale)
|
||||
{
|
||||
Scale(CVector3f(XScale, YScale, ZScale));
|
||||
}
|
||||
|
||||
void CTransform4f::SetIdentity()
|
||||
{
|
||||
*this = skIdentity;
|
||||
}
|
||||
|
||||
void CTransform4f::ZeroTranslation()
|
||||
{
|
||||
m[0][3] = 0.f;
|
||||
m[1][3] = 0.f;
|
||||
m[2][3] = 0.f;
|
||||
}
|
||||
|
||||
CTransform4f CTransform4f::MultiplyIgnoreTranslation(const CTransform4f& rkMtx) const
|
||||
{
|
||||
CTransform4f Out;
|
||||
Out[0][0] = (m[0][0] * rkMtx[0][0]) + (m[0][1] * rkMtx[1][0]) + (m[0][2] * rkMtx[2][0]);
|
||||
Out[0][1] = (m[0][0] * rkMtx[0][1]) + (m[0][1] * rkMtx[1][1]) + (m[0][2] * rkMtx[2][1]);
|
||||
Out[0][2] = (m[0][0] * rkMtx[0][2]) + (m[0][1] * rkMtx[1][2]) + (m[0][2] * rkMtx[2][2]);
|
||||
Out[1][0] = (m[1][0] * rkMtx[0][0]) + (m[1][1] * rkMtx[1][0]) + (m[1][2] * rkMtx[2][0]);
|
||||
Out[1][1] = (m[1][0] * rkMtx[0][1]) + (m[1][1] * rkMtx[1][1]) + (m[1][2] * rkMtx[2][1]);
|
||||
Out[1][2] = (m[1][0] * rkMtx[0][2]) + (m[1][1] * rkMtx[1][2]) + (m[1][2] * rkMtx[2][2]);
|
||||
Out[2][0] = (m[2][0] * rkMtx[0][0]) + (m[2][1] * rkMtx[1][0]) + (m[2][2] * rkMtx[2][0]);
|
||||
Out[2][1] = (m[2][0] * rkMtx[0][1]) + (m[2][1] * rkMtx[1][1]) + (m[2][2] * rkMtx[2][1]);
|
||||
Out[2][2] = (m[2][0] * rkMtx[0][2]) + (m[2][1] * rkMtx[1][2]) + (m[2][2] * rkMtx[2][2]);
|
||||
Out[0][3] = 0.f;
|
||||
Out[1][3] = 0.f;
|
||||
Out[2][3] = 0.f;
|
||||
return Out;
|
||||
}
|
||||
|
||||
CTransform4f CTransform4f::QuickInverse() const
|
||||
{
|
||||
CTransform4f Out;
|
||||
Out[0][0] = m[0][0];
|
||||
Out[0][1] = m[1][0];
|
||||
Out[0][2] = m[2][0];
|
||||
Out[0][3] = -((m[0][0] * m[0][3]) + (m[1][0] * m[1][3]) + (m[2][0] * m[2][3]));
|
||||
Out[1][0] = m[0][1];
|
||||
Out[1][1] = m[1][1];
|
||||
Out[1][2] = m[2][1];
|
||||
Out[1][3] = -((m[0][1] * m[0][3]) + (m[1][1] * m[1][3]) + (m[2][1] * m[2][3]));
|
||||
Out[2][0] = m[0][2];
|
||||
Out[2][1] = m[1][2];
|
||||
Out[2][2] = m[2][2];
|
||||
Out[2][3] = -((m[0][2] * m[0][3]) + (m[1][2] * m[1][3]) + (m[2][2] * m[2][3]));
|
||||
return Out;
|
||||
}
|
||||
|
||||
CTransform4f CTransform4f::NoTranslation() const
|
||||
{
|
||||
return CTransform4f(m[0][0], m[0][1], m[0][2], 0.f,
|
||||
m[1][0], m[1][1], m[1][2], 0.f,
|
||||
m[2][0], m[2][1], m[2][2], 0.f);
|
||||
}
|
||||
|
||||
CTransform4f CTransform4f::TranslationOnly() const
|
||||
{
|
||||
return CTransform4f(1.f, 0.f, 0.f, m[0][3],
|
||||
0.f, 1.f, 0.f, m[1][3],
|
||||
0.f, 0.f, 1.f, m[2][3]);
|
||||
}
|
||||
|
||||
CTransform4f CTransform4f::RotationOnly() const
|
||||
{
|
||||
return Inverse().Transpose();
|
||||
}
|
||||
|
||||
CVector3f CTransform4f::ExtractTranslation() const
|
||||
{
|
||||
return CVector3f(m[0][3], m[1][3], m[2][3]);
|
||||
}
|
||||
|
||||
CQuaternion CTransform4f::ExtractRotation() const
|
||||
{
|
||||
// todo: there's probably a faster way to do this...
|
||||
return CQuaternion::FromRotationMatrix(Inverse().Transpose());
|
||||
}
|
||||
|
||||
// ************ OPERATORS ************
|
||||
float* CTransform4f::operator[](long Index)
|
||||
{
|
||||
return m[Index];
|
||||
}
|
||||
|
||||
const float* CTransform4f::operator[](long Index) const
|
||||
{
|
||||
return m[Index];
|
||||
}
|
||||
|
||||
CVector3f CTransform4f::operator*(const CVector3f& rkVec) const
|
||||
{
|
||||
CVector3f Out;
|
||||
Out.X = (m[0][0] * rkVec.X) + (m[0][1] * rkVec.Y) + (m[0][2] * rkVec.Z) + (m[0][3]);
|
||||
Out.Y = (m[1][0] * rkVec.X) + (m[1][1] * rkVec.Y) + (m[1][2] * rkVec.Z) + (m[1][3]);
|
||||
Out.Z = (m[2][0] * rkVec.X) + (m[2][1] * rkVec.Y) + (m[2][2] * rkVec.Z) + (m[2][3]);
|
||||
return Out;
|
||||
}
|
||||
|
||||
CVector4f CTransform4f::operator*(const CVector4f& rkVec) const
|
||||
{
|
||||
CVector4f Out;
|
||||
Out.X = (m[0][0] * rkVec.X) + (m[0][1] * rkVec.Y) + (m[0][2] * rkVec.Z) + (m[0][3] * rkVec.W);
|
||||
Out.Y = (m[1][0] * rkVec.X) + (m[1][1] * rkVec.Y) + (m[1][2] * rkVec.Z) + (m[1][3] * rkVec.W);
|
||||
Out.Z = (m[2][0] * rkVec.X) + (m[2][1] * rkVec.Y) + (m[2][2] * rkVec.Z) + (m[2][3] * rkVec.W);
|
||||
Out.W = rkVec.W;
|
||||
return Out;
|
||||
}
|
||||
|
||||
CQuaternion CTransform4f::operator*(const CQuaternion& rkQuat) const
|
||||
{
|
||||
return ExtractRotation() * rkQuat;
|
||||
}
|
||||
|
||||
CTransform4f CTransform4f::operator*(const CTransform4f& rkMtx) const
|
||||
{
|
||||
CTransform4f Out;
|
||||
Out[0][0] = (m[0][0] * rkMtx[0][0]) + (m[0][1] * rkMtx[1][0]) + (m[0][2] * rkMtx[2][0]);
|
||||
Out[0][1] = (m[0][0] * rkMtx[0][1]) + (m[0][1] * rkMtx[1][1]) + (m[0][2] * rkMtx[2][1]);
|
||||
Out[0][2] = (m[0][0] * rkMtx[0][2]) + (m[0][1] * rkMtx[1][2]) + (m[0][2] * rkMtx[2][2]);
|
||||
Out[0][3] = (m[0][0] * rkMtx[0][3]) + (m[0][1] * rkMtx[1][3]) + (m[0][2] * rkMtx[2][3]) + m[0][3];
|
||||
Out[1][0] = (m[1][0] * rkMtx[0][0]) + (m[1][1] * rkMtx[1][0]) + (m[1][2] * rkMtx[2][0]);
|
||||
Out[1][1] = (m[1][0] * rkMtx[0][1]) + (m[1][1] * rkMtx[1][1]) + (m[1][2] * rkMtx[2][1]);
|
||||
Out[1][2] = (m[1][0] * rkMtx[0][2]) + (m[1][1] * rkMtx[1][2]) + (m[1][2] * rkMtx[2][2]);
|
||||
Out[1][3] = (m[1][0] * rkMtx[0][3]) + (m[1][1] * rkMtx[1][3]) + (m[1][2] * rkMtx[2][3]) + m[1][3];
|
||||
Out[2][0] = (m[2][0] * rkMtx[0][0]) + (m[2][1] * rkMtx[1][0]) + (m[2][2] * rkMtx[2][0]);
|
||||
Out[2][1] = (m[2][0] * rkMtx[0][1]) + (m[2][1] * rkMtx[1][1]) + (m[2][2] * rkMtx[2][1]);
|
||||
Out[2][2] = (m[2][0] * rkMtx[0][2]) + (m[2][1] * rkMtx[1][2]) + (m[2][2] * rkMtx[2][2]);
|
||||
Out[2][3] = (m[2][0] * rkMtx[0][3]) + (m[2][1] * rkMtx[1][3]) + (m[2][2] * rkMtx[2][3]) + m[2][3];
|
||||
return Out;
|
||||
}
|
||||
|
||||
void CTransform4f::operator*=(const CTransform4f& rkMtx)
|
||||
{
|
||||
*this = *this * rkMtx;
|
||||
}
|
||||
|
||||
bool CTransform4f::operator==(const CTransform4f& rkMtx) const
|
||||
{
|
||||
return ((m[0][0] == rkMtx[0][0]) &&
|
||||
(m[0][1] == rkMtx[0][1]) &&
|
||||
(m[0][2] == rkMtx[0][2]) &&
|
||||
(m[0][3] == rkMtx[0][3]) &&
|
||||
(m[1][0] == rkMtx[1][0]) &&
|
||||
(m[1][1] == rkMtx[1][1]) &&
|
||||
(m[1][2] == rkMtx[1][2]) &&
|
||||
(m[1][3] == rkMtx[1][3]) &&
|
||||
(m[2][0] == rkMtx[2][0]) &&
|
||||
(m[2][1] == rkMtx[2][1]) &&
|
||||
(m[2][2] == rkMtx[2][2]) &&
|
||||
(m[2][3] == rkMtx[2][3]));
|
||||
}
|
||||
|
||||
bool CTransform4f::operator!=(const CTransform4f& rkMtx) const
|
||||
{
|
||||
return (!(*this == rkMtx));
|
||||
}
|
||||
|
||||
// ************ STATIC ************
|
||||
CTransform4f CTransform4f::TranslationMatrix(CVector3f Translation)
|
||||
{
|
||||
CTransform4f Out = skIdentity;
|
||||
Out[0][3] = Translation.X;
|
||||
Out[1][3] = Translation.Y;
|
||||
Out[2][3] = Translation.Z;
|
||||
return Out;
|
||||
}
|
||||
|
||||
CTransform4f CTransform4f::RotationMatrix(CQuaternion Rotation)
|
||||
{
|
||||
CTransform4f Out = skIdentity;
|
||||
float X = Rotation.X;
|
||||
float Y = Rotation.Y;
|
||||
float Z = Rotation.Z;
|
||||
float W = Rotation.W;
|
||||
float X2 = X * X;
|
||||
float Y2 = Y * Y;
|
||||
float Z2 = Z * Z;
|
||||
|
||||
Out[0][0] = 1.0f - (2 * Y2) - (2 * Z2);
|
||||
Out[0][1] = (2 * X * Y) - (2 * Z * W);
|
||||
Out[0][2] = (2 * X * Z) + (2 * Y * W);
|
||||
Out[1][0] = (2 * X * Y) + (2 * Z * W);
|
||||
Out[1][1] = 1.0f - (2 * X2) - (2 * Z2);
|
||||
Out[1][2] = (2 * Y * Z) - (2 * X * W);
|
||||
Out[2][0] = (2 * X * Z) - (2 * Y * W);
|
||||
Out[2][1] = (2 * Y * Z) + (2 * X * W);
|
||||
Out[2][2] = 1.0f - (2 * X2) - (2 * Y2);
|
||||
return Out;
|
||||
}
|
||||
|
||||
CTransform4f CTransform4f::ScaleMatrix(CVector3f Scale)
|
||||
{
|
||||
CTransform4f Out = skIdentity;
|
||||
Out[0][0] = Scale.X;
|
||||
Out[1][1] = Scale.Y;
|
||||
Out[2][2] = Scale.Z;
|
||||
return Out;
|
||||
}
|
||||
|
||||
// ************ CONSTANTS ************
|
||||
const CTransform4f CTransform4f::skIdentity(1.0f, 0.0f, 0.0f, 0.0f,
|
||||
0.0f, 1.0f, 0.0f, 0.0f,
|
||||
0.0f, 0.0f, 1.0f, 0.0f);
|
||||
|
||||
const CTransform4f CTransform4f::skZero(0.0f, 0.0f, 0.0f, 0.0f,
|
||||
0.0f, 0.0f, 0.0f, 0.0f,
|
||||
0.0f, 0.0f, 0.0f, 0.0f);
|
|
@ -1,77 +0,0 @@
|
|||
#ifndef CTRANSFORM4F_H
|
||||
#define CTRANSFORM4F_H
|
||||
|
||||
#include <Common/FileIO.h>
|
||||
#include <Common/Serialization/IArchive.h>
|
||||
#include "CMatrix4f.h"
|
||||
|
||||
class CVector3f;
|
||||
class CVector4f;
|
||||
class CQuaternion;
|
||||
|
||||
class CTransform4f : public CMatrix4f
|
||||
{
|
||||
public:
|
||||
CTransform4f();
|
||||
CTransform4f(const CMatrix4f& rkMtx);
|
||||
CTransform4f(IInputStream& rInput);
|
||||
CTransform4f(float Diagonal);
|
||||
CTransform4f(float m00, float m01, float m02, float m03,
|
||||
float m10, float m11, float m12, float m13,
|
||||
float m20, float m21, float m22, float m23);
|
||||
CTransform4f(CVector3f Position, CQuaternion Rotation, CVector3f Scale);
|
||||
CTransform4f(CVector3f Position, CVector3f Rotation, CVector3f Scale);
|
||||
void Serialize(IArchive& rOut);
|
||||
void Write(IOutputStream& rOut);
|
||||
|
||||
// Math
|
||||
void Translate(CVector3f Translation);
|
||||
void Translate(float XTrans, float YTrans, float ZTrans);
|
||||
void Rotate(CQuaternion Rotation);
|
||||
void Rotate(CVector3f Rotation);
|
||||
void Rotate(float XRot, float YRot, float ZRot);
|
||||
void Scale(CVector3f Scale);
|
||||
void Scale(float XScale, float YScale, float ZScale);
|
||||
void SetIdentity();
|
||||
void ZeroTranslation();
|
||||
CTransform4f MultiplyIgnoreTranslation(const CTransform4f& rkMtx) const;
|
||||
CTransform4f QuickInverse() const;
|
||||
CTransform4f NoTranslation() const;
|
||||
CTransform4f TranslationOnly() const;
|
||||
CTransform4f RotationOnly() const;
|
||||
|
||||
CVector3f ExtractTranslation() const;
|
||||
CQuaternion ExtractRotation() const;
|
||||
|
||||
// Static
|
||||
static CTransform4f TranslationMatrix(CVector3f Translation);
|
||||
static CTransform4f RotationMatrix(CQuaternion Rotation);
|
||||
static CTransform4f ScaleMatrix(CVector3f Scale);
|
||||
|
||||
// Operators
|
||||
float* operator[](long Index);
|
||||
const float* operator[](long Index) const;
|
||||
CVector3f operator*(const CVector3f& rkVec) const;
|
||||
CVector4f operator*(const CVector4f& rkVec) const;
|
||||
CQuaternion operator*(const CQuaternion& rkQuat) const;
|
||||
CTransform4f operator*(const CTransform4f& rkMtx) const;
|
||||
void operator*=(const CTransform4f& rkMtx);
|
||||
bool operator==(const CTransform4f& rkMtx) const;
|
||||
bool operator!=(const CTransform4f& rkMtx) const;
|
||||
|
||||
// Constant
|
||||
static const CTransform4f skIdentity;
|
||||
static const CTransform4f skZero;
|
||||
|
||||
// Protected Utility
|
||||
protected:
|
||||
inline void SetupRow4()
|
||||
{
|
||||
m[3][0] = 0.f;
|
||||
m[3][1] = 0.f;
|
||||
m[3][2] = 0.f;
|
||||
m[3][3] = 1.f;
|
||||
}
|
||||
};
|
||||
|
||||
#endif // CTRANSFORM4F_H
|
|
@ -1,186 +0,0 @@
|
|||
#include "CVector2f.h"
|
||||
|
||||
CVector2f::CVector2f()
|
||||
{
|
||||
X = Y = 0.f;
|
||||
}
|
||||
|
||||
CVector2f::CVector2f(float XY)
|
||||
{
|
||||
X = Y = XY;
|
||||
}
|
||||
|
||||
CVector2f::CVector2f(float _X, float _Y)
|
||||
{
|
||||
X = _X;
|
||||
Y = _Y;
|
||||
}
|
||||
|
||||
CVector2f::CVector2f(IInputStream& rInput)
|
||||
{
|
||||
X = rInput.ReadFloat();
|
||||
Y = rInput.ReadFloat();
|
||||
}
|
||||
|
||||
void CVector2f::Write(IOutputStream& rOutput) const
|
||||
{
|
||||
rOutput.WriteFloat(X);
|
||||
rOutput.WriteFloat(Y);
|
||||
}
|
||||
|
||||
float CVector2f::Magnitude() const
|
||||
{
|
||||
return sqrtf(SquaredMagnitude());
|
||||
}
|
||||
|
||||
float CVector2f::SquaredMagnitude() const
|
||||
{
|
||||
return Dot(*this);
|
||||
}
|
||||
|
||||
CVector2f CVector2f::Normalized() const
|
||||
{
|
||||
return *this / Magnitude();
|
||||
}
|
||||
|
||||
float CVector2f::Dot(const CVector2f& rkOther) const
|
||||
{
|
||||
return ((X * rkOther.X) + (Y * rkOther.Y));
|
||||
}
|
||||
|
||||
CVector2f CVector2f::operator+(const CVector2f& rkSrc) const
|
||||
{
|
||||
CVector2f Out;
|
||||
Out.X = this->X + rkSrc.X;
|
||||
Out.Y = this->Y + rkSrc.Y;
|
||||
return Out;
|
||||
}
|
||||
|
||||
CVector2f CVector2f::operator-(const CVector2f& rkSrc) const
|
||||
{
|
||||
CVector2f Out;
|
||||
Out.X = this->X - rkSrc.X;
|
||||
Out.Y = this->Y - rkSrc.Y;
|
||||
return Out;
|
||||
}
|
||||
|
||||
CVector2f CVector2f::operator*(const CVector2f& rkSrc) const
|
||||
{
|
||||
CVector2f Out;
|
||||
Out.X = this->X * rkSrc.X;
|
||||
Out.Y = this->Y * rkSrc.Y;
|
||||
return Out;
|
||||
}
|
||||
|
||||
CVector2f CVector2f::operator/(const CVector2f& rkSrc) const
|
||||
{
|
||||
CVector2f Out;
|
||||
Out.X = this->X / rkSrc.X;
|
||||
Out.Y = this->Y / rkSrc.Y;
|
||||
return Out;
|
||||
}
|
||||
|
||||
void CVector2f::operator+=(const CVector2f& rkOther)
|
||||
{
|
||||
*this = *this + rkOther;
|
||||
}
|
||||
|
||||
void CVector2f::operator-=(const CVector2f& rkOther)
|
||||
{
|
||||
*this = *this - rkOther;
|
||||
}
|
||||
|
||||
void CVector2f::operator*=(const CVector2f& rkOther)
|
||||
{
|
||||
*this = *this * rkOther;
|
||||
}
|
||||
|
||||
void CVector2f::operator/=(const CVector2f& rkOther)
|
||||
{
|
||||
*this = *this / rkOther;
|
||||
}
|
||||
|
||||
CVector2f CVector2f::operator+(const float Src) const
|
||||
{
|
||||
CVector2f Out;
|
||||
Out.X = this->X + Src;
|
||||
Out.Y = this->Y + Src;
|
||||
return Out;
|
||||
}
|
||||
|
||||
CVector2f CVector2f::operator-(const float Src) const
|
||||
{
|
||||
CVector2f Out;
|
||||
Out.X = this->X - Src;
|
||||
Out.Y = this->Y - Src;
|
||||
return Out;
|
||||
}
|
||||
|
||||
CVector2f CVector2f::operator*(const float Src) const
|
||||
{
|
||||
CVector2f Out;
|
||||
Out.X = this->X * Src;
|
||||
Out.Y = this->Y * Src;
|
||||
return Out;
|
||||
}
|
||||
|
||||
CVector2f CVector2f::operator/(const float Src) const
|
||||
{
|
||||
CVector2f Out;
|
||||
Out.X = this->X / Src;
|
||||
Out.Y = this->Y / Src;
|
||||
return Out;
|
||||
}
|
||||
|
||||
void CVector2f::operator+=(const float Other)
|
||||
{
|
||||
*this = *this + Other;
|
||||
}
|
||||
|
||||
void CVector2f::operator-=(const float Other)
|
||||
{
|
||||
*this = *this - Other;
|
||||
}
|
||||
|
||||
void CVector2f::operator*=(const float Other)
|
||||
{
|
||||
*this = *this * Other;
|
||||
}
|
||||
|
||||
void CVector2f::operator/=(const float Other)
|
||||
{
|
||||
*this = *this / Other;
|
||||
}
|
||||
|
||||
bool CVector2f::operator==(const CVector2f& rkOther) const
|
||||
{
|
||||
return ((X == rkOther.X) && (Y == rkOther.Y));
|
||||
}
|
||||
|
||||
bool CVector2f::operator!=(const CVector2f& rkOther) const
|
||||
{
|
||||
return (!(*this == rkOther));
|
||||
}
|
||||
|
||||
CVector2f CVector2f::operator-() const
|
||||
{
|
||||
return CVector2f(-X, -Y);
|
||||
}
|
||||
|
||||
float& CVector2f::operator[](long Index)
|
||||
{
|
||||
return (&X)[Index];
|
||||
}
|
||||
|
||||
const float& CVector2f::operator[](long Index) const
|
||||
{
|
||||
return (&X)[Index];
|
||||
}
|
||||
|
||||
// ************ STATIC MEMBER INITIALIZATION ************
|
||||
const CVector2f CVector2f::skZero = CVector2f(0, 0);
|
||||
const CVector2f CVector2f::skOne = CVector2f(1, 1);
|
||||
const CVector2f CVector2f::skUp = CVector2f(0, 1);
|
||||
const CVector2f CVector2f::skRight = CVector2f(1, 0);
|
||||
const CVector2f CVector2f::skDown = CVector2f(0,-1);
|
||||
const CVector2f CVector2f::skLeft = CVector2f(-1,0);
|
|
@ -1,53 +0,0 @@
|
|||
#ifndef CVECTOR2F
|
||||
#define CVECTOR2F
|
||||
|
||||
#include <Common/FileIO/IInputStream.h>
|
||||
#include <Common/FileIO/IOutputStream.h>
|
||||
|
||||
class CVector2f
|
||||
{
|
||||
public:
|
||||
float X, Y;
|
||||
CVector2f();
|
||||
CVector2f(float XY);
|
||||
CVector2f(float _X, float _Y);
|
||||
CVector2f(IInputStream& rInput);
|
||||
void Write(IOutputStream& rOutput) const;
|
||||
|
||||
float Magnitude() const;
|
||||
float SquaredMagnitude() const;
|
||||
CVector2f Normalized() const;
|
||||
float Dot(const CVector2f& rkOther) const;
|
||||
|
||||
CVector2f operator+(const CVector2f& rkOther) const;
|
||||
CVector2f operator-(const CVector2f& rkOther) const;
|
||||
CVector2f operator*(const CVector2f& rkOther) const;
|
||||
CVector2f operator/(const CVector2f& rkOther) const;
|
||||
void operator+=(const CVector2f& rkOther);
|
||||
void operator-=(const CVector2f& rkOther);
|
||||
void operator*=(const CVector2f& rkOther);
|
||||
void operator/=(const CVector2f& rkOther);
|
||||
CVector2f operator+(const float Other) const;
|
||||
CVector2f operator-(const float Other) const;
|
||||
CVector2f operator*(const float Other) const;
|
||||
CVector2f operator/(const float Other) const;
|
||||
void operator+=(const float Other);
|
||||
void operator-=(const float Other);
|
||||
void operator*=(const float Other);
|
||||
void operator/=(const float Other);
|
||||
bool operator==(const CVector2f& rkOther) const;
|
||||
bool operator!=(const CVector2f& rkOther) const;
|
||||
CVector2f operator-() const;
|
||||
float& operator[](long Index);
|
||||
const float& operator[](long Index) const;
|
||||
|
||||
// Static Members
|
||||
static const CVector2f skZero;
|
||||
static const CVector2f skOne;
|
||||
static const CVector2f skUp;
|
||||
static const CVector2f skRight;
|
||||
static const CVector2f skDown;
|
||||
static const CVector2f skLeft;
|
||||
};
|
||||
|
||||
#endif // CVECTOR2F
|
|
@ -1,139 +0,0 @@
|
|||
#include "CVector2i.h"
|
||||
|
||||
CVector2i::CVector2i()
|
||||
{
|
||||
X = Y = 0;
|
||||
}
|
||||
|
||||
CVector2i::CVector2i(int XY)
|
||||
{
|
||||
X = Y = XY;
|
||||
}
|
||||
|
||||
CVector2i::CVector2i(int _X, int _Y)
|
||||
{
|
||||
X = _X;
|
||||
Y = _Y;
|
||||
}
|
||||
|
||||
CVector2i CVector2i::operator+(const CVector2i& rkOther) const
|
||||
{
|
||||
CVector2i Out;
|
||||
Out.X = this->X + rkOther.X;
|
||||
Out.Y = this->Y + rkOther.Y;
|
||||
return Out;
|
||||
}
|
||||
|
||||
CVector2i CVector2i::operator-(const CVector2i& rkOther) const
|
||||
{
|
||||
CVector2i Out;
|
||||
Out.X = this->X - rkOther.X;
|
||||
Out.Y = this->Y - rkOther.Y;
|
||||
return Out;
|
||||
}
|
||||
|
||||
CVector2i CVector2i::operator*(const CVector2i& rkOther) const
|
||||
{
|
||||
CVector2i Out;
|
||||
Out.X = this->X * rkOther.X;
|
||||
Out.Y = this->Y * rkOther.Y;
|
||||
return Out;
|
||||
}
|
||||
|
||||
CVector2i CVector2i::operator/(const CVector2i& rkOther) const
|
||||
{
|
||||
CVector2i Out;
|
||||
Out.X = this->X / rkOther.X;
|
||||
Out.Y = this->Y / rkOther.Y;
|
||||
return Out;
|
||||
}
|
||||
|
||||
void CVector2i::operator+=(const CVector2i& rkOther)
|
||||
{
|
||||
*this = *this + rkOther;
|
||||
}
|
||||
|
||||
void CVector2i::operator-=(const CVector2i& rkOther)
|
||||
{
|
||||
*this = *this - rkOther;
|
||||
}
|
||||
|
||||
void CVector2i::operator*=(const CVector2i& rkOther)
|
||||
{
|
||||
*this = *this * rkOther;
|
||||
}
|
||||
|
||||
void CVector2i::operator/=(const CVector2i& rkOther)
|
||||
{
|
||||
*this = *this / rkOther;
|
||||
}
|
||||
|
||||
CVector2i CVector2i::operator+(const int Other) const
|
||||
{
|
||||
CVector2i Out;
|
||||
Out.X = this->X + Other;
|
||||
Out.Y = this->Y + Other;
|
||||
return Out;
|
||||
}
|
||||
|
||||
CVector2i CVector2i::operator-(const int Other) const
|
||||
{
|
||||
CVector2i Out;
|
||||
Out.X = this->X - Other;
|
||||
Out.Y = this->Y - Other;
|
||||
return Out;
|
||||
}
|
||||
|
||||
CVector2i CVector2i::operator*(const int Other) const
|
||||
{
|
||||
CVector2i Out;
|
||||
Out.X = this->X * Other;
|
||||
Out.Y = this->Y * Other;
|
||||
return Out;
|
||||
}
|
||||
|
||||
CVector2i CVector2i::operator/(const int Other) const
|
||||
{
|
||||
CVector2i Out;
|
||||
Out.X = this->X / Other;
|
||||
Out.Y = this->Y / Other;
|
||||
return Out;
|
||||
}
|
||||
|
||||
void CVector2i::operator+=(const int Other)
|
||||
{
|
||||
*this = *this + Other;
|
||||
}
|
||||
|
||||
void CVector2i::operator-=(const int Other)
|
||||
{
|
||||
*this = *this - Other;
|
||||
}
|
||||
|
||||
void CVector2i::operator*=(const int Other)
|
||||
{
|
||||
*this = *this * Other;
|
||||
}
|
||||
|
||||
void CVector2i::operator/=(const int Other)
|
||||
{
|
||||
*this = *this / Other;
|
||||
}
|
||||
|
||||
bool CVector2i::operator==(const CVector2i& rkOther) const
|
||||
{
|
||||
return ((this->X == rkOther.X) && (this->Y == rkOther.Y));
|
||||
}
|
||||
|
||||
bool CVector2i::operator!=(const CVector2i& rkOther) const
|
||||
{
|
||||
return (!(*this == rkOther));
|
||||
}
|
||||
|
||||
int& CVector2i::operator[](int Index)
|
||||
{
|
||||
return (&X)[Index];
|
||||
}
|
||||
|
||||
// ************ STATIC MEMBER INTIALIZATION ************
|
||||
const CVector2i CVector2i::skZero = CVector2i(0,0);
|
|
@ -1,39 +0,0 @@
|
|||
#ifndef CVECTOR2I_H
|
||||
#define CVECTOR2I_H
|
||||
|
||||
#include <Common/FileIO/IInputStream.h>
|
||||
#include <Common/FileIO/IOutputStream.h>
|
||||
|
||||
class CVector2i
|
||||
{
|
||||
public:
|
||||
int X, Y;
|
||||
CVector2i();
|
||||
CVector2i(int XY);
|
||||
CVector2i(int _X, int _Y);
|
||||
|
||||
CVector2i operator+(const CVector2i& rkOther) const;
|
||||
CVector2i operator-(const CVector2i& rkOther) const;
|
||||
CVector2i operator*(const CVector2i& rkOther) const;
|
||||
CVector2i operator/(const CVector2i& rkOther) const;
|
||||
void operator+=(const CVector2i& rkOther);
|
||||
void operator-=(const CVector2i& rkOther);
|
||||
void operator*=(const CVector2i& rkOther);
|
||||
void operator/=(const CVector2i& rkOther);
|
||||
CVector2i operator+(const int Other) const;
|
||||
CVector2i operator-(const int Other) const;
|
||||
CVector2i operator*(const int Other) const;
|
||||
CVector2i operator/(const int Other) const;
|
||||
void operator+=(const int Other);
|
||||
void operator-=(const int Other);
|
||||
void operator*=(const int Other);
|
||||
void operator/=(const int Other);
|
||||
bool operator==(const CVector2i& rkOther) const;
|
||||
bool operator!=(const CVector2i& rkOther) const;
|
||||
int& operator[](int Index);
|
||||
|
||||
// Static Members
|
||||
static const CVector2i skZero;
|
||||
};
|
||||
|
||||
#endif // CVECTOR2I_H
|
|
@ -1,324 +0,0 @@
|
|||
#include "CVector3f.h"
|
||||
#include "CVector2f.h"
|
||||
#include "CVector4f.h"
|
||||
#include "CTransform4f.h"
|
||||
#include <iomanip>
|
||||
#include <float.h>
|
||||
|
||||
CVector3f::CVector3f()
|
||||
{
|
||||
X = Y = Z = 0.f;
|
||||
}
|
||||
|
||||
CVector3f::CVector3f(float XYZ)
|
||||
{
|
||||
X = Y = Z = XYZ;
|
||||
}
|
||||
|
||||
CVector3f::CVector3f(float _X, float _Y, float _Z)
|
||||
{
|
||||
X = _X;
|
||||
Y = _Y;
|
||||
Z = _Z;
|
||||
}
|
||||
|
||||
CVector3f::CVector3f(IInputStream& rInput)
|
||||
{
|
||||
X = rInput.ReadFloat();
|
||||
Y = rInput.ReadFloat();
|
||||
Z = rInput.ReadFloat();
|
||||
}
|
||||
|
||||
void CVector3f::Write(IOutputStream& rOutput) const
|
||||
{
|
||||
rOutput.WriteFloat(X);
|
||||
rOutput.WriteFloat(Y);
|
||||
rOutput.WriteFloat(Z);
|
||||
}
|
||||
|
||||
void CVector3f::Serialize(IArchive& rArc)
|
||||
{
|
||||
rArc << SerialParameter("X", X)
|
||||
<< SerialParameter("Y", Y)
|
||||
<< SerialParameter("Z", Z);
|
||||
}
|
||||
|
||||
TString CVector3f::ToString() const
|
||||
{
|
||||
return TString::Format("%s, %s, %s",
|
||||
*TString::FromFloat(X),
|
||||
*TString::FromFloat(Y),
|
||||
*TString::FromFloat(Z));
|
||||
}
|
||||
|
||||
// ************ SWIZZLE ************
|
||||
CVector2f CVector3f::XY()
|
||||
{
|
||||
return CVector2f(X, Y);
|
||||
}
|
||||
|
||||
CVector2f CVector3f::XZ()
|
||||
{
|
||||
return CVector2f(X, Z);
|
||||
}
|
||||
|
||||
CVector2f CVector3f::YZ()
|
||||
{
|
||||
return CVector2f(Y, Z);
|
||||
}
|
||||
|
||||
// ************ MATH ************
|
||||
float CVector3f::Magnitude() const
|
||||
{
|
||||
return sqrtf(SquaredMagnitude());
|
||||
}
|
||||
|
||||
float CVector3f::SquaredMagnitude() const
|
||||
{
|
||||
return Dot(*this);
|
||||
}
|
||||
|
||||
CVector3f CVector3f::Normalized() const
|
||||
{
|
||||
return *this / Magnitude();
|
||||
}
|
||||
|
||||
float CVector3f::Dot(const CVector3f& rkOther) const
|
||||
{
|
||||
return (X * rkOther.X) + (Y * rkOther.Y) + (Z * rkOther.Z);
|
||||
}
|
||||
|
||||
CVector3f CVector3f::Cross(const CVector3f& rkOther) const
|
||||
{
|
||||
return CVector3f((Y * rkOther.Z) - (Z * rkOther.Y), (Z * rkOther.X) - (X * rkOther.Z), (X * rkOther.Y) - (Y * rkOther.X));
|
||||
}
|
||||
|
||||
float CVector3f::Distance(const CVector3f& rkPoint) const
|
||||
{
|
||||
return (*this - rkPoint).Magnitude();
|
||||
}
|
||||
|
||||
float CVector3f::SquaredDistance(const CVector3f& rkPoint) const
|
||||
{
|
||||
return (*this - rkPoint).SquaredMagnitude();
|
||||
}
|
||||
|
||||
// ************ OPERATORS ************
|
||||
// VECTOR/VECTOR
|
||||
CVector3f CVector3f::operator+(const CVector3f& rkSrc) const
|
||||
{
|
||||
CVector3f Out;
|
||||
Out.X = this->X + rkSrc.X;
|
||||
Out.Y = this->Y + rkSrc.Y;
|
||||
Out.Z = this->Z + rkSrc.Z;
|
||||
return Out;
|
||||
}
|
||||
|
||||
CVector3f CVector3f::operator-(const CVector3f& rkSrc) const
|
||||
{
|
||||
CVector3f Out;
|
||||
Out.X = this->X - rkSrc.X;
|
||||
Out.Y = this->Y - rkSrc.Y;
|
||||
Out.Z = this->Z - rkSrc.Z;
|
||||
return Out;
|
||||
}
|
||||
|
||||
CVector3f CVector3f::operator*(const CVector3f& rkSrc) const
|
||||
{
|
||||
CVector3f Out;
|
||||
Out.X = this->X * rkSrc.X;
|
||||
Out.Y = this->Y * rkSrc.Y;
|
||||
Out.Z = this->Z * rkSrc.Z;
|
||||
return Out;
|
||||
}
|
||||
|
||||
CVector3f CVector3f::operator/(const CVector3f& rkSrc) const
|
||||
{
|
||||
CVector3f Out;
|
||||
Out.X = this->X / rkSrc.X;
|
||||
Out.Y = this->Y / rkSrc.Y;
|
||||
Out.Z = this->Z / rkSrc.Z;
|
||||
return Out;
|
||||
}
|
||||
|
||||
void CVector3f::operator+=(const CVector3f& rkOther)
|
||||
{
|
||||
*this = *this + rkOther;
|
||||
}
|
||||
|
||||
void CVector3f::operator-=(const CVector3f& rkOther)
|
||||
{
|
||||
*this = *this - rkOther;
|
||||
}
|
||||
|
||||
void CVector3f::operator*=(const CVector3f& rkOther)
|
||||
{
|
||||
*this = *this * rkOther;
|
||||
}
|
||||
|
||||
void CVector3f::operator/=(const CVector3f& rkOther)
|
||||
{
|
||||
*this = *this / rkOther;
|
||||
}
|
||||
|
||||
bool CVector3f::operator> (const CVector3f& rkOther) const
|
||||
{
|
||||
return ((X > rkOther.X) && (Y > rkOther.Y) && (Z > rkOther.Z));
|
||||
}
|
||||
|
||||
bool CVector3f::operator>=(const CVector3f& rkOther) const
|
||||
{
|
||||
return ((X >= rkOther.X) && (Y >= rkOther.Y) && (Z >= rkOther.Z));
|
||||
}
|
||||
|
||||
bool CVector3f::operator< (const CVector3f& rkOther) const
|
||||
{
|
||||
return ((X < rkOther.X) && (Y < rkOther.Y) && (Z < rkOther.Z));
|
||||
}
|
||||
|
||||
bool CVector3f::operator<=(const CVector3f& rkOther) const
|
||||
{
|
||||
return ((X <= rkOther.X) && (Y <= rkOther.Y) && (Z <= rkOther.Z));
|
||||
}
|
||||
|
||||
bool CVector3f::operator==(const CVector3f& rkOther) const
|
||||
{
|
||||
return ((X == rkOther.X) && (Y == rkOther.Y) && (Z == rkOther.Z));
|
||||
}
|
||||
|
||||
bool CVector3f::operator!=(const CVector3f& rkOther) const
|
||||
{
|
||||
return (!(*this == rkOther));
|
||||
}
|
||||
|
||||
// VECTOR/FLOAT
|
||||
CVector3f CVector3f::operator+(const float Src) const
|
||||
{
|
||||
CVector3f Out;
|
||||
Out.X = this->X + Src;
|
||||
Out.Y = this->Y + Src;
|
||||
Out.Z = this->Z + Src;
|
||||
return Out;
|
||||
}
|
||||
|
||||
CVector3f CVector3f::operator-(const float Src) const
|
||||
{
|
||||
CVector3f Out;
|
||||
Out.X = this->X - Src;
|
||||
Out.Y = this->Y - Src;
|
||||
Out.Z = this->Z - Src;
|
||||
return Out;
|
||||
}
|
||||
|
||||
CVector3f CVector3f::operator*(const float Src) const
|
||||
{
|
||||
CVector3f Out;
|
||||
Out.X = this->X * Src;
|
||||
Out.Y = this->Y * Src;
|
||||
Out.Z = this->Z * Src;
|
||||
return Out;
|
||||
}
|
||||
|
||||
CVector3f CVector3f::operator/(const float Src) const
|
||||
{
|
||||
CVector3f Out;
|
||||
Out.X = this->X / Src;
|
||||
Out.Y = this->Y / Src;
|
||||
Out.Z = this->Z / Src;
|
||||
return Out;
|
||||
}
|
||||
|
||||
void CVector3f::operator+=(const float Other)
|
||||
{
|
||||
*this = *this + Other;
|
||||
}
|
||||
|
||||
void CVector3f::operator-=(const float Other)
|
||||
{
|
||||
*this = *this - Other;
|
||||
}
|
||||
|
||||
void CVector3f::operator*=(const float Other)
|
||||
{
|
||||
*this = *this * Other;
|
||||
}
|
||||
|
||||
void CVector3f::operator/=(const float Other)
|
||||
{
|
||||
*this = *this / Other;
|
||||
}
|
||||
|
||||
// VECTOR/MATRIX
|
||||
CVector3f CVector3f::operator*(const CTransform4f& rkMtx) const
|
||||
{
|
||||
CVector3f Out;
|
||||
Out.X = (X * rkMtx[0][0]) + (Y * rkMtx[1][0]) + (Z * rkMtx[2][0]);
|
||||
Out.Y = (X * rkMtx[0][1]) + (Y * rkMtx[1][1]) + (Z * rkMtx[2][1]);
|
||||
Out.Z = (X * rkMtx[0][2]) + (Y * rkMtx[1][2]) + (Z * rkMtx[2][2]);
|
||||
return Out;
|
||||
}
|
||||
|
||||
void CVector3f::operator*=(const CTransform4f& rkMtx)
|
||||
{
|
||||
*this = *this * rkMtx;
|
||||
}
|
||||
|
||||
CVector3f CVector3f::operator*(const CMatrix4f& rkMtx) const
|
||||
{
|
||||
// To multiply by a Matrix4f, we consider the vector w component to be 1
|
||||
CVector3f Out;
|
||||
float W = (X * rkMtx[0][3]) + (Y * rkMtx[1][3]) + (Z * rkMtx[2][3]) + rkMtx[3][3];
|
||||
Out.X = ((X * rkMtx[0][0]) + (Y * rkMtx[1][0]) + (Z * rkMtx[2][0]) + rkMtx[3][0]) / W;
|
||||
Out.Y = ((X * rkMtx[0][1]) + (Y * rkMtx[1][1]) + (Z * rkMtx[2][1]) + rkMtx[3][1]) / W;
|
||||
Out.Z = ((X * rkMtx[0][2]) + (Y * rkMtx[1][2]) + (Z * rkMtx[2][2]) + rkMtx[3][2]) / W;
|
||||
return Out;
|
||||
}
|
||||
|
||||
// UNARY
|
||||
CVector3f CVector3f::operator-() const
|
||||
{
|
||||
return CVector3f(-X, -Y, -Z);
|
||||
}
|
||||
|
||||
float& CVector3f::operator[](long Index)
|
||||
{
|
||||
return (&X)[Index];
|
||||
}
|
||||
|
||||
const float& CVector3f::operator[](long Index) const
|
||||
{
|
||||
return (&X)[Index];
|
||||
}
|
||||
|
||||
// ************ CONSTANTS ************
|
||||
const CVector3f CVector3f::skZero = CVector3f(0.f);
|
||||
const CVector3f CVector3f::skOne = CVector3f(1.f);
|
||||
const CVector3f CVector3f::skInfinite = CVector3f(FLT_MAX);
|
||||
const CVector3f CVector3f::skUnitX = CVector3f(1.f, 0.f, 0.f);
|
||||
const CVector3f CVector3f::skUnitY = CVector3f(0.f, 1.f, 0.f);
|
||||
const CVector3f CVector3f::skUnitZ = CVector3f(0.f, 0.f, 1.f);
|
||||
const CVector3f CVector3f::skRight = CVector3f::skUnitX;
|
||||
const CVector3f CVector3f::skLeft = -CVector3f::skUnitX;
|
||||
const CVector3f CVector3f::skForward = CVector3f::skUnitY;
|
||||
const CVector3f CVector3f::skBack = -CVector3f::skUnitY;
|
||||
const CVector3f CVector3f::skUp = CVector3f::skUnitZ;
|
||||
const CVector3f CVector3f::skDown = -CVector3f::skUnitZ;
|
||||
|
||||
// ************ OTHER ************
|
||||
std::ostream& operator<<(std::ostream& rOut, const CVector3f& rkVector)
|
||||
{
|
||||
rOut << std::setprecision(6)
|
||||
<< std::fixed
|
||||
<< "["
|
||||
<< ((rkVector.X >= 0) ? " " : "")
|
||||
<< rkVector.X
|
||||
<< ", "
|
||||
<< ((rkVector.Y >= 0) ? " " : "")
|
||||
<< rkVector.Y
|
||||
<< ", "
|
||||
<< ((rkVector.Z >= 0) ? " " : "")
|
||||
<< rkVector.Z
|
||||
<< "]";
|
||||
|
||||
return rOut;
|
||||
}
|
|
@ -1,95 +0,0 @@
|
|||
#ifndef CVECTOR3F_H
|
||||
#define CVECTOR3F_H
|
||||
|
||||
#include <Common/FileIO/IInputStream.h>
|
||||
#include <Common/FileIO/IOutputStream.h>
|
||||
#include <Common/Serialization/IArchive.h>
|
||||
#include <ostream>
|
||||
|
||||
class CMatrix4f;
|
||||
class CVector2f;
|
||||
class CVector4f;
|
||||
class CTransform4f;
|
||||
|
||||
class CVector3f
|
||||
{
|
||||
public:
|
||||
float X, Y, Z;
|
||||
|
||||
CVector3f();
|
||||
CVector3f(float XYZ);
|
||||
CVector3f(float _X, float _Y, float _Z);
|
||||
CVector3f(IInputStream& rInput);
|
||||
void Write(IOutputStream& rOutput) const;
|
||||
void Serialize(IArchive& rArc);
|
||||
TString ToString() const;
|
||||
|
||||
// Swizzle
|
||||
CVector2f XY();
|
||||
CVector2f XZ();
|
||||
CVector2f YZ();
|
||||
|
||||
// Math
|
||||
float Magnitude() const;
|
||||
float SquaredMagnitude() const;
|
||||
CVector3f Normalized() const;
|
||||
float Dot(const CVector3f& rkOther) const;
|
||||
CVector3f Cross(const CVector3f& rkOther) const;
|
||||
float Distance(const CVector3f& rkPoint) const;
|
||||
float SquaredDistance(const CVector3f& rkPoint) const;
|
||||
|
||||
// Vector/Vector
|
||||
CVector3f operator+(const CVector3f& rkOther) const;
|
||||
CVector3f operator-(const CVector3f& rkOther) const;
|
||||
CVector3f operator*(const CVector3f& rkOther) const;
|
||||
CVector3f operator/(const CVector3f& rkOther) const;
|
||||
void operator+=(const CVector3f& rkOther);
|
||||
void operator-=(const CVector3f& rkOther);
|
||||
void operator*=(const CVector3f& rkOther);
|
||||
void operator/=(const CVector3f& rkOther);
|
||||
bool operator> (const CVector3f& rkOther) const;
|
||||
bool operator>=(const CVector3f& rkOther) const;
|
||||
bool operator< (const CVector3f& rkOther) const;
|
||||
bool operator<=(const CVector3f& rkOther) const;
|
||||
bool operator==(const CVector3f& rkOther) const;
|
||||
bool operator!=(const CVector3f& rkOther) const;
|
||||
|
||||
// Vector/Float
|
||||
CVector3f operator+(const float Other) const;
|
||||
CVector3f operator-(const float Other) const;
|
||||
CVector3f operator*(const float Other) const;
|
||||
CVector3f operator/(const float Other) const;
|
||||
void operator+=(const float Other);
|
||||
void operator-=(const float Other);
|
||||
void operator*=(const float Other);
|
||||
void operator/=(const float Other);
|
||||
|
||||
// Vector/Matrix
|
||||
CVector3f operator*(const CTransform4f& rkMtx) const;
|
||||
void operator*=(const CTransform4f& rkMtx);
|
||||
CVector3f operator*(const CMatrix4f& rkMtx) const;
|
||||
|
||||
// Unary
|
||||
CVector3f operator-() const;
|
||||
float& operator[](long Index);
|
||||
const float& operator[](long Index) const;
|
||||
|
||||
// Constants
|
||||
static const CVector3f skZero;
|
||||
static const CVector3f skOne;
|
||||
static const CVector3f skInfinite;
|
||||
static const CVector3f skUnitX;
|
||||
static const CVector3f skUnitY;
|
||||
static const CVector3f skUnitZ;
|
||||
static const CVector3f skRight;
|
||||
static const CVector3f skLeft;
|
||||
static const CVector3f skForward;
|
||||
static const CVector3f skBack;
|
||||
static const CVector3f skUp;
|
||||
static const CVector3f skDown;
|
||||
|
||||
// Other
|
||||
friend std::ostream& operator<<(std::ostream& rOut, const CVector3f& rkVector);
|
||||
};
|
||||
|
||||
#endif // CVECTOR3F_H
|
|
@ -1,273 +0,0 @@
|
|||
#include "CVector4f.h"
|
||||
#include "CVector2f.h"
|
||||
#include "CVector3f.h"
|
||||
#include "CTransform4f.h"
|
||||
|
||||
CVector4f::CVector4f()
|
||||
{
|
||||
X = Y = Z = W = 0.f;
|
||||
}
|
||||
|
||||
CVector4f::CVector4f(float XYZW)
|
||||
{
|
||||
X = Y = Z = W = XYZW;
|
||||
}
|
||||
|
||||
CVector4f::CVector4f(float _X, float _Y, float _Z, float _W)
|
||||
{
|
||||
X = _X;
|
||||
Y = _Y;
|
||||
Z = _Z;
|
||||
W = _W;
|
||||
}
|
||||
|
||||
CVector4f::CVector4f(const CVector2f& rkXY, float _Z, float _W)
|
||||
{
|
||||
X = rkXY.X;
|
||||
Y = rkXY.Y;
|
||||
Z = _Z;
|
||||
W = _W;
|
||||
}
|
||||
|
||||
CVector4f::CVector4f(const CVector3f& rkXYZ)
|
||||
{
|
||||
X = rkXYZ.X;
|
||||
Y = rkXYZ.Y;
|
||||
Z = rkXYZ.Z;
|
||||
W = 1.f;
|
||||
}
|
||||
|
||||
CVector4f::CVector4f(const CVector3f& rkXYZ, float _W)
|
||||
{
|
||||
X = rkXYZ.X;
|
||||
Y = rkXYZ.Y;
|
||||
Z = rkXYZ.Z;
|
||||
W = _W;
|
||||
}
|
||||
|
||||
CVector4f::CVector4f(IInputStream& rInput)
|
||||
{
|
||||
X = rInput.ReadFloat();
|
||||
Y = rInput.ReadFloat();
|
||||
Z = rInput.ReadFloat();
|
||||
W = rInput.ReadFloat();
|
||||
}
|
||||
|
||||
void CVector4f::Write(IOutputStream& rOutput)
|
||||
{
|
||||
rOutput.WriteFloat(X);
|
||||
rOutput.WriteFloat(Y);
|
||||
rOutput.WriteFloat(Z);
|
||||
rOutput.WriteFloat(W);
|
||||
}
|
||||
|
||||
// ************ SWIZZLE ************
|
||||
CVector3f CVector4f::XYZ() const
|
||||
{
|
||||
return CVector3f(X, Y, Z);
|
||||
}
|
||||
|
||||
CVector3f CVector4f::XZW() const
|
||||
{
|
||||
return CVector3f(X, Z, W);
|
||||
}
|
||||
|
||||
CVector3f CVector4f::YZW() const
|
||||
{
|
||||
return CVector3f(Y, Z, W);
|
||||
}
|
||||
|
||||
CVector2f CVector4f::XY() const
|
||||
{
|
||||
return CVector2f(X, Y);
|
||||
}
|
||||
|
||||
CVector2f CVector4f::XZ() const
|
||||
{
|
||||
return CVector2f(X, Z);
|
||||
}
|
||||
|
||||
CVector2f CVector4f::XW() const
|
||||
{
|
||||
return CVector2f(X, W);
|
||||
}
|
||||
|
||||
CVector2f CVector4f::YZ() const
|
||||
{
|
||||
return CVector2f(Y, Z);
|
||||
}
|
||||
|
||||
CVector2f CVector4f::YW() const
|
||||
{
|
||||
return CVector2f(Y, W);
|
||||
}
|
||||
|
||||
CVector2f CVector4f::ZW() const
|
||||
{
|
||||
return CVector2f(Z, W);
|
||||
}
|
||||
|
||||
// ************ MATH ************
|
||||
// ************ VECTOR/VECTOR ************
|
||||
CVector4f CVector4f::operator+(const CVector4f& rkSrc) const
|
||||
{
|
||||
CVector4f Out;
|
||||
Out.X = this->X + rkSrc.X;
|
||||
Out.Y = this->Y + rkSrc.Y;
|
||||
Out.Z = this->Z + rkSrc.Z;
|
||||
Out.W = this->W + rkSrc.W;
|
||||
return Out;
|
||||
}
|
||||
|
||||
CVector4f CVector4f::operator-(const CVector4f& rkSrc) const
|
||||
{
|
||||
CVector4f Out;
|
||||
Out.X = this->X - rkSrc.X;
|
||||
Out.Y = this->Y - rkSrc.Y;
|
||||
Out.Z = this->Z - rkSrc.Z;
|
||||
Out.W = this->W - rkSrc.W;
|
||||
return Out;
|
||||
}
|
||||
|
||||
CVector4f CVector4f::operator*(const CVector4f& rkSrc) const
|
||||
{
|
||||
CVector4f Out;
|
||||
Out.X = this->X * rkSrc.X;
|
||||
Out.Y = this->Y * rkSrc.Y;
|
||||
Out.Z = this->Z * rkSrc.Z;
|
||||
Out.W = this->W * rkSrc.W;
|
||||
return Out;
|
||||
}
|
||||
|
||||
CVector4f CVector4f::operator/(const CVector4f& rkSrc) const
|
||||
{
|
||||
CVector4f Out;
|
||||
Out.X = this->X / rkSrc.X;
|
||||
Out.Y = this->Y / rkSrc.Y;
|
||||
Out.Z = this->Z / rkSrc.Z;
|
||||
Out.W = this->W / rkSrc.W;
|
||||
return Out;
|
||||
}
|
||||
|
||||
void CVector4f::operator+=(const CVector4f& rkOther)
|
||||
{
|
||||
*this = *this + rkOther;
|
||||
}
|
||||
|
||||
void CVector4f::operator-=(const CVector4f& rkOther)
|
||||
{
|
||||
*this = *this - rkOther;
|
||||
}
|
||||
|
||||
void CVector4f::operator*=(const CVector4f& rkOther)
|
||||
{
|
||||
*this = *this * rkOther;
|
||||
}
|
||||
|
||||
void CVector4f::operator/=(const CVector4f& rkOther)
|
||||
{
|
||||
*this = *this / rkOther;
|
||||
}
|
||||
|
||||
bool CVector4f::operator==(const CVector4f& rkOther) const
|
||||
{
|
||||
return ((X == rkOther.X) && (Y == rkOther.Y) && (Z == rkOther.Z) && (W == rkOther.W));
|
||||
}
|
||||
|
||||
// ************ VECTOR/FLOAT ************
|
||||
CVector4f CVector4f::operator+(const float Src) const
|
||||
{
|
||||
CVector4f Out;
|
||||
Out.X = this->X + Src;
|
||||
Out.Y = this->Y + Src;
|
||||
Out.Z = this->Z + Src;
|
||||
Out.W = this->W + Src;
|
||||
return Out;
|
||||
}
|
||||
|
||||
CVector4f CVector4f::operator-(const float Src) const
|
||||
{
|
||||
CVector4f Out;
|
||||
Out.X = this->X - Src;
|
||||
Out.Y = this->Y - Src;
|
||||
Out.Z = this->Z - Src;
|
||||
Out.W = this->W - Src;
|
||||
return Out;
|
||||
}
|
||||
|
||||
CVector4f CVector4f::operator*(const float Src) const
|
||||
{
|
||||
CVector4f Out;
|
||||
Out.X = this->X * Src;
|
||||
Out.Y = this->Y * Src;
|
||||
Out.Z = this->Z * Src;
|
||||
Out.W = this->W * Src;
|
||||
return Out;
|
||||
}
|
||||
|
||||
CVector4f CVector4f::operator/(const float Src) const
|
||||
{
|
||||
CVector4f Out;
|
||||
Out.X = this->X / Src;
|
||||
Out.Y = this->Y / Src;
|
||||
Out.Z = this->Z / Src;
|
||||
Out.W = this->W / Src;
|
||||
return Out;
|
||||
}
|
||||
|
||||
void CVector4f::operator+=(const float Other)
|
||||
{
|
||||
*this = *this + Other;
|
||||
}
|
||||
|
||||
void CVector4f::operator-=(const float Other)
|
||||
{
|
||||
*this = *this - Other;
|
||||
}
|
||||
|
||||
void CVector4f::operator*=(const float Other)
|
||||
{
|
||||
*this = *this * Other;
|
||||
}
|
||||
|
||||
void CVector4f::operator/=(const float Other)
|
||||
{
|
||||
*this = *this / Other;
|
||||
}
|
||||
|
||||
// ************ VECTOR/MATRIX ************
|
||||
CVector4f CVector4f::operator*(const CTransform4f& rkMtx) const
|
||||
{
|
||||
CVector4f Out;
|
||||
Out.X = (X * rkMtx[0][0]) + (Y * rkMtx[1][0]) + (Z * rkMtx[2][0]);
|
||||
Out.Y = (X * rkMtx[0][1]) + (Y * rkMtx[1][1]) + (Z * rkMtx[2][1]);
|
||||
Out.Z = (X * rkMtx[0][2]) + (Y * rkMtx[1][2]) + (Z * rkMtx[2][2]);
|
||||
Out.W = (X * rkMtx[0][3]) + (Y * rkMtx[1][3]) + (Z * rkMtx[2][3]) + W;
|
||||
return Out;
|
||||
}
|
||||
|
||||
void CVector4f::operator*=(const CTransform4f& rkMtx)
|
||||
{
|
||||
*this = *this * rkMtx;
|
||||
}
|
||||
|
||||
CVector4f CVector4f::operator*(const CMatrix4f& rkMtx) const
|
||||
{
|
||||
CVector4f Out;
|
||||
Out.X = (X * rkMtx[0][0]) + (Y * rkMtx[1][0]) + (Z * rkMtx[2][0]) + (W * rkMtx[3][0]);
|
||||
Out.Y = (X * rkMtx[0][1]) + (Y * rkMtx[1][1]) + (Z * rkMtx[2][1]) + (W * rkMtx[3][1]);
|
||||
Out.Z = (X * rkMtx[0][2]) + (Y * rkMtx[1][2]) + (Z * rkMtx[2][2]) + (W * rkMtx[3][2]);
|
||||
Out.W = (X * rkMtx[0][3]) + (Y * rkMtx[1][3]) + (Z * rkMtx[2][3]) + (W * rkMtx[3][3]);
|
||||
return Out;
|
||||
}
|
||||
|
||||
void CVector4f::operator*=(const CMatrix4f& rkMtx)
|
||||
{
|
||||
*this = *this * rkMtx;
|
||||
}
|
||||
|
||||
// ************ UNARY ************
|
||||
float& CVector4f::operator[](long Index)
|
||||
{
|
||||
return (&X)[Index];
|
||||
}
|
|
@ -1,68 +0,0 @@
|
|||
#ifndef CVECTOR4F
|
||||
#define CVECTOR4F
|
||||
|
||||
#include <Common/FileIO/IInputStream.h>
|
||||
#include <Common/FileIO/IOutputStream.h>
|
||||
|
||||
class CMatrix4f;
|
||||
class CTransform4f;
|
||||
class CVector2f;
|
||||
class CVector3f;
|
||||
|
||||
class CVector4f
|
||||
{
|
||||
public:
|
||||
float X, Y, Z, W;
|
||||
|
||||
CVector4f();
|
||||
CVector4f(float XYZW);
|
||||
CVector4f(float _X, float _Y, float _Z, float _W);
|
||||
CVector4f(const CVector2f& rkXY, float _Z, float _W);
|
||||
CVector4f(const CVector3f& rkXYZ);
|
||||
CVector4f(const CVector3f& rkXYZ, float _W);
|
||||
CVector4f(IInputStream& rInput);
|
||||
void Write(IOutputStream& rOutput);
|
||||
|
||||
// Swizzle
|
||||
CVector3f XYZ() const;
|
||||
CVector3f XZW() const;
|
||||
CVector3f YZW() const;
|
||||
CVector2f XY() const;
|
||||
CVector2f XZ() const;
|
||||
CVector2f XW() const;
|
||||
CVector2f YZ() const;
|
||||
CVector2f YW() const;
|
||||
CVector2f ZW() const;
|
||||
|
||||
// Vector/Vector
|
||||
CVector4f operator+(const CVector4f& rkOther) const;
|
||||
CVector4f operator-(const CVector4f& rkOther) const;
|
||||
CVector4f operator*(const CVector4f& rkOther) const;
|
||||
CVector4f operator/(const CVector4f& rkOther) const;
|
||||
void operator+=(const CVector4f& rkOther);
|
||||
void operator-=(const CVector4f& rkOther);
|
||||
void operator*=(const CVector4f& rkOther);
|
||||
void operator/=(const CVector4f& rkOther);
|
||||
bool operator==(const CVector4f& rkOther) const;
|
||||
|
||||
// Vector/Float
|
||||
CVector4f operator+(const float Other) const;
|
||||
CVector4f operator-(const float Other) const;
|
||||
CVector4f operator*(const float Other) const;
|
||||
CVector4f operator/(const float Other) const;
|
||||
void operator+=(const float Other);
|
||||
void operator-=(const float Other);
|
||||
void operator*=(const float Other);
|
||||
void operator/=(const float Other);
|
||||
|
||||
// Vector/Matrix
|
||||
CVector4f operator*(const CTransform4f& rkMtx) const;
|
||||
void operator*=(const CTransform4f& rkMtx);
|
||||
CVector4f operator*(const CMatrix4f& rkMtx) const;
|
||||
void operator*=(const CMatrix4f& rkMtx);
|
||||
|
||||
// Unary
|
||||
float& operator[](long Index);
|
||||
};
|
||||
|
||||
#endif // CVECTOR4F
|
|
@ -1,11 +0,0 @@
|
|||
#ifndef ETRANSFORMSPACE
|
||||
#define ETRANSFORMSPACE
|
||||
|
||||
enum ETransformSpace
|
||||
{
|
||||
eWorldTransform,
|
||||
eLocalTransform
|
||||
};
|
||||
|
||||
#endif // ETRANSFORMSPACE
|
||||
|
|
@ -1,86 +0,0 @@
|
|||
#-------------------------------------------------
|
||||
#
|
||||
# Project created by QtCreator 2015-12-16T12:35:34
|
||||
#
|
||||
#-------------------------------------------------
|
||||
|
||||
QT -= core gui
|
||||
DEFINES += PWE_MATH
|
||||
|
||||
CONFIG += staticlib
|
||||
TEMPLATE = lib
|
||||
DESTDIR = $$BUILD_DIR/Math
|
||||
|
||||
unix {
|
||||
target.path = /usr/lib
|
||||
QMAKE_CXXFLAGS += /WX
|
||||
INSTALLS += target
|
||||
}
|
||||
|
||||
CONFIG (debug, debug|release) {
|
||||
# Debug Config
|
||||
OBJECTS_DIR = $$BUILD_DIR/Math/debug
|
||||
TARGET = Mathd
|
||||
|
||||
# Debug Libs
|
||||
LIBS += -L$$BUILD_DIR/Common/ -lCommond
|
||||
|
||||
# Debug Target Dependencies
|
||||
win32 {
|
||||
PRE_TARGETDEPS += $$BUILD_DIR/Common/Commond.lib
|
||||
}
|
||||
}
|
||||
|
||||
CONFIG (release, debug|release) {
|
||||
# Release Config
|
||||
OBJECTS_DIR = $$BUILD_DIR/Math/release
|
||||
TARGET = Math
|
||||
|
||||
# Release Libs
|
||||
LIBS += -L$$BUILD_DIR/Common/ -lCommon
|
||||
|
||||
# Release Target Dependencies
|
||||
win32 {
|
||||
PRE_TARGETDEPS += $$BUILD_DIR/Common/Common.lib
|
||||
}
|
||||
}
|
||||
|
||||
# Include Paths
|
||||
INCLUDEPATH += $$PWE_MAIN_INCLUDE \
|
||||
$$EXTERNALS_DIR/CodeGen/include \
|
||||
$$EXTERNALS_DIR/tinyxml2
|
||||
|
||||
# Header Files
|
||||
HEADERS += \
|
||||
CAABox.h \
|
||||
CFrustumPlanes.h \
|
||||
CMatrix4f.h \
|
||||
CPlane.h \
|
||||
CQuaternion.h \
|
||||
CRay.h \
|
||||
CTransform4f.h \
|
||||
CVector2f.h \
|
||||
CVector2i.h \
|
||||
CVector3f.h \
|
||||
CVector4f.h \
|
||||
ETransformSpace.h \
|
||||
MathUtil.h
|
||||
|
||||
# Source Files
|
||||
SOURCES += \
|
||||
CAABox.cpp \
|
||||
CFrustumPlanes.cpp \
|
||||
CMatrix4f.cpp \
|
||||
CQuaternion.cpp \
|
||||
CTransform4f.cpp \
|
||||
CVector2f.cpp \
|
||||
CVector2i.cpp \
|
||||
CVector3f.cpp \
|
||||
CVector4f.cpp \
|
||||
MathUtil.cpp
|
||||
|
||||
# Codegen
|
||||
CODEGEN_DIR = $$EXTERNALS_DIR/CodeGen
|
||||
CODEGEN_OUT_PATH = $$BUILD_DIR/Common/codegen_build/auto_codegen.cpp
|
||||
CODEGEN_SRC_PATH = $$PWD
|
||||
include($$EXTERNALS_DIR/CodeGen/codegen.pri)
|
|
@ -1,387 +0,0 @@
|
|||
#include "MathUtil.h"
|
||||
#include "CMatrix4f.h"
|
||||
|
||||
namespace Math
|
||||
{
|
||||
|
||||
float Abs(float Value)
|
||||
{
|
||||
return fabs(Value);
|
||||
}
|
||||
|
||||
float Pow(float Base, float Exponent)
|
||||
{
|
||||
return pow(Base, Exponent);
|
||||
}
|
||||
|
||||
float Sqrt(float Value)
|
||||
{
|
||||
return sqrtf(Value);
|
||||
}
|
||||
|
||||
float Distance(const CVector3f& rkA, const CVector3f& rkB)
|
||||
{
|
||||
return sqrtf( Pow(rkB.X - rkA.X, 2.f) +
|
||||
Pow(rkB.Y - rkA.Y, 2.f) +
|
||||
Pow(rkB.Z - rkA.Z, 2.f) );
|
||||
}
|
||||
|
||||
float DegreesToRadians(float Deg)
|
||||
{
|
||||
return Deg * skPi / 180.f;
|
||||
}
|
||||
|
||||
float RadiansToDegrees(float Rad)
|
||||
{
|
||||
return Rad * 180.f / skPi;
|
||||
}
|
||||
|
||||
std::pair<bool,float> RayPlaneIntersection(const CRay& rkRay, const CPlane& rkPlane)
|
||||
{
|
||||
// Code based on ray/plane intersect code from Ogre
|
||||
// https://bitbucket.org/sinbad/ogre/src/197116fd2ac62c57cdeed1666f9866c3dddd4289/OgreMain/src/OgreMath.cpp?at=default#OgreMath.cpp-350
|
||||
|
||||
// Are ray and plane parallel?
|
||||
float Denom = rkPlane.Normal().Dot(rkRay.Direction());
|
||||
|
||||
if (Abs(Denom) < FLT_EPSILON)
|
||||
return std::pair<bool,float>(false, 0.f);
|
||||
|
||||
// Not parallel
|
||||
float Nom = rkPlane.Normal().Dot(rkRay.Origin()) + rkPlane.Dist();
|
||||
float t = -(Nom / Denom);
|
||||
return std::pair<bool,float>(t >= 0.f, t);
|
||||
}
|
||||
|
||||
std::pair<bool,float> RayBoxIntersection(const CRay& rkRay, const CAABox& rkBox)
|
||||
{
|
||||
// Code slightly modified from Ogre
|
||||
// https://github.com/ehsan/ogre/blob/master/OgreMain/src/OgreMath.cpp
|
||||
if (rkBox.IsNull()) return std::pair<bool,float>(false, 0.f);
|
||||
if (rkBox.IsInfinite()) return std::pair<bool,float>(true, 0.f);
|
||||
|
||||
float lowt = 0.0f;
|
||||
float t;
|
||||
bool Hit = false;
|
||||
CVector3f HitPoint;
|
||||
const CVector3f& RayOrig = rkRay.Origin();
|
||||
const CVector3f& RayDir = rkRay.Direction();
|
||||
const CVector3f Min = rkBox.Min();
|
||||
const CVector3f Max = rkBox.Max();
|
||||
|
||||
// Check origin inside first
|
||||
if ( RayOrig > Min && RayOrig < Max )
|
||||
{
|
||||
return std::pair<bool, float>(true, 0.f);
|
||||
}
|
||||
|
||||
// Check each face in turn, only check closest 3
|
||||
// Min x
|
||||
if (RayOrig.X <= Min.X && RayDir.X > 0)
|
||||
{
|
||||
t = (Min.X - RayOrig.X) / RayDir.X;
|
||||
if (t >= 0)
|
||||
{
|
||||
// Substitute t back into ray and check bounds and dist
|
||||
HitPoint = RayOrig + RayDir * t;
|
||||
if (HitPoint.Y >= Min.Y && HitPoint.Y <= Max.Y &&
|
||||
HitPoint.Z >= Min.Z && HitPoint.Z <= Max.Z &&
|
||||
(!Hit || t < lowt))
|
||||
{
|
||||
Hit = true;
|
||||
lowt = t;
|
||||
}
|
||||
}
|
||||
}
|
||||
// Max x
|
||||
if (RayOrig.X >= Max.X && RayDir.X < 0)
|
||||
{
|
||||
t = (Max.X - RayOrig.X) / RayDir.X;
|
||||
if (t >= 0)
|
||||
{
|
||||
// Substitute t back into ray and check bounds and dist
|
||||
HitPoint = RayOrig + RayDir * t;
|
||||
if (HitPoint.Y >= Min.Y && HitPoint.Y <= Max.Y &&
|
||||
HitPoint.Z >= Min.Z && HitPoint.Z <= Max.Z &&
|
||||
(!Hit || t < lowt))
|
||||
{
|
||||
Hit = true;
|
||||
lowt = t;
|
||||
}
|
||||
}
|
||||
}
|
||||
// Min y
|
||||
if (RayOrig.Y <= Min.Y && RayDir.Y > 0)
|
||||
{
|
||||
t = (Min.Y - RayOrig.Y) / RayDir.Y;
|
||||
if (t >= 0)
|
||||
{
|
||||
// Substitute t back into ray and check bounds and dist
|
||||
HitPoint = RayOrig + RayDir * t;
|
||||
if (HitPoint.X >= Min.X && HitPoint.X <= Max.X &&
|
||||
HitPoint.Z >= Min.Z && HitPoint.Z <= Max.Z &&
|
||||
(!Hit || t < lowt))
|
||||
{
|
||||
Hit = true;
|
||||
lowt = t;
|
||||
}
|
||||
}
|
||||
}
|
||||
// Max y
|
||||
if (RayOrig.Y >= Max.Y && RayDir.Y < 0)
|
||||
{
|
||||
t = (Max.Y - RayOrig.Y) / RayDir.Y;
|
||||
if (t >= 0)
|
||||
{
|
||||
// Substitute t back into ray and check bounds and dist
|
||||
HitPoint = RayOrig + RayDir * t;
|
||||
if (HitPoint.X >= Min.X && HitPoint.X <= Max.X &&
|
||||
HitPoint.Z >= Min.Z && HitPoint.Z <= Max.Z &&
|
||||
(!Hit || t < lowt))
|
||||
{
|
||||
Hit = true;
|
||||
lowt = t;
|
||||
}
|
||||
}
|
||||
}
|
||||
// Min z
|
||||
if (RayOrig.Z <= Min.Z && RayDir.Z > 0)
|
||||
{
|
||||
t = (Min.Z - RayOrig.Z) / RayDir.Z;
|
||||
if (t >= 0)
|
||||
{
|
||||
// Substitute t back into ray and check bounds and dist
|
||||
HitPoint = RayOrig + RayDir * t;
|
||||
if (HitPoint.X >= Min.X && HitPoint.X <= Max.X &&
|
||||
HitPoint.Y >= Min.Y && HitPoint.Y <= Max.Y &&
|
||||
(!Hit || t < lowt))
|
||||
{
|
||||
Hit = true;
|
||||
lowt = t;
|
||||
}
|
||||
}
|
||||
}
|
||||
// Max z
|
||||
if (RayOrig.Z >= Max.Z && RayDir.Z < 0)
|
||||
{
|
||||
t = (Max.Z - RayOrig.Z) / RayDir.Z;
|
||||
if (t >= 0)
|
||||
{
|
||||
// Substitute t back into ray and check bounds and dist
|
||||
HitPoint = RayOrig + RayDir * t;
|
||||
if (HitPoint.X >= Min.X && HitPoint.X <= Max.X &&
|
||||
HitPoint.Y >= Min.Y && HitPoint.Y <= Max.Y &&
|
||||
(!Hit || t < lowt))
|
||||
{
|
||||
Hit = true;
|
||||
lowt = t;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return std::pair<bool,float>(Hit, lowt);
|
||||
}
|
||||
|
||||
std::pair<bool,float> RayLineIntersection(const CRay& rkRay, const CVector3f& rkPointA,
|
||||
const CVector3f& rkPointB, float Threshold)
|
||||
{
|
||||
// http://geomalgorithms.com/a07-_distance.html
|
||||
// http://www.gamedev.net/topic/589705-rayline-intersection-in-3d/
|
||||
CVector3f u = rkRay.Direction();
|
||||
CVector3f v = rkPointB - rkPointA;
|
||||
CVector3f w = rkRay.Origin() - rkPointA;
|
||||
float a = u.Dot(u);
|
||||
float b = u.Dot(v);
|
||||
float c = v.Dot(v);
|
||||
float d = u.Dot(w);
|
||||
float e = v.Dot(w);
|
||||
float D = a * c - b * b;
|
||||
float sc, sN, sD = D;
|
||||
float tc, tN, tD = D;
|
||||
|
||||
if (D < FLT_EPSILON) {
|
||||
sN = 0.f;
|
||||
sD = 1.f;
|
||||
tN = e;
|
||||
tD = c;
|
||||
}
|
||||
else {
|
||||
sN = b * e - c * d;
|
||||
tN = a * e - b * d;
|
||||
|
||||
if (sN < 0.f) {
|
||||
sN = 0.f;
|
||||
tN = e;
|
||||
tD = c;
|
||||
}
|
||||
}
|
||||
|
||||
if (tN < 0.f) {
|
||||
tN = 0.f;
|
||||
|
||||
if (-d < 0.f)
|
||||
sN = 0.f;
|
||||
else {
|
||||
sN = -d;
|
||||
sD = a;
|
||||
}
|
||||
}
|
||||
else if (tN > tD) {
|
||||
tN = tD;
|
||||
|
||||
if (-d + b < 0.f)
|
||||
sN = 0.f;
|
||||
else {
|
||||
sN = -d + b;
|
||||
sD = a;
|
||||
}
|
||||
}
|
||||
|
||||
sc = (fabs(sN) < FLT_EPSILON ? 0.f : sN / sD);
|
||||
tc = (fabs(tN) < FLT_EPSILON ? 0.f : tN / tD);
|
||||
|
||||
CVector3f dP = w + (u * sc) - (v * tc);
|
||||
bool hit = (dP.Magnitude() <= Threshold);
|
||||
return std::pair<bool,float>(hit, sc);
|
||||
}
|
||||
|
||||
std::pair<bool,float> RaySphereIntersection(const CRay& rkRay, const CVector3f& rkSpherePos, float SphereRadius, bool AllowBackfaces /*= false*/)
|
||||
{
|
||||
std::pair<bool,float> Out(false, 0.f);
|
||||
float SquaredRadius = (SphereRadius * SphereRadius);
|
||||
|
||||
// Test for ray origin inside sphere
|
||||
if (!AllowBackfaces && rkRay.Origin().SquaredDistance(rkSpherePos) <= SquaredRadius)
|
||||
return Out;
|
||||
|
||||
CVector3f RayToSphere = rkSpherePos - rkRay.Origin();
|
||||
float CenterDist = RayToSphere.Dot(rkRay.Direction());
|
||||
|
||||
if (CenterDist >= 0.f)
|
||||
{
|
||||
float RayToSphereDistSquared = RayToSphere.SquaredMagnitude();
|
||||
float DSquared = RayToSphereDistSquared - (CenterDist * CenterDist);
|
||||
|
||||
if (DSquared >= 0.f && DSquared <= SquaredRadius)
|
||||
{
|
||||
Out.first = true;
|
||||
Out.second = CenterDist - Sqrt(SquaredRadius - DSquared);
|
||||
}
|
||||
}
|
||||
|
||||
return Out;
|
||||
}
|
||||
|
||||
std::pair<bool,float> RayTriangleIntersection(const CRay& rkRay,
|
||||
const CVector3f& rkVtxA, const CVector3f& rkVtxB,
|
||||
const CVector3f& rkVtxC, bool AllowBackfaces)
|
||||
{
|
||||
// Ogre code cuz I'm lazy and bad at math
|
||||
// https://github.com/ehsan/ogre/blob/master/OgreMain/src/OgreMath.cpp#L709
|
||||
CVector3f FaceNormal = (rkVtxB - rkVtxA).Cross(rkVtxC - rkVtxA);
|
||||
|
||||
//
|
||||
// Calculate intersection with plane.
|
||||
//
|
||||
float t;
|
||||
{
|
||||
float denom = FaceNormal.Dot(rkRay.Direction());
|
||||
|
||||
// Check intersect side
|
||||
if (denom > + std::numeric_limits<float>::epsilon())
|
||||
{
|
||||
if (!AllowBackfaces)
|
||||
return std::pair<bool,float>(false, 0.f);
|
||||
}
|
||||
else if (denom >= - std::numeric_limits<float>::epsilon())
|
||||
{
|
||||
// Parallel or triangle area is close to zero when
|
||||
// the plane normal not normalised.
|
||||
return std::pair<bool,float>(false, 0.f);
|
||||
}
|
||||
|
||||
t = FaceNormal.Dot(rkVtxA - rkRay.Origin()) / denom;
|
||||
|
||||
if (t < 0)
|
||||
{
|
||||
// Intersection is behind origin
|
||||
return std::pair<bool,float>(false, 0.f);
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Calculate the largest area projection plane in X, Y or Z.
|
||||
//
|
||||
size_t i0, i1;
|
||||
{
|
||||
float n0 = fabs(FaceNormal[0]);
|
||||
float n1 = fabs(FaceNormal[1]);
|
||||
float n2 = fabs(FaceNormal[2]);
|
||||
|
||||
i0 = 1; i1 = 2;
|
||||
if (n1 > n2)
|
||||
{
|
||||
if (n1 > n0) i0 = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (n2 > n0) i1 = 0;
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Check the intersection point is inside the triangle.
|
||||
//
|
||||
{
|
||||
float u1 = rkVtxB[i0] - rkVtxA[i0];
|
||||
float v1 = rkVtxB[i1] - rkVtxA[i1];
|
||||
float u2 = rkVtxC[i0] - rkVtxA[i0];
|
||||
float v2 = rkVtxC[i1] - rkVtxA[i1];
|
||||
float u0 = t * rkRay.Direction()[i0] + rkRay.Origin()[i0] - rkVtxA[i0];
|
||||
float v0 = t * rkRay.Direction()[i1] + rkRay.Origin()[i1] - rkVtxA[i1];
|
||||
|
||||
float alpha = u0 * v2 - u2 * v0;
|
||||
float beta = u1 * v0 - u0 * v1;
|
||||
float area = u1 * v2 - u2 * v1;
|
||||
|
||||
// epsilon to avoid float precision error
|
||||
const float EPSILON = 1e-6f;
|
||||
|
||||
float tolerance = - EPSILON * area;
|
||||
|
||||
if (area > 0)
|
||||
{
|
||||
if (alpha < tolerance || beta < tolerance || alpha+beta > area-tolerance)
|
||||
return std::pair<bool,float>(false, 0.f);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (alpha > tolerance || beta > tolerance || alpha+beta < area-tolerance)
|
||||
return std::pair<bool,float>(false, 0.f);
|
||||
}
|
||||
}
|
||||
|
||||
return std::pair<bool,float>(true, t);
|
||||
}
|
||||
|
||||
CMatrix4f PerspectiveMatrix(float FOV, float Aspect, float Near, float Far)
|
||||
{
|
||||
float TanHalfFOV = tanf( DegreesToRadians(FOV) / 2.f );
|
||||
return CMatrix4f(
|
||||
1.f / (Aspect * TanHalfFOV), 0, 0, 0,
|
||||
0, 1.f / TanHalfFOV, 0, 0,
|
||||
0, 0, -(Far+Near)/(Far-Near), (-2.f*Far*Near)/(Far-Near),
|
||||
0, 0, -1, 0
|
||||
);
|
||||
}
|
||||
|
||||
CMatrix4f OrthographicMatrix(float Left, float Right, float Bottom, float Top, float Near, float Far)
|
||||
{
|
||||
return CMatrix4f (
|
||||
2/(Right-Left), 0, 0, -(Right+Left)/(Right-Left),
|
||||
0, 2/(Top-Bottom), 0, -(Top+Bottom)/(Top-Bottom),
|
||||
0, 0, -2/(Far-Near), -(Far+Near)/(Far-Near),
|
||||
0, 0, 0, 1);
|
||||
}
|
||||
|
||||
} // End namespace
|
|
@ -1,76 +0,0 @@
|
|||
#ifndef MATH_H
|
||||
#define MATH_H
|
||||
|
||||
#include "CAABox.h"
|
||||
#include "CRay.h"
|
||||
#include "CPlane.h"
|
||||
#include "CVector3f.h"
|
||||
#include <utility>
|
||||
|
||||
namespace Math
|
||||
{
|
||||
|
||||
float Abs(float Value);
|
||||
|
||||
float Pow(float Base, float Exponent);
|
||||
|
||||
float Sqrt(float Value);
|
||||
|
||||
float Distance(const CVector3f& rkA, const CVector3f& rkB);
|
||||
|
||||
float DegreesToRadians(float Deg);
|
||||
|
||||
float RadiansToDegrees(float Rad);
|
||||
|
||||
template<typename Type>
|
||||
Type Clamp(const Type& rkMin, const Type& rkMax, const Type& rkVal)
|
||||
{
|
||||
return (rkVal < rkMin) ? rkMin :
|
||||
(rkVal > rkMax) ? rkMax :
|
||||
rkVal;
|
||||
}
|
||||
|
||||
template<typename Type>
|
||||
Type Max(const Type& rkA, const Type& rkB)
|
||||
{
|
||||
return (rkA > rkB ? rkA : rkB);
|
||||
}
|
||||
|
||||
template<typename Type>
|
||||
Type Min(const Type& rkA, const Type& rkB)
|
||||
{
|
||||
return (rkA < rkB ? rkA : rkB);
|
||||
}
|
||||
|
||||
template<typename Type>
|
||||
Type Lerp(const Type& rkA, const Type& rkB, float t)
|
||||
{
|
||||
Type Diff = rkB - rkA;
|
||||
return rkA + Type(Diff * t);
|
||||
}
|
||||
|
||||
std::pair<bool,float> RayPlaneIntersection(const CRay& rkRay, const CPlane& rkPlane);
|
||||
|
||||
std::pair<bool,float> RayBoxIntersection(const CRay& rkRay, const CAABox& rkBox);
|
||||
|
||||
std::pair<bool,float> RayLineIntersection(const CRay& rkRay, const CVector3f& rkPointA,
|
||||
const CVector3f& rkPointB, float Threshold = 0.02f);
|
||||
|
||||
std::pair<bool,float> RaySphereIntersection(const CRay& rkRay, const CVector3f& rkSpherePos,
|
||||
float SphereRadius, bool AllowBackfaces = false);
|
||||
|
||||
std::pair<bool,float> RayTriangleIntersection(const CRay& rkRay, const CVector3f& rkPointA,
|
||||
const CVector3f& rkPointB, const CVector3f& rkPointC,
|
||||
bool AllowBackfaces = false);
|
||||
|
||||
CMatrix4f PerspectiveMatrix(float FOV, float Aspect, float Near, float Far);
|
||||
|
||||
CMatrix4f OrthographicMatrix(float Left, float Right, float Bottom, float Top, float Near, float Far);
|
||||
|
||||
// Constants
|
||||
static const float skPi = 3.14159265358979323846f;
|
||||
static const float skHalfPi = skPi / 2.f;
|
||||
}
|
||||
|
||||
#endif // MATH_H
|
||||
|
|
@ -5,11 +5,10 @@
|
|||
#-------------------------------------------------
|
||||
|
||||
TEMPLATE = subdirs
|
||||
|
||||
SUBDIRS += \
|
||||
Common \
|
||||
Math \
|
||||
Core \
|
||||
Editor
|
||||
|
||||
CONFIG += ordered
|
||||
|
||||
# Add library subdirs
|
||||
SUBDIRS += ..\externals\LibCommon\Source\LibCommon.pro
|
||||
|
||||
# Add PWE subdirs
|
||||
SUBDIRS += Core Editor
|
||||
|
|
Loading…
Reference in New Issue