leocad/common/lc_library.h

258 lines
7.9 KiB
C
Raw Normal View History

#pragma once
2013-08-09 06:57:18 +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;
enum lcZipFileType
{
LC_ZIPFILE_OFFICIAL,
LC_ZIPFILE_UNOFFICIAL,
LC_NUM_ZIPFILES
};
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
};
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
}
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);
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;
mZipFileType = ZipFileType;
2013-08-09 06:57:18 +02:00
mZipFileIndex = ZipFileIndex;
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)
{
mZipFileType = ZipFileType;
mZipFileIndex = ZipFileIndex;
}
2013-08-09 06:57:18 +02:00
char mName[LC_MAXPATH];
lcZipFileType mZipFileType;
2017-12-02 21:22:04 +01:00
quint32 mZipFileIndex;
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();
bool Load(const QString& LibraryPath, bool ShowProgress);
2013-08-09 06:57:18 +02:00
void Unload();
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);
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
lcTexture* FindTexture(const char* TextureName, Project* CurrentProject, bool SearchProjectFolder);
2013-08-09 06:57:18 +02:00
bool LoadTexture(lcTexture* Texture);
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
bool IsPrimitive(const char* Name) const
{
2017-07-24 01:19:09 +02:00
return mPrimitives.find(Name) != mPrimitives.end();
}
void SetOfficialPieces()
{
if (mZipFiles[LC_ZIPFILE_OFFICIAL])
2017-07-24 04:35:18 +02:00
mNumOfficialPieces = mPieces.size();
}
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);
lcMesh* CreateMesh(PieceInfo* Info, lcLibraryMeshData& MeshData);
2016-12-28 22:30:31 +01:00
void ReleaseBuffers(lcContext* Context);
void UpdateBuffers(lcContext* Context);
void UnloadUnusedParts();
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
QDir mLibraryDir;
2013-08-09 06:57:18 +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:
bool OpenArchive(const QString& FileName, lcZipFileType ZipFileType);
bool OpenArchive(lcFile* File, const QString& FileName, lcZipFileType ZipFileType);
bool OpenDirectory(const QDir& LibraryDir, bool ShowProgress);
void ReadArchiveDescriptions(const QString& OfficialFileName, const QString& UnofficialFileName);
void ReadDirectoryDescriptions(const QFileInfoList (&FileLists)[LC_NUM_FOLDERTYPES], bool ShowProgress);
2013-08-09 06:57:18 +02:00
bool ReadArchiveCacheFile(const QString& FileName, lcMemFile& CacheFile);
bool WriteArchiveCacheFile(const QString& FileName, lcMemFile& CacheFile);
bool LoadCacheIndex(const QString& FileName);
bool SaveArchiveCacheIndex(const QString& FileName);
2013-08-09 06:57:18 +02:00
bool LoadCachePiece(PieceInfo* Info);
bool SaveCachePiece(PieceInfo* Info);
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;
QString mCachePath;
qint64 mArchiveCheckSum[4];
QString mLibraryFileName;
QString mUnofficialFileName;
lcZipFile* mZipFiles[LC_NUM_ZIPFILES];
bool mHasUnofficial;
bool mCancelLoading;
2013-08-09 06:57:18 +02:00
};