2017-07-19 23:20:32 +02:00
|
|
|
#pragma once
|
2013-08-09 06:57:18 +02:00
|
|
|
|
2015-04-26 20:14:33 +02:00
|
|
|
#include "lc_context.h"
|
2013-08-09 06:57:18 +02:00
|
|
|
#include "lc_mesh.h"
|
|
|
|
#include "lc_math.h"
|
2013-08-16 01:43:18 +02:00
|
|
|
#include "lc_array.h"
|
2013-08-09 06:57:18 +02:00
|
|
|
|
|
|
|
class PieceInfo;
|
|
|
|
class lcZipFile;
|
|
|
|
|
2014-05-08 00:58:59 +02:00
|
|
|
enum lcZipFileType
|
|
|
|
{
|
|
|
|
LC_ZIPFILE_OFFICIAL,
|
|
|
|
LC_ZIPFILE_UNOFFICIAL,
|
|
|
|
LC_NUM_ZIPFILES
|
|
|
|
};
|
|
|
|
|
2017-11-27 04:21:54 +01:00
|
|
|
enum lcLibraryFolderType
|
|
|
|
{
|
|
|
|
LC_FOLDER_UNOFFICIAL,
|
|
|
|
LC_FOLDER_OFFICIAL,
|
|
|
|
LC_NUM_FOLDERTYPES
|
|
|
|
};
|
|
|
|
|
2017-02-28 01:03:12 +01:00
|
|
|
struct lcLibraryMeshVertex
|
|
|
|
{
|
|
|
|
lcVector3 Position;
|
|
|
|
lcVector3 Normal;
|
|
|
|
float NormalWeight;
|
|
|
|
};
|
|
|
|
|
|
|
|
struct lcLibraryMeshVertexTextured
|
|
|
|
{
|
|
|
|
lcVector3 Position;
|
|
|
|
lcVector3 Normal;
|
|
|
|
float NormalWeight;
|
|
|
|
lcVector2 TexCoord;
|
|
|
|
};
|
|
|
|
|
2013-08-09 06:57:18 +02:00
|
|
|
class lcLibraryMeshSection
|
|
|
|
{
|
|
|
|
public:
|
2017-12-02 21:22:04 +01:00
|
|
|
lcLibraryMeshSection(lcMeshPrimitiveType PrimitiveType, quint32 Color, lcTexture* Texture)
|
2013-08-09 06:57:18 +02:00
|
|
|
: mIndices(1024, 1024)
|
|
|
|
{
|
|
|
|
mPrimitiveType = PrimitiveType;
|
|
|
|
mColor = Color;
|
|
|
|
mTexture = Texture;
|
|
|
|
}
|
|
|
|
|
|
|
|
~lcLibraryMeshSection()
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
2016-08-22 03:11:32 +02:00
|
|
|
lcMeshPrimitiveType mPrimitiveType;
|
2017-12-02 21:22:04 +01:00
|
|
|
quint32 mColor;
|
2013-08-09 06:57:18 +02:00
|
|
|
lcTexture* mTexture;
|
2017-12-02 21:22:04 +01:00
|
|
|
lcArray<quint32> mIndices;
|
2013-08-09 06:57:18 +02:00
|
|
|
};
|
|
|
|
|
|
|
|
struct lcLibraryTextureMap
|
|
|
|
{
|
|
|
|
lcVector4 Params[2];
|
|
|
|
lcTexture* Texture;
|
|
|
|
bool Fallback;
|
|
|
|
bool Next;
|
|
|
|
};
|
|
|
|
|
2015-05-24 06:36:25 +02:00
|
|
|
enum lcMeshDataType
|
|
|
|
{
|
|
|
|
LC_MESHDATA_HIGH,
|
|
|
|
LC_MESHDATA_LOW,
|
|
|
|
LC_MESHDATA_SHARED,
|
|
|
|
LC_NUM_MESHDATA_TYPES
|
|
|
|
};
|
|
|
|
|
2017-11-25 04:45:27 +01:00
|
|
|
enum class lcPrimitiveState
|
|
|
|
{
|
|
|
|
NOT_LOADED,
|
|
|
|
LOADING,
|
|
|
|
LOADED
|
|
|
|
};
|
|
|
|
|
2013-08-09 06:57:18 +02:00
|
|
|
class lcLibraryMeshData
|
|
|
|
{
|
|
|
|
public:
|
|
|
|
lcLibraryMeshData()
|
|
|
|
{
|
2015-05-24 06:36:25 +02:00
|
|
|
for (int MeshDataIdx = 0; MeshDataIdx < LC_NUM_MESHDATA_TYPES; MeshDataIdx++)
|
|
|
|
mVertices[MeshDataIdx].SetGrow(1024);
|
2013-08-09 06:57:18 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
~lcLibraryMeshData()
|
|
|
|
{
|
2015-05-24 06:36:25 +02:00
|
|
|
for (int MeshDataIdx = 0; MeshDataIdx < LC_NUM_MESHDATA_TYPES; MeshDataIdx++)
|
|
|
|
mSections[MeshDataIdx].DeleteAll();
|
2013-08-09 06:57:18 +02:00
|
|
|
}
|
|
|
|
|
2016-11-26 02:12:19 +01:00
|
|
|
bool IsEmpty() const
|
|
|
|
{
|
|
|
|
for (int MeshDataIdx = 0; MeshDataIdx < LC_NUM_MESHDATA_TYPES; MeshDataIdx++)
|
|
|
|
if (!mSections[MeshDataIdx].IsEmpty())
|
|
|
|
return false;
|
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2017-12-02 21:22:04 +01:00
|
|
|
lcLibraryMeshSection* AddSection(lcMeshDataType MeshDataType, lcMeshPrimitiveType PrimitiveType, quint32 ColorCode, lcTexture* Texture);
|
|
|
|
quint32 AddVertex(lcMeshDataType MeshDataType, const lcVector3& Position, bool Optimize);
|
|
|
|
quint32 AddVertex(lcMeshDataType MeshDataType, const lcVector3& Position, const lcVector3& Normal, bool Optimize);
|
|
|
|
quint32 AddTexturedVertex(lcMeshDataType MeshDataType, const lcVector3& Position, const lcVector2& TexCoord, bool Optimize);
|
|
|
|
quint32 AddTexturedVertex(lcMeshDataType MeshDataType, const lcVector3& Position, const lcVector3& Normal, const lcVector2& TexCoord, bool Optimize);
|
2017-02-28 01:03:12 +01:00
|
|
|
void AddVertices(lcMeshDataType MeshDataType, int VertexCount, int* BaseVertex, lcLibraryMeshVertex** VertexBuffer);
|
2017-12-02 21:22:04 +01:00
|
|
|
void AddIndices(lcMeshDataType MeshDataType, lcMeshPrimitiveType PrimitiveType, quint32 ColorCode, int IndexCount, quint32** IndexBuffer);
|
|
|
|
void AddLine(lcMeshDataType MeshDataType, int LineType, quint32 ColorCode, bool WindingCCW, const lcVector3* Vertices, bool Optimize);
|
|
|
|
void AddTexturedLine(lcMeshDataType MeshDataType, int LineType, quint32 ColorCode, bool WindingCCW, const lcLibraryTextureMap& Map, const lcVector3* Vertices, bool Optimize);
|
|
|
|
void AddMeshData(const lcLibraryMeshData& Data, const lcMatrix44& Transform, quint32 CurrentColorCode, bool InvertWinding, bool InvertNormals, lcLibraryTextureMap* TextureMap, lcMeshDataType OverrideDestIndex);
|
|
|
|
void AddMeshDataNoDuplicateCheck(const lcLibraryMeshData& Data, const lcMatrix44& Transform, quint32 CurrentColorCode, bool InvertWinding, bool InvertNormals, lcLibraryTextureMap* TextureMap, lcMeshDataType OverrideDestIndex);
|
2015-02-23 01:50:37 +01:00
|
|
|
void TestQuad(int* QuadIndices, const lcVector3* Vertices);
|
|
|
|
void ResequenceQuad(int* QuadIndices, int a, int b, int c, int d);
|
2013-08-09 06:57:18 +02:00
|
|
|
|
2015-05-24 06:36:25 +02:00
|
|
|
lcArray<lcLibraryMeshSection*> mSections[LC_NUM_MESHDATA_TYPES];
|
2017-02-28 01:03:12 +01:00
|
|
|
lcArray<lcLibraryMeshVertex> mVertices[LC_NUM_MESHDATA_TYPES];
|
|
|
|
lcArray<lcLibraryMeshVertexTextured> mTexturedVertices[LC_NUM_MESHDATA_TYPES];
|
2013-08-09 06:57:18 +02:00
|
|
|
};
|
|
|
|
|
|
|
|
class lcLibraryPrimitive
|
|
|
|
{
|
|
|
|
public:
|
2017-12-02 21:22:04 +01:00
|
|
|
lcLibraryPrimitive(const char* Name, lcZipFileType ZipFileType,quint32 ZipFileIndex, bool Stud, bool SubFile)
|
2013-08-09 06:57:18 +02:00
|
|
|
{
|
|
|
|
strncpy(mName, Name, sizeof(mName));
|
|
|
|
mName[sizeof(mName) - 1] = 0;
|
|
|
|
|
2014-05-08 00:58:59 +02:00
|
|
|
mZipFileType = ZipFileType;
|
2013-08-09 06:57:18 +02:00
|
|
|
mZipFileIndex = ZipFileIndex;
|
2017-11-25 04:45:27 +01:00
|
|
|
mState = lcPrimitiveState::NOT_LOADED;
|
2013-08-09 06:57:18 +02:00
|
|
|
mStud = Stud;
|
|
|
|
mSubFile = SubFile;
|
|
|
|
}
|
|
|
|
|
2017-12-02 21:22:04 +01:00
|
|
|
void SetZipFile(lcZipFileType ZipFileType,quint32 ZipFileIndex)
|
2014-05-08 00:58:59 +02:00
|
|
|
{
|
|
|
|
mZipFileType = ZipFileType;
|
|
|
|
mZipFileIndex = ZipFileIndex;
|
|
|
|
}
|
|
|
|
|
2013-08-09 06:57:18 +02:00
|
|
|
char mName[LC_MAXPATH];
|
2014-05-08 00:58:59 +02:00
|
|
|
lcZipFileType mZipFileType;
|
2017-12-02 21:22:04 +01:00
|
|
|
quint32 mZipFileIndex;
|
2017-11-25 04:45:27 +01:00
|
|
|
lcPrimitiveState mState;
|
2013-08-09 06:57:18 +02:00
|
|
|
bool mStud;
|
|
|
|
bool mSubFile;
|
|
|
|
lcLibraryMeshData mMeshData;
|
|
|
|
};
|
|
|
|
|
2017-01-23 04:28:05 +01:00
|
|
|
class lcPiecesLibrary : public QObject
|
2013-08-09 06:57:18 +02:00
|
|
|
{
|
2017-01-23 04:28:05 +01:00
|
|
|
Q_OBJECT
|
|
|
|
|
2013-08-09 06:57:18 +02:00
|
|
|
public:
|
|
|
|
lcPiecesLibrary();
|
|
|
|
~lcPiecesLibrary();
|
|
|
|
|
2017-11-25 05:00:16 +01:00
|
|
|
bool Load(const QString& LibraryPath, bool ShowProgress);
|
2013-08-09 06:57:18 +02:00
|
|
|
void Unload();
|
2015-01-07 17:52:42 +01:00
|
|
|
void RemoveTemporaryPieces();
|
2015-02-22 03:39:15 +01:00
|
|
|
void RemovePiece(PieceInfo* Info);
|
2013-08-09 06:57:18 +02:00
|
|
|
|
2017-07-24 04:35:18 +02:00
|
|
|
void RenamePiece(PieceInfo* Info, const char* NewName);
|
2016-11-26 02:12:19 +01:00
|
|
|
PieceInfo* FindPiece(const char* PieceName, Project* Project, bool CreatePlaceholder, bool SearchProjectFolder);
|
2017-01-23 04:28:05 +01:00
|
|
|
void LoadPieceInfo(PieceInfo* Info, bool Wait, bool Priority);
|
|
|
|
void ReleasePieceInfo(PieceInfo* Info);
|
2014-09-11 21:55:34 +02:00
|
|
|
bool LoadBuiltinPieces();
|
2017-01-23 04:28:05 +01:00
|
|
|
bool LoadPieceData(PieceInfo* Info);
|
|
|
|
void LoadQueuedPiece();
|
|
|
|
void WaitForLoadQueue();
|
2013-08-09 06:57:18 +02:00
|
|
|
|
2017-07-02 02:12:09 +02:00
|
|
|
lcTexture* FindTexture(const char* TextureName, Project* CurrentProject, bool SearchProjectFolder);
|
2013-08-09 06:57:18 +02:00
|
|
|
bool LoadTexture(lcTexture* Texture);
|
2017-07-02 02:12:09 +02:00
|
|
|
void ReleaseTexture(lcTexture* Texture);
|
2013-08-09 06:57:18 +02:00
|
|
|
|
2017-02-08 03:55:54 +01:00
|
|
|
bool PieceInCategory(PieceInfo* Info, const char* CategoryKeywords) const;
|
2013-08-16 01:43:18 +02:00
|
|
|
void GetCategoryEntries(int CategoryIndex, bool GroupPieces, lcArray<PieceInfo*>& SinglePieces, lcArray<PieceInfo*>& GroupedPieces);
|
2017-02-08 03:55:54 +01:00
|
|
|
void GetCategoryEntries(const char* CategoryKeywords, bool GroupPieces, lcArray<PieceInfo*>& SinglePieces, lcArray<PieceInfo*>& GroupedPieces);
|
2013-08-16 01:43:18 +02:00
|
|
|
void GetPatternedPieces(PieceInfo* Parent, lcArray<PieceInfo*>& Pieces) const;
|
2017-02-01 06:12:30 +01:00
|
|
|
void GetParts(lcArray<PieceInfo*>& Parts);
|
2013-08-09 06:57:18 +02:00
|
|
|
|
2015-02-28 21:31:57 +01:00
|
|
|
bool IsPrimitive(const char* Name) const
|
|
|
|
{
|
2017-07-24 01:19:09 +02:00
|
|
|
return mPrimitives.find(Name) != mPrimitives.end();
|
2015-02-28 21:31:57 +01:00
|
|
|
}
|
|
|
|
|
2014-03-07 03:39:28 +01:00
|
|
|
void SetOfficialPieces()
|
|
|
|
{
|
2014-05-08 00:58:59 +02:00
|
|
|
if (mZipFiles[LC_ZIPFILE_OFFICIAL])
|
2017-07-24 04:35:18 +02:00
|
|
|
mNumOfficialPieces = mPieces.size();
|
2014-03-07 03:39:28 +01:00
|
|
|
}
|
|
|
|
|
2017-12-02 21:22:04 +01:00
|
|
|
bool ReadMeshData(lcFile& File, const lcMatrix44& CurrentTransform, quint32 CurrentColorCode, bool InvertWinding, lcArray<lcLibraryTextureMap>& TextureStack, lcLibraryMeshData& MeshData, lcMeshDataType MeshDataType, bool Optimize, Project* CurrentProject, bool SearchProjectFolder);
|
2016-02-29 21:13:54 +01:00
|
|
|
lcMesh* CreateMesh(PieceInfo* Info, lcLibraryMeshData& MeshData);
|
2016-12-28 22:30:31 +01:00
|
|
|
void ReleaseBuffers(lcContext* Context);
|
2015-04-26 20:14:33 +02:00
|
|
|
void UpdateBuffers(lcContext* Context);
|
2015-11-16 03:41:16 +01:00
|
|
|
void UnloadUnusedParts();
|
2015-02-23 01:50:37 +01:00
|
|
|
|
2017-07-24 04:35:18 +02:00
|
|
|
std::map<std::string, PieceInfo*> mPieces;
|
2017-07-24 01:19:09 +02:00
|
|
|
std::map<std::string, lcLibraryPrimitive*> mPrimitives;
|
2013-08-09 06:57:18 +02:00
|
|
|
int mNumOfficialPieces;
|
|
|
|
|
2013-08-16 01:43:18 +02:00
|
|
|
lcArray<lcTexture*> mTextures;
|
2013-08-09 06:57:18 +02:00
|
|
|
|
2017-05-29 22:31:24 +02:00
|
|
|
QDir mLibraryDir;
|
2013-08-09 06:57:18 +02:00
|
|
|
|
2015-04-26 20:14:33 +02:00
|
|
|
bool mBuffersDirty;
|
|
|
|
lcVertexBuffer mVertexBuffer;
|
|
|
|
lcIndexBuffer mIndexBuffer;
|
|
|
|
|
2017-01-23 04:28:05 +01:00
|
|
|
signals:
|
|
|
|
void PartLoaded(PieceInfo* Info);
|
|
|
|
|
2013-08-09 06:57:18 +02:00
|
|
|
protected:
|
2017-05-29 22:31:24 +02:00
|
|
|
bool OpenArchive(const QString& FileName, lcZipFileType ZipFileType);
|
|
|
|
bool OpenArchive(lcFile* File, const QString& FileName, lcZipFileType ZipFileType);
|
2017-11-25 05:00:16 +01:00
|
|
|
bool OpenDirectory(const QDir& LibraryDir, bool ShowProgress);
|
2015-07-22 06:00:47 +02:00
|
|
|
void ReadArchiveDescriptions(const QString& OfficialFileName, const QString& UnofficialFileName);
|
2017-11-27 04:21:54 +01:00
|
|
|
void ReadDirectoryDescriptions(const QFileInfoList (&FileLists)[LC_NUM_FOLDERTYPES], bool ShowProgress);
|
2013-08-09 06:57:18 +02:00
|
|
|
|
2017-11-27 04:21:54 +01:00
|
|
|
bool ReadArchiveCacheFile(const QString& FileName, lcMemFile& CacheFile);
|
|
|
|
bool WriteArchiveCacheFile(const QString& FileName, lcMemFile& CacheFile);
|
2015-07-22 06:00:47 +02:00
|
|
|
bool LoadCacheIndex(const QString& FileName);
|
2017-11-27 04:21:54 +01:00
|
|
|
bool SaveArchiveCacheIndex(const QString& FileName);
|
2013-08-09 06:57:18 +02:00
|
|
|
bool LoadCachePiece(PieceInfo* Info);
|
2015-07-22 06:00:47 +02:00
|
|
|
bool SaveCachePiece(PieceInfo* Info);
|
2017-11-27 04:21:54 +01:00
|
|
|
bool ReadDirectoryCacheFile(const QString& FileName, lcMemFile& CacheFile);
|
|
|
|
bool WriteDirectoryCacheFile(const QString& FileName, lcMemFile& CacheFile);
|
2013-08-09 06:57:18 +02:00
|
|
|
|
2017-07-24 01:19:09 +02:00
|
|
|
lcLibraryPrimitive* FindPrimitive(const char* Name) const
|
|
|
|
{
|
|
|
|
const auto PrimitiveIt = mPrimitives.find(Name);
|
|
|
|
return PrimitiveIt != mPrimitives.end() ? PrimitiveIt->second : nullptr;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool LoadPrimitive(lcLibraryPrimitive* Primitive);
|
2013-08-09 06:57:18 +02:00
|
|
|
|
2017-01-23 04:28:05 +01:00
|
|
|
QMutex mLoadMutex;
|
|
|
|
QList<QFuture<void>> mLoadFutures;
|
|
|
|
QList<PieceInfo*> mLoadQueue;
|
|
|
|
|
2015-07-22 06:00:47 +02:00
|
|
|
QString mCachePath;
|
|
|
|
qint64 mArchiveCheckSum[4];
|
2017-05-29 22:31:24 +02:00
|
|
|
QString mLibraryFileName;
|
|
|
|
QString mUnofficialFileName;
|
2014-05-08 00:58:59 +02:00
|
|
|
lcZipFile* mZipFiles[LC_NUM_ZIPFILES];
|
2017-03-19 21:12:24 +01:00
|
|
|
bool mHasUnofficial;
|
2017-11-25 21:57:41 +01:00
|
|
|
bool mCancelLoading;
|
2013-08-09 06:57:18 +02:00
|
|
|
};
|
|
|
|
|