Support loading textures from the same folder of the model being loaded.

This commit is contained in:
Leonardo Zide 2017-07-01 17:12:09 -07:00
parent 0305c4964b
commit bca9b205af
9 changed files with 87 additions and 28 deletions

View file

@ -165,12 +165,37 @@ PieceInfo* lcPiecesLibrary::FindPiece(const char* PieceName, Project* CurrentPro
return nullptr;
}
lcTexture* lcPiecesLibrary::FindTexture(const char* TextureName)
lcTexture* lcPiecesLibrary::FindTexture(const char* TextureName, Project* CurrentProject, bool SearchProjectFolder)
{
for (int TextureIdx = 0; TextureIdx < mTextures.GetSize(); TextureIdx++)
if (!strcmp(TextureName, mTextures[TextureIdx]->mName))
return mTextures[TextureIdx];
QString ProjectPath;
if (SearchProjectFolder)
{
QString FileName = CurrentProject->GetFileName();
if (!FileName.isEmpty())
ProjectPath = QFileInfo(FileName).absolutePath();
}
if (!ProjectPath.isEmpty())
{
QFileInfo TextureFile = QFileInfo(ProjectPath + QDir::separator() + TextureName + ".png");
if (TextureFile.isFile())
{
lcTexture* Texture = lcLoadTexture(TextureFile.absoluteFilePath(), LC_TEXTURE_WRAPU | LC_TEXTURE_WRAPV);
if (Texture)
{
mTextures.Add(Texture);
return Texture;
}
}
}
return nullptr;
}
@ -1059,7 +1084,7 @@ bool lcPiecesLibrary::LoadPieceData(PieceInfo* Info)
lcMemFile PieceFile;
if (mZipFiles[Info->mZipFileType]->ExtractFile(Info->mZipFileIndex, PieceFile))
Loaded = ReadMeshData(PieceFile, lcMatrix44Identity(), 16, false, TextureStack, MeshData, LC_MESHDATA_SHARED, true);
Loaded = ReadMeshData(PieceFile, lcMatrix44Identity(), 16, false, TextureStack, MeshData, LC_MESHDATA_SHARED, true, nullptr, false);
SaveCache = Loaded && (Info->mZipFileType == LC_ZIPFILE_OFFICIAL);
}
@ -1077,7 +1102,7 @@ bool lcPiecesLibrary::LoadPieceData(PieceInfo* Info)
sprintf(FileName, "unofficial/parts/%s.dat", Name);
PieceFile.SetFileName(mLibraryDir.absoluteFilePath(QLatin1String(FileName)));
if (PieceFile.Open(QIODevice::ReadOnly))
Loaded = ReadMeshData(PieceFile, lcMatrix44Identity(), 16, false, TextureStack, MeshData, LC_MESHDATA_SHARED, true);
Loaded = ReadMeshData(PieceFile, lcMatrix44Identity(), 16, false, TextureStack, MeshData, LC_MESHDATA_SHARED, true, nullptr, false);
}
if (!Loaded)
@ -1085,7 +1110,7 @@ bool lcPiecesLibrary::LoadPieceData(PieceInfo* Info)
sprintf(FileName, "parts/%s.dat", Name);
PieceFile.SetFileName(mLibraryDir.absoluteFilePath(QLatin1String(FileName)));
if (PieceFile.Open(QIODevice::ReadOnly))
Loaded = ReadMeshData(PieceFile, lcMatrix44Identity(), 16, false, TextureStack, MeshData, LC_MESHDATA_SHARED, true);
Loaded = ReadMeshData(PieceFile, lcMatrix44Identity(), 16, false, TextureStack, MeshData, LC_MESHDATA_SHARED, true, nullptr, false);
}
}
@ -1497,6 +1522,17 @@ bool lcPiecesLibrary::LoadTexture(lcTexture* Texture)
return true;
}
void lcPiecesLibrary::ReleaseTexture(lcTexture* Texture)
{
QMutexLocker LoadLock(&mLoadMutex);
if (Texture->Release() == 0 && Texture->IsTemporary())
{
mTextures.Remove(Texture);
delete Texture;
}
}
int lcPiecesLibrary::FindPrimitiveIndex(const char* Name) const
{
int Count = mPrimitives.GetSize();
@ -1553,12 +1589,12 @@ bool lcPiecesLibrary::LoadPrimitive(int PrimitiveIndex)
if (LowPrimitiveIndex == -1)
{
if (!ReadMeshData(PrimFile, lcMatrix44Identity(), 16, false, TextureStack, Primitive->mMeshData, LC_MESHDATA_SHARED, true))
if (!ReadMeshData(PrimFile, lcMatrix44Identity(), 16, false, TextureStack, Primitive->mMeshData, LC_MESHDATA_SHARED, true, nullptr, false))
return false;
}
else
{
if (!ReadMeshData(PrimFile, lcMatrix44Identity(), 16, false, TextureStack, Primitive->mMeshData, LC_MESHDATA_HIGH, true))
if (!ReadMeshData(PrimFile, lcMatrix44Identity(), 16, false, TextureStack, Primitive->mMeshData, LC_MESHDATA_HIGH, true, nullptr, false))
return false;
lcLibraryPrimitive* LowPrimitive = mPrimitives[LowPrimitiveIndex];
@ -1568,7 +1604,7 @@ bool lcPiecesLibrary::LoadPrimitive(int PrimitiveIndex)
TextureStack.RemoveAll();
if (!ReadMeshData(PrimFile, lcMatrix44Identity(), 16, false, TextureStack, Primitive->mMeshData, LC_MESHDATA_LOW, true))
if (!ReadMeshData(PrimFile, lcMatrix44Identity(), 16, false, TextureStack, Primitive->mMeshData, LC_MESHDATA_LOW, true, nullptr, false))
return false;
}
}
@ -1602,7 +1638,7 @@ bool lcPiecesLibrary::LoadPrimitive(int PrimitiveIndex)
Found = PrimFile.Open(QIODevice::ReadOnly);
}
if (!Found || !ReadMeshData(PrimFile, lcMatrix44Identity(), 16, false, TextureStack, Primitive->mMeshData, LC_MESHDATA_SHARED, true))
if (!Found || !ReadMeshData(PrimFile, lcMatrix44Identity(), 16, false, TextureStack, Primitive->mMeshData, LC_MESHDATA_SHARED, true, nullptr, false))
return false;
}
@ -1611,7 +1647,7 @@ bool lcPiecesLibrary::LoadPrimitive(int PrimitiveIndex)
return true;
}
bool lcPiecesLibrary::ReadMeshData(lcFile& File, const lcMatrix44& CurrentTransform, lcuint32 CurrentColorCode, bool InvertWinding, lcArray<lcLibraryTextureMap>& TextureStack, lcLibraryMeshData& MeshData, lcMeshDataType MeshDataType, bool Optimize)
bool lcPiecesLibrary::ReadMeshData(lcFile& File, const lcMatrix44& CurrentTransform, lcuint32 CurrentColorCode, bool InvertWinding, lcArray<lcLibraryTextureMap>& TextureStack, lcLibraryMeshData& MeshData, lcMeshDataType MeshDataType, bool Optimize, Project* CurrentProject, bool SearchProjectFolder)
{
char Buffer[1024];
char* Line;
@ -1712,7 +1748,7 @@ bool lcPiecesLibrary::ReadMeshData(lcFile& File, const lcMatrix44& CurrentTransf
lcLibraryTextureMap& Map = TextureStack.Add();
Map.Next = false;
Map.Fallback = false;
Map.Texture = FindTexture(FileName);
Map.Texture = FindTexture(FileName, CurrentProject, SearchProjectFolder);
for (int EdgeIdx = 0; EdgeIdx < 2; EdgeIdx++)
{
@ -1863,7 +1899,7 @@ bool lcPiecesLibrary::ReadMeshData(lcFile& File, const lcMatrix44& CurrentTransf
lcMemFile IncludeFile;
if (mZipFiles[Primitive->mZipFileType]->ExtractFile(Primitive->mZipFileIndex, IncludeFile))
ReadMeshData(IncludeFile, IncludeTransform, ColorCode, Mirror ^ InvertNext, TextureStack, MeshData, MeshDataType, Optimize);
ReadMeshData(IncludeFile, IncludeTransform, ColorCode, Mirror ^ InvertNext, TextureStack, MeshData, MeshDataType, Optimize, CurrentProject, SearchProjectFolder);
}
else
{
@ -1894,7 +1930,7 @@ bool lcPiecesLibrary::ReadMeshData(lcFile& File, const lcMatrix44& CurrentTransf
Found = IncludeFile.Open(QIODevice::ReadOnly);
}
if (Found)
ReadMeshData(IncludeFile, IncludeTransform, ColorCode, Mirror ^ InvertNext, TextureStack, MeshData, MeshDataType, Optimize);
ReadMeshData(IncludeFile, IncludeTransform, ColorCode, Mirror ^ InvertNext, TextureStack, MeshData, MeshDataType, Optimize, CurrentProject, SearchProjectFolder);
}
}
}
@ -1912,7 +1948,7 @@ bool lcPiecesLibrary::ReadMeshData(lcFile& File, const lcMatrix44& CurrentTransf
lcMemFile IncludeFile;
if (mZipFiles[Info->mZipFileType]->ExtractFile(Info->mZipFileIndex, IncludeFile))
ReadMeshData(IncludeFile, IncludeTransform, ColorCode, Mirror ^ InvertNext, TextureStack, MeshData, MeshDataType, Optimize);
ReadMeshData(IncludeFile, IncludeTransform, ColorCode, Mirror ^ InvertNext, TextureStack, MeshData, MeshDataType, Optimize, CurrentProject, SearchProjectFolder);
}
else
{
@ -1938,7 +1974,7 @@ bool lcPiecesLibrary::ReadMeshData(lcFile& File, const lcMatrix44& CurrentTransf
}
if (Found)
ReadMeshData(IncludeFile, IncludeTransform, ColorCode, Mirror ^ InvertNext, TextureStack, MeshData, MeshDataType, Optimize);
ReadMeshData(IncludeFile, IncludeTransform, ColorCode, Mirror ^ InvertNext, TextureStack, MeshData, MeshDataType, Optimize, CurrentProject, SearchProjectFolder);
}
break;

View file

@ -162,8 +162,9 @@ public:
void LoadQueuedPiece();
void WaitForLoadQueue();
lcTexture* FindTexture(const char* TextureName);
lcTexture* FindTexture(const char* TextureName, Project* CurrentProject, bool SearchProjectFolder);
bool LoadTexture(lcTexture* Texture);
void ReleaseTexture(lcTexture* Texture);
bool PieceInCategory(PieceInfo* Info, const char* CategoryKeywords) const;
void GetCategoryEntries(int CategoryIndex, bool GroupPieces, lcArray<PieceInfo*>& SinglePieces, lcArray<PieceInfo*>& GroupedPieces);
@ -182,7 +183,7 @@ public:
mNumOfficialPieces = mPieces.GetSize();
}
bool ReadMeshData(lcFile& File, const lcMatrix44& CurrentTransform, lcuint32 CurrentColorCode, bool InvertWinding, lcArray<lcLibraryTextureMap>& TextureStack, lcLibraryMeshData& MeshData, lcMeshDataType MeshDataType, bool Optimize);
bool ReadMeshData(lcFile& File, const lcMatrix44& CurrentTransform, lcuint32 CurrentColorCode, bool InvertWinding, lcArray<lcLibraryTextureMap>& TextureStack, lcLibraryMeshData& MeshData, lcMeshDataType MeshDataType, bool Optimize, Project* CurrentProject, bool SearchProjectFolder);
lcMesh* CreateMesh(PieceInfo* Info, lcLibraryMeshData& MeshData);
void ReleaseBuffers(lcContext* Context);
void UpdateBuffers(lcContext* Context);

View file

@ -389,7 +389,7 @@ bool lcMesh::FileLoad(lcMemFile& File)
File.ReadBuffer(FileName, Length);
FileName[Length] = 0;
Section.Texture = lcGetPiecesLibrary()->FindTexture(FileName);
Section.Texture = lcGetPiecesLibrary()->FindTexture(FileName, nullptr, false);
}
else
Section.Texture = nullptr;

View file

@ -225,7 +225,7 @@ void lcModel::CreatePieceInfo(Project* Project)
{
lcPiecesLibrary* Library = lcGetPiecesLibrary();
mPieceInfo = Library->FindPiece(mProperties.mName.toUpper().toLatin1().constData(), Project, true, false);
mPieceInfo->SetModel(this, true);
mPieceInfo->SetModel(this, true, Project, true);
Library->LoadPieceInfo(mPieceInfo, true, true);
}
@ -234,7 +234,7 @@ void lcModel::UpdatePieceInfo(lcArray<lcModel*>& UpdatedModels)
if (UpdatedModels.FindIndex(this) != -1)
return;
mPieceInfo->SetModel(this, false);
mPieceInfo->SetModel(this, false, nullptr, false);
UpdatedModels.Add(this);
lcMesh* Mesh = mPieceInfo->GetMesh();

View file

@ -690,7 +690,7 @@ lcMesh* lcSynthInfo::CreateMesh(const lcArray<lcPieceControlPoint>& ControlPoint
lcArray<lcLibraryTextureMap> TextureStack;
File.Seek(0, SEEK_SET);
if (lcGetPiecesLibrary()->ReadMeshData(File, lcMatrix44Identity(), 16, false, TextureStack, MeshData, LC_MESHDATA_SHARED, false))
if (lcGetPiecesLibrary()->ReadMeshData(File, lcMatrix44Identity(), 16, false, TextureStack, MeshData, LC_MESHDATA_SHARED, false, nullptr, false))
return lcGetPiecesLibrary()->CreateMesh(nullptr, MeshData);
return nullptr;

View file

@ -16,6 +16,11 @@ lcTexture* lcLoadTexture(const QString& FileName, int Flags)
delete Texture;
Texture = nullptr;
}
else
{
strcpy(Texture->mName, QFileInfo(FileName).baseName().toLatin1());
Texture->SetTemporary(true);
}
return Texture;
}
@ -30,6 +35,7 @@ lcTexture::lcTexture()
{
mTexture = 0;
mRefCount = 0;
mTemporary = false;
}
lcTexture::~lcTexture()

View file

@ -51,6 +51,16 @@ public:
return mRefCount;
}
void SetTemporary(bool Temporary)
{
mTemporary = Temporary;
}
bool IsTemporary() const
{
return mTemporary;
}
int mWidth;
int mHeight;
char mName[LC_TEXTURE_NAME_LEN];
@ -59,6 +69,7 @@ public:
protected:
bool Load();
bool mTemporary;
int mRefCount;
};

View file

@ -45,6 +45,7 @@ QString PieceInfo::GetSaveID() const
void PieceInfo::SetMesh(lcMesh* Mesh)
{
mBoundingBox = Mesh->mBoundingBox;
ReleaseMesh();
mMesh = Mesh;
}
@ -52,16 +53,14 @@ void PieceInfo::SetPlaceholder()
{
mBoundingBox.Min = lcVector3(-10.0f, -10.0f, -24.0f);
mBoundingBox.Max = lcVector3(10.0f, 10.0f, 4.0f);
ReleaseMesh();
mFlags = LC_PIECE_PLACEHOLDER | LC_PIECE_HAS_DEFAULT | LC_PIECE_HAS_LINES;
mModel = nullptr;
mProject = nullptr;
delete mMesh;
mMesh = nullptr;
}
void PieceInfo::SetModel(lcModel* Model, bool UpdateMesh)
void PieceInfo::SetModel(lcModel* Model, bool UpdateMesh, Project* CurrentProject, bool SearchProjectFolder)
{
if (mModel != Model)
{
@ -91,7 +90,7 @@ void PieceInfo::SetModel(lcModel* Model, bool UpdateMesh)
lcArray<lcLibraryTextureMap> TextureStack;
PieceFile.Seek(0, SEEK_SET);
bool Ret = lcGetPiecesLibrary()->ReadMeshData(PieceFile, lcMatrix44Identity(), 16, false, TextureStack, MeshData, LC_MESHDATA_SHARED, true);
bool Ret = lcGetPiecesLibrary()->ReadMeshData(PieceFile, lcMatrix44Identity(), 16, false, TextureStack, MeshData, LC_MESHDATA_SHARED, true, CurrentProject, SearchProjectFolder);
if (Ret && !MeshData.IsEmpty())
lcGetPiecesLibrary()->CreateMesh(this, MeshData);
@ -159,7 +158,7 @@ void PieceInfo::Load()
mState = LC_PIECEINFO_LOADED;
}
void PieceInfo::Unload()
void PieceInfo::ReleaseMesh()
{
if (mMesh)
{
@ -170,14 +169,18 @@ void PieceInfo::Unload()
lcMeshSection& Section = mMesh->mLods[LodIdx].Sections[SectionIdx];
if (Section.Texture)
Section.Texture->Release();
lcGetPiecesLibrary()->ReleaseTexture(Section.Texture);
}
}
delete mMesh;
mMesh = nullptr;
}
}
void PieceInfo::Unload()
{
ReleaseMesh();
mState = LC_PIECEINFO_UNLOADED;
mModel = nullptr;

View file

@ -139,7 +139,7 @@ public:
void CreatePlaceholder(const char* Name);
void SetPlaceholder();
void SetModel(lcModel* Model, bool UpdateMesh);
void SetModel(lcModel* Model, bool UpdateMesh, Project* CurrentProject, bool SearchProjectFolder);
void SetProject(Project* Project, const char* PieceName);
bool IncludesModel(const lcModel* Model) const;
bool MinIntersectDist(const lcVector3& Start, const lcVector3& End, float& MinDistance) const;
@ -160,6 +160,8 @@ public:
lcPieceInfoState mState;
protected:
void ReleaseMesh();
int mRefCount;
lcModel* mModel;
Project* mProject;