mirror of
https://github.com/leozide/leocad
synced 2025-01-30 20:34:56 +01:00
Store texture projection as part of the section while loading meshes.
This commit is contained in:
parent
d84d8f1f3c
commit
bf7a382dcc
2 changed files with 281 additions and 206 deletions
|
@ -10,10 +10,13 @@ static lcVector2 lcCalculateTexCoord(const lcVector3& Position, const lcMeshLoad
|
||||||
{
|
{
|
||||||
switch (TextureMap->Type)
|
switch (TextureMap->Type)
|
||||||
{
|
{
|
||||||
case lcMeshLoaderTextureMapType::Planar:
|
case lcMeshLoaderMaterialType::Solid:
|
||||||
|
break;
|
||||||
|
|
||||||
|
case lcMeshLoaderMaterialType::Planar:
|
||||||
return lcVector2(lcDot3(Position, TextureMap->Params.Planar.Planes[0]) + TextureMap->Params.Planar.Planes[0].w, lcDot3(Position, TextureMap->Params.Planar.Planes[1]) + TextureMap->Params.Planar.Planes[1].w);
|
return lcVector2(lcDot3(Position, TextureMap->Params.Planar.Planes[0]) + TextureMap->Params.Planar.Planes[0].w, lcDot3(Position, TextureMap->Params.Planar.Planes[1]) + TextureMap->Params.Planar.Planes[1].w);
|
||||||
|
|
||||||
case lcMeshLoaderTextureMapType::Cylindrical:
|
case lcMeshLoaderMaterialType::Cylindrical:
|
||||||
{
|
{
|
||||||
const lcVector4& FrontPlane = TextureMap->Params.Cylindrical.FrontPlane;
|
const lcVector4& FrontPlane = TextureMap->Params.Cylindrical.FrontPlane;
|
||||||
const lcVector4& Plane1 = TextureMap->Params.Cylindrical.Plane1;
|
const lcVector4& Plane1 = TextureMap->Params.Cylindrical.Plane1;
|
||||||
|
@ -33,7 +36,7 @@ static lcVector2 lcCalculateTexCoord(const lcVector3& Position, const lcMeshLoad
|
||||||
return TexCoord;
|
return TexCoord;
|
||||||
}
|
}
|
||||||
|
|
||||||
case lcMeshLoaderTextureMapType::Spherical:
|
case lcMeshLoaderMaterialType::Spherical:
|
||||||
{
|
{
|
||||||
const lcVector4& FrontPlane = TextureMap->Params.Spherical.FrontPlane;
|
const lcVector4& FrontPlane = TextureMap->Params.Spherical.FrontPlane;
|
||||||
const lcVector3& Center = TextureMap->Params.Spherical.Center;
|
const lcVector3& Center = TextureMap->Params.Spherical.Center;
|
||||||
|
@ -113,13 +116,13 @@ static bool lcCompareVertices(const lcVector3& Position1, const lcVector2& TexCo
|
||||||
return lcCompareVertices(Position1, Position2) && fabsf(TexCoord1.x - TexCoord2.x) < lcTexCoordEpsilon && fabsf(TexCoord1.y - TexCoord2.y) < lcTexCoordEpsilon;
|
return lcCompareVertices(Position1, Position2) && fabsf(TexCoord1.x - TexCoord2.x) < lcTexCoordEpsilon && fabsf(TexCoord1.y - TexCoord2.y) < lcTexCoordEpsilon;
|
||||||
}
|
}
|
||||||
|
|
||||||
lcMeshLoaderSection* lcMeshLoaderTypeData::AddSection(lcMeshPrimitiveType PrimitiveType, quint32 ColorCode, lcTexture* Texture)
|
lcMeshLoaderSection* lcMeshLoaderTypeData::AddSection(lcMeshPrimitiveType PrimitiveType, lcMeshLoaderMaterial* Material)
|
||||||
{
|
{
|
||||||
for (std::unique_ptr<lcMeshLoaderSection>& Section : mSections)
|
for (std::unique_ptr<lcMeshLoaderSection>& Section : mSections)
|
||||||
if (Section->mColor == ColorCode && Section->mPrimitiveType == PrimitiveType && Section->mTexture == Texture)
|
if (Section->mMaterial == Material && Section->mPrimitiveType == PrimitiveType)
|
||||||
return Section.get();
|
return Section.get();
|
||||||
|
|
||||||
mSections.emplace_back(new lcMeshLoaderSection(PrimitiveType, ColorCode, Texture));
|
mSections.emplace_back(new lcMeshLoaderSection(PrimitiveType, Material));
|
||||||
|
|
||||||
return mSections.back().get();
|
return mSections.back().get();
|
||||||
}
|
}
|
||||||
|
@ -300,11 +303,11 @@ quint32 lcMeshLoaderTypeData::AddConditionalVertex(const lcVector3(&Position)[4]
|
||||||
return mConditionalVertices.GetSize() - 1;
|
return mConditionalVertices.GetSize() - 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
void lcMeshLoaderTypeData::ProcessLine(int LineType, quint32 ColorCode, bool WindingCCW, lcVector3 (&Vertices)[4], bool Optimize)
|
void lcMeshLoaderTypeData::ProcessLine(int LineType, lcMeshLoaderMaterial* Material, bool WindingCCW, lcVector3 (&Vertices)[4], bool Optimize)
|
||||||
{
|
{
|
||||||
lcMeshPrimitiveType PrimitiveTypes[4] = { LC_MESH_LINES, LC_MESH_TRIANGLES, LC_MESH_TRIANGLES, LC_MESH_CONDITIONAL_LINES };
|
lcMeshPrimitiveType PrimitiveTypes[4] = { LC_MESH_LINES, LC_MESH_TRIANGLES, LC_MESH_TRIANGLES, LC_MESH_CONDITIONAL_LINES };
|
||||||
lcMeshPrimitiveType PrimitiveType = PrimitiveTypes[LineType - 2];
|
lcMeshPrimitiveType PrimitiveType = PrimitiveTypes[LineType - 2];
|
||||||
lcMeshLoaderSection* Section = AddSection(PrimitiveType, ColorCode, nullptr);
|
lcMeshLoaderSection* Section = AddSection(PrimitiveType, Material);
|
||||||
|
|
||||||
int QuadIndices[4] = { 0, 1, 2, 3 };
|
int QuadIndices[4] = { 0, 1, 2, 3 };
|
||||||
int Indices[4] = { -1, -1, -1, -1 };
|
int Indices[4] = { -1, -1, -1, -1 };
|
||||||
|
@ -396,10 +399,10 @@ void lcMeshLoaderTypeData::ProcessLine(int LineType, quint32 ColorCode, bool Win
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void lcMeshLoaderTypeData::ProcessTexturedLine(int LineType, quint32 ColorCode, bool WindingCCW, const lcMeshLoaderTextureMap& TextureMap, const lcVector3* Vertices, bool Optimize)
|
void lcMeshLoaderTypeData::ProcessTexturedLine(int LineType, lcMeshLoaderMaterial* Material, bool WindingCCW, const lcMeshLoaderTextureMap& TextureMap, const lcVector3* Vertices, bool Optimize)
|
||||||
{
|
{
|
||||||
lcMeshPrimitiveType PrimitiveType = LC_MESH_TEXTURED_TRIANGLES;
|
lcMeshPrimitiveType PrimitiveType = LC_MESH_TEXTURED_TRIANGLES;
|
||||||
lcMeshLoaderSection* Section = AddSection(PrimitiveType, ColorCode, TextureMap.Texture);
|
lcMeshLoaderSection* Section = AddSection(PrimitiveType, Material);
|
||||||
|
|
||||||
int QuadIndices[4] = { 0, 1, 2, 3 };
|
int QuadIndices[4] = { 0, 1, 2, 3 };
|
||||||
int Indices[4] = { -1, -1, -1, -1 };
|
int Indices[4] = { -1, -1, -1, -1 };
|
||||||
|
@ -420,7 +423,7 @@ void lcMeshLoaderTypeData::ProcessTexturedLine(int LineType, quint32 ColorCode,
|
||||||
TexCoords[QuadIndices[IndexIdx]] = lcCalculateTexCoord(Position, &TextureMap);
|
TexCoords[QuadIndices[IndexIdx]] = lcCalculateTexCoord(Position, &TextureMap);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (TextureMap.Type == lcMeshLoaderTextureMapType::Cylindrical || TextureMap.Type == lcMeshLoaderTextureMapType::Spherical)
|
if (TextureMap.Type == lcMeshLoaderMaterialType::Cylindrical || TextureMap.Type == lcMeshLoaderMaterialType::Spherical)
|
||||||
{
|
{
|
||||||
auto CheckTexCoordsWrap = [&TexCoords, &Vertices, &TextureMap](int Index1, int Index2, int Index3)
|
auto CheckTexCoordsWrap = [&TexCoords, &Vertices, &TextureMap](int Index1, int Index2, int Index3)
|
||||||
{
|
{
|
||||||
|
@ -431,7 +434,7 @@ void lcMeshLoaderTypeData::ProcessTexturedLine(int LineType, quint32 ColorCode,
|
||||||
if (u12 < 0.5f && u13 < 0.5f && u23 < 0.5f)
|
if (u12 < 0.5f && u13 < 0.5f && u23 < 0.5f)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
const lcVector4& Plane2 = (TextureMap.Type == lcMeshLoaderTextureMapType::Cylindrical) ? TextureMap.Params.Cylindrical.Plane2 : TextureMap.Params.Spherical.Plane2;
|
const lcVector4& Plane2 = (TextureMap.Type == lcMeshLoaderMaterialType::Cylindrical) ? TextureMap.Params.Cylindrical.Plane2 : TextureMap.Params.Spherical.Plane2;
|
||||||
float Dot1 = fabsf(lcDot(Plane2, lcVector4(Vertices[Index1], 1.0f)));
|
float Dot1 = fabsf(lcDot(Plane2, lcVector4(Vertices[Index1], 1.0f)));
|
||||||
float Dot2 = fabsf(lcDot(Plane2, lcVector4(Vertices[Index2], 1.0f)));
|
float Dot2 = fabsf(lcDot(Plane2, lcVector4(Vertices[Index2], 1.0f)));
|
||||||
float Dot3 = fabsf(lcDot(Plane2, lcVector4(Vertices[Index3], 1.0f)));
|
float Dot3 = fabsf(lcDot(Plane2, lcVector4(Vertices[Index3], 1.0f)));
|
||||||
|
@ -482,7 +485,7 @@ void lcMeshLoaderTypeData::ProcessTexturedLine(int LineType, quint32 ColorCode,
|
||||||
CheckTexCoordsWrap(QuadIndices[2], QuadIndices[3], QuadIndices[0]);
|
CheckTexCoordsWrap(QuadIndices[2], QuadIndices[3], QuadIndices[0]);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (TextureMap.Type == lcMeshLoaderTextureMapType::Spherical)
|
if (TextureMap.Type == lcMeshLoaderMaterialType::Spherical)
|
||||||
{
|
{
|
||||||
auto CheckTexCoordsPole = [&TexCoords, &Vertices, &TextureMap](int Index1, int Index2, int Index3)
|
auto CheckTexCoordsPole = [&TexCoords, &Vertices, &TextureMap](int Index1, int Index2, int Index3)
|
||||||
{
|
{
|
||||||
|
@ -654,21 +657,30 @@ void lcMeshLoaderTypeData::AddMeshData(const lcMeshLoaderTypeData& Data, const l
|
||||||
|
|
||||||
for (const std::unique_ptr<lcMeshLoaderSection>& SrcSection : Data.mSections)
|
for (const std::unique_ptr<lcMeshLoaderSection>& SrcSection : Data.mSections)
|
||||||
{
|
{
|
||||||
quint32 ColorCode = SrcSection->mColor == 16 ? CurrentColorCode : SrcSection->mColor;
|
const quint32 ColorCode = SrcSection->mMaterial->Color == 16 ? CurrentColorCode : SrcSection->mMaterial->Color;
|
||||||
lcTexture* Texture;
|
|
||||||
lcMeshPrimitiveType PrimitiveType = SrcSection->mPrimitiveType;
|
lcMeshPrimitiveType PrimitiveType = SrcSection->mPrimitiveType;
|
||||||
|
lcMeshLoaderSection* DstSection;
|
||||||
|
|
||||||
if (SrcSection->mTexture)
|
if (SrcSection->mMaterial->Type != lcMeshLoaderMaterialType::Solid)
|
||||||
Texture = SrcSection->mTexture;
|
{
|
||||||
|
lcMeshLoaderTextureMap DstTextureMap = *TextureMap;
|
||||||
|
|
||||||
|
for (lcVector3& Point : DstTextureMap.Points)
|
||||||
|
Point = lcMul31(Point, Transform);
|
||||||
|
|
||||||
|
DstSection = AddSection(PrimitiveType, mMeshData->GetTexturedMaterial(ColorCode, DstTextureMap));
|
||||||
|
}
|
||||||
else if (TextureMap && SrcSection->mPrimitiveType == LC_MESH_TRIANGLES)
|
else if (TextureMap && SrcSection->mPrimitiveType == LC_MESH_TRIANGLES)
|
||||||
{
|
{
|
||||||
Texture = TextureMap->Texture;
|
|
||||||
PrimitiveType = LC_MESH_TEXTURED_TRIANGLES;
|
PrimitiveType = LC_MESH_TEXTURED_TRIANGLES;
|
||||||
|
|
||||||
|
DstSection = AddSection(PrimitiveType, mMeshData->GetTexturedMaterial(ColorCode, *TextureMap));
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
Texture = nullptr;
|
{
|
||||||
|
DstSection = AddSection(PrimitiveType, mMeshData->GetMaterial(ColorCode));
|
||||||
|
}
|
||||||
|
|
||||||
lcMeshLoaderSection* DstSection = AddSection(PrimitiveType, ColorCode, Texture);
|
|
||||||
DstSection->mIndices.AllocGrow(SrcSection->mIndices.GetSize());
|
DstSection->mIndices.AllocGrow(SrcSection->mIndices.GetSize());
|
||||||
|
|
||||||
if (PrimitiveType == LC_MESH_CONDITIONAL_LINES)
|
if (PrimitiveType == LC_MESH_CONDITIONAL_LINES)
|
||||||
|
@ -758,21 +770,30 @@ void lcMeshLoaderTypeData::AddMeshDataNoDuplicateCheck(const lcMeshLoaderTypeDat
|
||||||
|
|
||||||
for (const std::unique_ptr<lcMeshLoaderSection>& SrcSection : Data.mSections)
|
for (const std::unique_ptr<lcMeshLoaderSection>& SrcSection : Data.mSections)
|
||||||
{
|
{
|
||||||
quint32 ColorCode = SrcSection->mColor == 16 ? CurrentColorCode : SrcSection->mColor;
|
const quint32 ColorCode = SrcSection->mMaterial->Color == 16 ? CurrentColorCode : SrcSection->mMaterial->Color;
|
||||||
lcTexture* Texture;
|
|
||||||
lcMeshPrimitiveType PrimitiveType = SrcSection->mPrimitiveType;
|
lcMeshPrimitiveType PrimitiveType = SrcSection->mPrimitiveType;
|
||||||
|
lcMeshLoaderSection* DstSection;
|
||||||
|
|
||||||
if (SrcSection->mTexture)
|
if (SrcSection->mMaterial->Type != lcMeshLoaderMaterialType::Solid)
|
||||||
Texture = SrcSection->mTexture;
|
{
|
||||||
|
lcMeshLoaderTextureMap DstTextureMap = *TextureMap;
|
||||||
|
|
||||||
|
for (lcVector3& Point : DstTextureMap.Points)
|
||||||
|
Point = lcMul31(Point, Transform);
|
||||||
|
|
||||||
|
DstSection = AddSection(PrimitiveType, mMeshData->GetTexturedMaterial(ColorCode, DstTextureMap));
|
||||||
|
}
|
||||||
else if (TextureMap && SrcSection->mPrimitiveType == LC_MESH_TRIANGLES)
|
else if (TextureMap && SrcSection->mPrimitiveType == LC_MESH_TRIANGLES)
|
||||||
{
|
{
|
||||||
Texture = TextureMap->Texture;
|
|
||||||
PrimitiveType = LC_MESH_TEXTURED_TRIANGLES;
|
PrimitiveType = LC_MESH_TEXTURED_TRIANGLES;
|
||||||
|
|
||||||
|
DstSection = AddSection(PrimitiveType, mMeshData->GetTexturedMaterial(ColorCode, *TextureMap));
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
Texture = nullptr;
|
{
|
||||||
|
DstSection = AddSection(PrimitiveType, mMeshData->GetMaterial(ColorCode));
|
||||||
|
}
|
||||||
|
|
||||||
lcMeshLoaderSection* DstSection = AddSection(SrcSection->mPrimitiveType, ColorCode, Texture);
|
|
||||||
DstSection->mIndices.SetGrow(lcMin(DstSection->mIndices.GetSize(), 8 * 1024 * 1024));
|
DstSection->mIndices.SetGrow(lcMin(DstSection->mIndices.GetSize(), 8 * 1024 * 1024));
|
||||||
DstSection->mIndices.AllocGrow(SrcSection->mIndices.GetSize());
|
DstSection->mIndices.AllocGrow(SrcSection->mIndices.GetSize());
|
||||||
|
|
||||||
|
@ -811,7 +832,7 @@ void lcLibraryMeshData::AddVertices(lcMeshDataType MeshDataType, int VertexCount
|
||||||
|
|
||||||
void lcLibraryMeshData::AddIndices(lcMeshDataType MeshDataType, lcMeshPrimitiveType PrimitiveType, quint32 ColorCode, int IndexCount, quint32** IndexBuffer)
|
void lcLibraryMeshData::AddIndices(lcMeshDataType MeshDataType, lcMeshPrimitiveType PrimitiveType, quint32 ColorCode, int IndexCount, quint32** IndexBuffer)
|
||||||
{
|
{
|
||||||
lcMeshLoaderSection* Section = mData[MeshDataType].AddSection(PrimitiveType, ColorCode, nullptr);
|
lcMeshLoaderSection* Section = mData[MeshDataType].AddSection(PrimitiveType, GetMaterial(ColorCode));
|
||||||
lcArray<quint32>& Indices = Section->mIndices;
|
lcArray<quint32>& Indices = Section->mIndices;
|
||||||
int CurrentSize = Indices.GetSize();
|
int CurrentSize = Indices.GetSize();
|
||||||
|
|
||||||
|
@ -842,12 +863,66 @@ void lcLibraryMeshData::AddMeshDataNoDuplicateCheck(const lcLibraryMeshData& Dat
|
||||||
mHasTextures |= (Data.mHasTextures || TextureMap);
|
mHasTextures |= (Data.mHasTextures || TextureMap);
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool lcLibraryMeshSectionCompare(const lcMergeSection& First, const lcMergeSection& Second)
|
lcMeshLoaderMaterial* lcLibraryMeshData::GetMaterial(quint32 ColorCode)
|
||||||
{
|
{
|
||||||
lcMeshLoaderSection* a = First.Lod ? First.Lod : First.Shared;
|
for (std::unique_ptr<lcMeshLoaderMaterial>& Material : mMaterials)
|
||||||
lcMeshLoaderSection* b = Second.Lod ? Second.Lod : Second.Shared;
|
if (Material->Type == lcMeshLoaderMaterialType::Solid && Material->Color == ColorCode)
|
||||||
|
return Material.get();
|
||||||
|
|
||||||
if (a->mPrimitiveType != b->mPrimitiveType)
|
lcMeshLoaderMaterial* Material = new lcMeshLoaderMaterial();
|
||||||
|
mMaterials.emplace_back(Material);
|
||||||
|
|
||||||
|
Material->Type = lcMeshLoaderMaterialType::Solid;
|
||||||
|
Material->Color = ColorCode;
|
||||||
|
|
||||||
|
return Material;
|
||||||
|
}
|
||||||
|
|
||||||
|
lcMeshLoaderMaterial* lcLibraryMeshData::GetTexturedMaterial(quint32 ColorCode, const lcMeshLoaderTextureMap& TextureMap)
|
||||||
|
{
|
||||||
|
for (std::unique_ptr<lcMeshLoaderMaterial>& Material : mMaterials)
|
||||||
|
{
|
||||||
|
if (Material->Type != TextureMap.Type || Material->Color != ColorCode)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (strcmp(Material->Name, TextureMap.Name))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (Material->Points[0] != TextureMap.Points[0] || Material->Points[1] != TextureMap.Points[1] || Material->Points[2] != TextureMap.Points[2])
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (Material->Type == lcMeshLoaderMaterialType::Cylindrical)
|
||||||
|
{
|
||||||
|
if (Material->Angles[0] != TextureMap.Angles[0])
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
else if (Material->Type == lcMeshLoaderMaterialType::Spherical)
|
||||||
|
{
|
||||||
|
if (Material->Angles[0] != TextureMap.Angles[0] || Material->Angles[1] != TextureMap.Angles[1])
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
return Material.get();
|
||||||
|
}
|
||||||
|
|
||||||
|
lcMeshLoaderMaterial* Material = new lcMeshLoaderMaterial();
|
||||||
|
mMaterials.emplace_back(Material);
|
||||||
|
|
||||||
|
Material->Type = TextureMap.Type;
|
||||||
|
Material->Color = ColorCode;
|
||||||
|
Material->Points[0] = TextureMap.Points[0];
|
||||||
|
Material->Points[1] = TextureMap.Points[1];
|
||||||
|
Material->Points[2] = TextureMap.Points[2];
|
||||||
|
Material->Angles[0] = TextureMap.Angles[0];
|
||||||
|
Material->Angles[1] = TextureMap.Angles[1];
|
||||||
|
strcpy(Material->Name, TextureMap.Name);
|
||||||
|
|
||||||
|
return Material;
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool lcMeshLoaderFinalSectionCompare(const lcMeshLoaderFinalSection& a, const lcMeshLoaderFinalSection& b)
|
||||||
|
{
|
||||||
|
if (a.PrimitiveType != b.PrimitiveType)
|
||||||
{
|
{
|
||||||
int PrimitiveOrder[LC_MESH_NUM_PRIMITIVE_TYPES] =
|
int PrimitiveOrder[LC_MESH_NUM_PRIMITIVE_TYPES] =
|
||||||
{
|
{
|
||||||
|
@ -861,21 +936,21 @@ static bool lcLibraryMeshSectionCompare(const lcMergeSection& First, const lcMer
|
||||||
{
|
{
|
||||||
int Primitive = PrimitiveOrder[PrimitiveType];
|
int Primitive = PrimitiveOrder[PrimitiveType];
|
||||||
|
|
||||||
if (a->mPrimitiveType == Primitive)
|
if (a.PrimitiveType == Primitive)
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
if (b->mPrimitiveType == Primitive)
|
if (b.PrimitiveType == Primitive)
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool TranslucentA = lcIsColorTranslucent(a->mColor);
|
bool TranslucentA = lcIsColorTranslucent(a.Color);
|
||||||
bool TranslucentB = lcIsColorTranslucent(b->mColor);
|
bool TranslucentB = lcIsColorTranslucent(b.Color);
|
||||||
|
|
||||||
if (TranslucentA != TranslucentB)
|
if (TranslucentA != TranslucentB)
|
||||||
return !TranslucentA;
|
return !TranslucentA;
|
||||||
|
|
||||||
return a->mColor > b->mColor;
|
return a.Color > b.Color;
|
||||||
}
|
}
|
||||||
|
|
||||||
lcMesh* lcLibraryMeshData::CreateMesh()
|
lcMesh* lcLibraryMeshData::CreateMesh()
|
||||||
|
@ -891,15 +966,14 @@ lcMesh* lcLibraryMeshData::CreateMesh()
|
||||||
std::vector<quint32> IndexRemap[LC_NUM_MESHDATA_TYPES];
|
std::vector<quint32> IndexRemap[LC_NUM_MESHDATA_TYPES];
|
||||||
std::vector<quint32> TexturedIndexRemap[LC_NUM_MESHDATA_TYPES];
|
std::vector<quint32> TexturedIndexRemap[LC_NUM_MESHDATA_TYPES];
|
||||||
|
|
||||||
|
// todo: I don't think we should be converting to color index here because it gets saved to the cache
|
||||||
|
for (const std::unique_ptr<lcMeshLoaderMaterial>& Material : mMaterials)
|
||||||
|
Material->Color = lcGetColorIndex(Material->Color);
|
||||||
|
|
||||||
if (!mHasTextures)
|
if (!mHasTextures)
|
||||||
{
|
{
|
||||||
for (int MeshDataIdx = 0; MeshDataIdx < LC_NUM_MESHDATA_TYPES; MeshDataIdx++)
|
for (int MeshDataIdx = 0; MeshDataIdx < LC_NUM_MESHDATA_TYPES; MeshDataIdx++)
|
||||||
{
|
{
|
||||||
std::vector<std::unique_ptr<lcMeshLoaderSection>>& Sections = mData[MeshDataIdx].mSections;
|
|
||||||
|
|
||||||
for (const std::unique_ptr<lcMeshLoaderSection>& Section : Sections)
|
|
||||||
Section->mColor = lcGetColorIndex(Section->mColor);
|
|
||||||
|
|
||||||
BaseVertices[MeshDataIdx] = NumVertices;
|
BaseVertices[MeshDataIdx] = NumVertices;
|
||||||
NumVertices += mData[MeshDataIdx].mVertices.GetSize();
|
NumVertices += mData[MeshDataIdx].mVertices.GetSize();
|
||||||
BaseConditionalVertices[MeshDataIdx] = ConditionalVertexCount;
|
BaseConditionalVertices[MeshDataIdx] = ConditionalVertexCount;
|
||||||
|
@ -910,11 +984,6 @@ lcMesh* lcLibraryMeshData::CreateMesh()
|
||||||
{
|
{
|
||||||
for (int MeshDataIdx = 0; MeshDataIdx < LC_NUM_MESHDATA_TYPES; MeshDataIdx++)
|
for (int MeshDataIdx = 0; MeshDataIdx < LC_NUM_MESHDATA_TYPES; MeshDataIdx++)
|
||||||
{
|
{
|
||||||
std::vector<std::unique_ptr<lcMeshLoaderSection>>& Sections = mData[MeshDataIdx].mSections;
|
|
||||||
|
|
||||||
for (const std::unique_ptr<lcMeshLoaderSection>& Section : Sections)
|
|
||||||
Section->mColor = lcGetColorIndex(Section->mColor);
|
|
||||||
|
|
||||||
BaseVertices[MeshDataIdx] = NumVertices;
|
BaseVertices[MeshDataIdx] = NumVertices;
|
||||||
BaseTexturedVertices[MeshDataIdx] = NumTexturedVertices;
|
BaseTexturedVertices[MeshDataIdx] = NumTexturedVertices;
|
||||||
|
|
||||||
|
@ -947,51 +1016,39 @@ lcMesh* lcLibraryMeshData::CreateMesh()
|
||||||
quint16 NumSections[LC_NUM_MESH_LODS];
|
quint16 NumSections[LC_NUM_MESH_LODS];
|
||||||
int NumIndices = 0;
|
int NumIndices = 0;
|
||||||
|
|
||||||
lcArray<lcMergeSection> MergeSections[LC_NUM_MESH_LODS];
|
lcArray<lcMeshLoaderFinalSection> FinalSections[LC_NUM_MESH_LODS];
|
||||||
|
|
||||||
for (int LodIdx = 0; LodIdx < LC_NUM_MESH_LODS; LodIdx++)
|
for (int LodIdx = 0; LodIdx < LC_NUM_MESH_LODS; LodIdx++)
|
||||||
{
|
{
|
||||||
std::vector<std::unique_ptr<lcMeshLoaderSection>>& SharedSections = mData[LC_MESHDATA_SHARED].mSections;
|
auto AddFinalSection = [](lcMeshLoaderSection* Section, lcArray<lcMeshLoaderFinalSection>& FinalSections)
|
||||||
std::vector<std::unique_ptr<lcMeshLoaderSection>>& Sections = mData[LodIdx].mSections;
|
|
||||||
|
|
||||||
for (std::unique_ptr<lcMeshLoaderSection>& SharedSection : SharedSections)
|
|
||||||
{
|
{
|
||||||
NumIndices += SharedSection->mIndices.GetSize();
|
for (const lcMeshLoaderFinalSection& FinalSection : FinalSections)
|
||||||
|
if (FinalSection.PrimitiveType == Section->mPrimitiveType && FinalSection.Color == Section->mMaterial->Color && !strcmp(FinalSection.Name, Section->mMaterial->Name))
|
||||||
|
return;
|
||||||
|
|
||||||
lcMergeSection& MergeSection = MergeSections[LodIdx].Add();
|
lcMeshLoaderFinalSection& FinalSection = FinalSections.Add();
|
||||||
MergeSection.Shared = SharedSection.get();
|
|
||||||
MergeSection.Lod = nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (std::unique_ptr<lcMeshLoaderSection>& Section : Sections)
|
FinalSection.PrimitiveType = Section->mPrimitiveType;
|
||||||
|
FinalSection.Color = Section->mMaterial->Color;
|
||||||
|
strcpy(FinalSection.Name, Section->mMaterial->Name);
|
||||||
|
};
|
||||||
|
|
||||||
|
for (std::unique_ptr<lcMeshLoaderSection>& Section : mData[LC_MESHDATA_SHARED].mSections)
|
||||||
{
|
{
|
||||||
bool Found = false;
|
|
||||||
|
|
||||||
NumIndices += Section->mIndices.GetSize();
|
NumIndices += Section->mIndices.GetSize();
|
||||||
|
|
||||||
for (int SharedSectionIdx = 0; SharedSectionIdx < (int)SharedSections.size(); SharedSectionIdx++)
|
AddFinalSection(Section.get(), FinalSections[LodIdx]);
|
||||||
{
|
|
||||||
lcMeshLoaderSection* SharedSection = SharedSections[SharedSectionIdx].get();
|
|
||||||
|
|
||||||
if (SharedSection->mColor == Section->mColor && SharedSection->mPrimitiveType == Section->mPrimitiveType && SharedSection->mTexture == Section->mTexture)
|
|
||||||
{
|
|
||||||
lcMergeSection& MergeSection = MergeSections[LodIdx][SharedSectionIdx];
|
|
||||||
MergeSection.Lod = Section.get();
|
|
||||||
Found = true;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!Found)
|
|
||||||
{
|
|
||||||
lcMergeSection& MergeSection = MergeSections[LodIdx].Add();
|
|
||||||
MergeSection.Shared = nullptr;
|
|
||||||
MergeSection.Lod = Section.get();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
NumSections[LodIdx] = MergeSections[LodIdx].GetSize();
|
for (std::unique_ptr<lcMeshLoaderSection>& Section : mData[LodIdx].mSections)
|
||||||
std::sort(MergeSections[LodIdx].begin(), MergeSections[LodIdx].end(), lcLibraryMeshSectionCompare);
|
{
|
||||||
|
NumIndices += Section->mIndices.GetSize();
|
||||||
|
|
||||||
|
AddFinalSection(Section.get(), FinalSections[LodIdx]);
|
||||||
|
}
|
||||||
|
|
||||||
|
NumSections[LodIdx] = FinalSections[LodIdx].GetSize();
|
||||||
|
std::sort(FinalSections[LodIdx].begin(), FinalSections[LodIdx].end(), lcMeshLoaderFinalSectionCompare);
|
||||||
}
|
}
|
||||||
|
|
||||||
Mesh->Create(NumSections, NumVertices, NumTexturedVertices, ConditionalVertexCount, NumIndices);
|
Mesh->Create(NumSections, NumVertices, NumTexturedVertices, ConditionalVertexCount, NumIndices);
|
||||||
|
@ -1070,7 +1127,7 @@ lcMesh* lcLibraryMeshData::CreateMesh()
|
||||||
}
|
}
|
||||||
else if (Section->mPrimitiveType != LC_MESH_CONDITIONAL_LINES)
|
else if (Section->mPrimitiveType != LC_MESH_CONDITIONAL_LINES)
|
||||||
{
|
{
|
||||||
if (!Section->mTexture)
|
if (Section->mMaterial->Type == lcMeshLoaderMaterialType::Solid)
|
||||||
{
|
{
|
||||||
for (quint32& Index : Section->mIndices)
|
for (quint32& Index : Section->mIndices)
|
||||||
Index = IndexRemap[MeshDataIdx][Index];
|
Index = IndexRemap[MeshDataIdx][Index];
|
||||||
|
@ -1101,9 +1158,9 @@ lcMesh* lcLibraryMeshData::CreateMesh()
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Mesh->mIndexType == GL_UNSIGNED_SHORT)
|
if (Mesh->mIndexType == GL_UNSIGNED_SHORT)
|
||||||
WriteSections<quint16>(Mesh, MergeSections, BaseVertices, BaseTexturedVertices, BaseConditionalVertices);
|
WriteSections<quint16>(Mesh, FinalSections, BaseVertices, BaseTexturedVertices, BaseConditionalVertices);
|
||||||
else
|
else
|
||||||
WriteSections<quint32>(Mesh, MergeSections, BaseVertices, BaseTexturedVertices, BaseConditionalVertices);
|
WriteSections<quint32>(Mesh, FinalSections, BaseVertices, BaseTexturedVertices, BaseConditionalVertices);
|
||||||
|
|
||||||
if (mHasStyleStud)
|
if (mHasStyleStud)
|
||||||
Mesh->mFlags |= lcMeshFlag::HasStyleStud;
|
Mesh->mFlags |= lcMeshFlag::HasStyleStud;
|
||||||
|
@ -1114,40 +1171,45 @@ lcMesh* lcLibraryMeshData::CreateMesh()
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename IndexType>
|
template<typename IndexType>
|
||||||
void lcLibraryMeshData::WriteSections(lcMesh* Mesh, const lcArray<lcMergeSection> (&MergeSections)[LC_NUM_MESH_LODS], int(&BaseVertices)[LC_NUM_MESHDATA_TYPES], int(&BaseTexturedVertices)[LC_NUM_MESHDATA_TYPES], int(&BaseConditionalVertices)[LC_NUM_MESHDATA_TYPES])
|
void lcLibraryMeshData::WriteSections(lcMesh* Mesh, const lcArray<lcMeshLoaderFinalSection> (&FinalSections)[LC_NUM_MESH_LODS], int(&BaseVertices)[LC_NUM_MESHDATA_TYPES], int(&BaseTexturedVertices)[LC_NUM_MESHDATA_TYPES], int(&BaseConditionalVertices)[LC_NUM_MESHDATA_TYPES])
|
||||||
{
|
{
|
||||||
int NumIndices = 0;
|
int NumIndices = 0;
|
||||||
|
|
||||||
for (int LodIdx = 0; LodIdx < LC_NUM_MESH_LODS; LodIdx++)
|
for (int LodIdx = 0; LodIdx < LC_NUM_MESH_LODS; LodIdx++)
|
||||||
{
|
{
|
||||||
for (int SectionIdx = 0; SectionIdx < MergeSections[LodIdx].GetSize(); SectionIdx++)
|
for (int SectionIdx = 0; SectionIdx < FinalSections[LodIdx].GetSize(); SectionIdx++)
|
||||||
{
|
{
|
||||||
const lcMergeSection& MergeSection = MergeSections[LodIdx][SectionIdx];
|
const lcMeshLoaderFinalSection& FinalSection = FinalSections[LodIdx][SectionIdx];
|
||||||
lcMeshSection& DstSection = Mesh->mLods[LodIdx].Sections[SectionIdx];
|
lcMeshSection& DstSection = Mesh->mLods[LodIdx].Sections[SectionIdx];
|
||||||
|
|
||||||
lcMeshLoaderSection* SetupSection = MergeSection.Shared ? MergeSection.Shared : MergeSection.Lod;
|
DstSection.ColorIndex = FinalSection.Color;
|
||||||
|
DstSection.PrimitiveType = FinalSection.PrimitiveType;
|
||||||
DstSection.ColorIndex = SetupSection->mColor;
|
|
||||||
DstSection.PrimitiveType = SetupSection->mPrimitiveType;
|
|
||||||
DstSection.NumIndices = 0;
|
DstSection.NumIndices = 0;
|
||||||
DstSection.Texture = SetupSection->mTexture;
|
|
||||||
|
|
||||||
if (DstSection.Texture)
|
if (!FinalSection.Name[0])
|
||||||
DstSection.Texture->AddRef();
|
DstSection.Texture = nullptr;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (mMeshLoader)
|
||||||
|
DstSection.Texture = lcGetPiecesLibrary()->FindTexture(FinalSection.Name, mMeshLoader->mCurrentProject, mMeshLoader->mSearchProjectFolder);
|
||||||
|
else
|
||||||
|
DstSection.Texture = lcGetPiecesLibrary()->FindTexture(FinalSection.Name, nullptr, false);
|
||||||
|
|
||||||
|
if (DstSection.Texture)
|
||||||
|
DstSection.Texture->AddRef();
|
||||||
|
}
|
||||||
|
|
||||||
DstSection.IndexOffset = NumIndices * sizeof(IndexType);
|
DstSection.IndexOffset = NumIndices * sizeof(IndexType);
|
||||||
|
|
||||||
IndexType* Index = (IndexType*)Mesh->mIndexData + NumIndices;
|
IndexType* Index = (IndexType*)Mesh->mIndexData + NumIndices;
|
||||||
|
|
||||||
if (MergeSection.Shared)
|
auto AddSection = [this, &DstSection, &Index, &BaseVertices, &BaseTexturedVertices, &BaseConditionalVertices](lcMeshLoaderSection* SrcSection, lcMeshDataType SrcDataType)
|
||||||
{
|
{
|
||||||
lcMeshLoaderSection* SrcSection = MergeSection.Shared;
|
|
||||||
|
|
||||||
if (DstSection.PrimitiveType != LC_MESH_CONDITIONAL_LINES)
|
if (DstSection.PrimitiveType != LC_MESH_CONDITIONAL_LINES)
|
||||||
{
|
{
|
||||||
if (!mHasTextures)
|
if (!mHasTextures)
|
||||||
{
|
{
|
||||||
IndexType BaseVertex = DstSection.Texture ? BaseTexturedVertices[LC_MESHDATA_SHARED] : BaseVertices[LC_MESHDATA_SHARED];
|
IndexType BaseVertex = DstSection.Texture ? BaseTexturedVertices[SrcDataType] : BaseVertices[SrcDataType];
|
||||||
|
|
||||||
for (int IndexIdx = 0; IndexIdx < SrcSection->mIndices.GetSize(); IndexIdx++)
|
for (int IndexIdx = 0; IndexIdx < SrcSection->mIndices.GetSize(); IndexIdx++)
|
||||||
*Index++ = BaseVertex + SrcSection->mIndices[IndexIdx];
|
*Index++ = BaseVertex + SrcSection->mIndices[IndexIdx];
|
||||||
|
@ -1158,42 +1220,24 @@ void lcLibraryMeshData::WriteSections(lcMesh* Mesh, const lcArray<lcMergeSection
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
IndexType BaseVertex = BaseConditionalVertices[LC_MESHDATA_SHARED];
|
IndexType BaseVertex = BaseConditionalVertices[SrcDataType];
|
||||||
|
|
||||||
for (int IndexIdx = 0; IndexIdx < SrcSection->mIndices.GetSize(); IndexIdx++)
|
for (int IndexIdx = 0; IndexIdx < SrcSection->mIndices.GetSize(); IndexIdx++)
|
||||||
*Index++ = BaseVertex + SrcSection->mIndices[IndexIdx];
|
*Index++ = BaseVertex + SrcSection->mIndices[IndexIdx];
|
||||||
}
|
}
|
||||||
|
|
||||||
DstSection.NumIndices += SrcSection->mIndices.GetSize();
|
DstSection.NumIndices += SrcSection->mIndices.GetSize();
|
||||||
}
|
};
|
||||||
|
|
||||||
if (MergeSection.Lod)
|
for (std::unique_ptr<lcMeshLoaderSection>& Section : mData[LC_MESHDATA_SHARED].mSections)
|
||||||
{
|
if (FinalSection.PrimitiveType == Section->mPrimitiveType && FinalSection.Color == Section->mMaterial->Color && !strcmp(FinalSection.Name, Section->mMaterial->Name))
|
||||||
lcMeshLoaderSection* SrcSection = MergeSection.Lod;
|
AddSection(Section.get(), LC_MESHDATA_SHARED);
|
||||||
|
|
||||||
if (DstSection.PrimitiveType != LC_MESH_CONDITIONAL_LINES)
|
const lcMeshDataType MeshDataType = (LodIdx == LC_MESH_LOD_LOW) ? LC_MESHDATA_LOW : LC_MESHDATA_HIGH;
|
||||||
{
|
|
||||||
if (!mHasTextures)
|
|
||||||
{
|
|
||||||
IndexType BaseVertex = DstSection.Texture ? BaseTexturedVertices[LodIdx] : BaseVertices[LodIdx];
|
|
||||||
|
|
||||||
for (int IndexIdx = 0; IndexIdx < SrcSection->mIndices.GetSize(); IndexIdx++)
|
for (std::unique_ptr<lcMeshLoaderSection>& Section : mData[MeshDataType].mSections)
|
||||||
*Index++ = BaseVertex + SrcSection->mIndices[IndexIdx];
|
if (FinalSection.PrimitiveType == Section->mPrimitiveType && FinalSection.Color == Section->mMaterial->Color && !strcmp(FinalSection.Name, Section->mMaterial->Name))
|
||||||
}
|
AddSection(Section.get(), MeshDataType);
|
||||||
else
|
|
||||||
for (int IndexIdx = 0; IndexIdx < SrcSection->mIndices.GetSize(); IndexIdx++)
|
|
||||||
*Index++ = SrcSection->mIndices[IndexIdx];
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
IndexType BaseVertex = BaseConditionalVertices[LodIdx];
|
|
||||||
|
|
||||||
for (int IndexIdx = 0; IndexIdx < SrcSection->mIndices.GetSize(); IndexIdx++)
|
|
||||||
*Index++ = BaseVertex + SrcSection->mIndices[IndexIdx];
|
|
||||||
}
|
|
||||||
|
|
||||||
DstSection.NumIndices += SrcSection->mIndices.GetSize();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (DstSection.PrimitiveType == LC_MESH_TRIANGLES || DstSection.PrimitiveType == LC_MESH_TEXTURED_TRIANGLES)
|
if (DstSection.PrimitiveType == LC_MESH_TRIANGLES || DstSection.PrimitiveType == LC_MESH_TEXTURED_TRIANGLES)
|
||||||
{
|
{
|
||||||
|
@ -1304,6 +1348,7 @@ void lcLibraryMeshData::UpdateMeshSectionBoundingBox(lcMesh* Mesh, lcMeshSection
|
||||||
lcMeshLoader::lcMeshLoader(lcLibraryMeshData& MeshData, bool Optimize, Project* CurrentProject, bool SearchProjectFolder)
|
lcMeshLoader::lcMeshLoader(lcLibraryMeshData& MeshData, bool Optimize, Project* CurrentProject, bool SearchProjectFolder)
|
||||||
: mMeshData(MeshData), mOptimize(Optimize), mCurrentProject(CurrentProject), mSearchProjectFolder(SearchProjectFolder)
|
: mMeshData(MeshData), mOptimize(Optimize), mCurrentProject(CurrentProject), mSearchProjectFolder(SearchProjectFolder)
|
||||||
{
|
{
|
||||||
|
MeshData.SetMeshLoader(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool lcMeshLoader::LoadMesh(lcFile& File, lcMeshDataType MeshDataType)
|
bool lcMeshLoader::LoadMesh(lcFile& File, lcMeshDataType MeshDataType)
|
||||||
|
@ -1411,22 +1456,19 @@ bool lcMeshLoader::ReadMeshData(lcFile& File, const lcMatrix44& CurrentTransform
|
||||||
{
|
{
|
||||||
Token += 7;
|
Token += 7;
|
||||||
|
|
||||||
char FileName[LC_MAXPATH];
|
lcMeshLoaderTextureMap& Map = mTextureStack.Add();
|
||||||
lcVector3 Points[3];
|
lcVector3 (&Points)[3] = Map.Points;
|
||||||
|
|
||||||
sscanf(Token, "%f %f %f %f %f %f %f %f %f %s", &Points[0].x, &Points[0].y, &Points[0].z, &Points[1].x, &Points[1].y, &Points[1].z, &Points[2].x, &Points[2].y, &Points[2].z, FileName);
|
sscanf(Token, "%f %f %f %f %f %f %f %f %f %s", &Points[0].x, &Points[0].y, &Points[0].z, &Points[1].x, &Points[1].y, &Points[1].z, &Points[2].x, &Points[2].y, &Points[2].z, Map.Name);
|
||||||
|
|
||||||
Points[0] = lcMul31(Points[0], CurrentTransform);
|
Points[0] = lcMul31(Points[0], CurrentTransform);
|
||||||
Points[1] = lcMul31(Points[1], CurrentTransform);
|
Points[1] = lcMul31(Points[1], CurrentTransform);
|
||||||
Points[2] = lcMul31(Points[2], CurrentTransform);
|
Points[2] = lcMul31(Points[2], CurrentTransform);
|
||||||
|
|
||||||
CleanTextureName(FileName);
|
CleanTextureName(Map.Name);
|
||||||
|
|
||||||
lcMeshLoaderTextureMap& Map = mTextureStack.Add();
|
// Map.Texture = Library->FindTexture(Map.Name, mCurrentProject, mSearchProjectFolder);
|
||||||
Map.Next = false;
|
Map.Type = lcMeshLoaderMaterialType::Planar;
|
||||||
Map.Fallback = false;
|
|
||||||
Map.Texture = Library->FindTexture(FileName, mCurrentProject, mSearchProjectFolder);
|
|
||||||
Map.Type = lcMeshLoaderTextureMapType::Planar;
|
|
||||||
|
|
||||||
for (int EdgeIdx = 0; EdgeIdx < 2; EdgeIdx++)
|
for (int EdgeIdx = 0; EdgeIdx < 2; EdgeIdx++)
|
||||||
{
|
{
|
||||||
|
@ -1444,24 +1486,21 @@ bool lcMeshLoader::ReadMeshData(lcFile& File, const lcMatrix44& CurrentTransform
|
||||||
{
|
{
|
||||||
Token += 12;
|
Token += 12;
|
||||||
|
|
||||||
char FileName[LC_MAXPATH];
|
lcMeshLoaderTextureMap& Map = mTextureStack.Add();
|
||||||
lcVector3 Points[3];
|
lcVector3 (&Points)[3] = Map.Points;
|
||||||
float Angle;
|
float& Angle = Map.Angles[0];
|
||||||
|
|
||||||
sscanf(Token, "%f %f %f %f %f %f %f %f %f %f %s", &Points[0].x, &Points[0].y, &Points[0].z, &Points[1].x, &Points[1].y, &Points[1].z, &Points[2].x, &Points[2].y, &Points[2].z, &Angle, FileName);
|
sscanf(Token, "%f %f %f %f %f %f %f %f %f %f %s", &Points[0].x, &Points[0].y, &Points[0].z, &Points[1].x, &Points[1].y, &Points[1].z, &Points[2].x, &Points[2].y, &Points[2].z, &Angle, Map.Name);
|
||||||
|
|
||||||
Points[0] = lcMul31(Points[0], CurrentTransform);
|
Points[0] = lcMul31(Points[0], CurrentTransform);
|
||||||
Points[1] = lcMul31(Points[1], CurrentTransform);
|
Points[1] = lcMul31(Points[1], CurrentTransform);
|
||||||
Points[2] = lcMul31(Points[2], CurrentTransform);
|
Points[2] = lcMul31(Points[2], CurrentTransform);
|
||||||
|
|
||||||
CleanTextureName(FileName);
|
CleanTextureName(Map.Name);
|
||||||
|
|
||||||
lcMeshLoaderTextureMap& Map = mTextureStack.Add();
|
// Map.Texture = Library->FindTexture(Map.Name, mCurrentProject, mSearchProjectFolder);
|
||||||
Map.Next = false;
|
Map.Type = lcMeshLoaderMaterialType::Cylindrical;
|
||||||
Map.Fallback = false;
|
|
||||||
Map.Texture = Library->FindTexture(FileName, mCurrentProject, mSearchProjectFolder);
|
|
||||||
|
|
||||||
Map.Type = lcMeshLoaderTextureMapType::Cylindrical;
|
|
||||||
lcVector3 Up = Points[0] - Points[1];
|
lcVector3 Up = Points[0] - Points[1];
|
||||||
float UpLength = lcLength(Up);
|
float UpLength = lcLength(Up);
|
||||||
lcVector3 Front = lcNormalize(Points[2] - Points[1]);
|
lcVector3 Front = lcNormalize(Points[2] - Points[1]);
|
||||||
|
@ -1477,23 +1516,21 @@ bool lcMeshLoader::ReadMeshData(lcFile& File, const lcMatrix44& CurrentTransform
|
||||||
{
|
{
|
||||||
Token += 10;
|
Token += 10;
|
||||||
|
|
||||||
char FileName[LC_MAXPATH];
|
lcMeshLoaderTextureMap& Map = mTextureStack.Add();
|
||||||
lcVector3 Points[3];
|
lcVector3(&Points)[3] = Map.Points;
|
||||||
float Angle1, Angle2;
|
float& Angle1 = Map.Angles[0];
|
||||||
|
float& Angle2 = Map.Angles[1];
|
||||||
|
|
||||||
sscanf(Token, "%f %f %f %f %f %f %f %f %f %f %f %s", &Points[0].x, &Points[0].y, &Points[0].z, &Points[1].x, &Points[1].y, &Points[1].z, &Points[2].x, &Points[2].y, &Points[2].z, &Angle1, &Angle2, FileName);
|
sscanf(Token, "%f %f %f %f %f %f %f %f %f %f %f %s", &Points[0].x, &Points[0].y, &Points[0].z, &Points[1].x, &Points[1].y, &Points[1].z, &Points[2].x, &Points[2].y, &Points[2].z, &Angle1, &Angle2, Map.Name);
|
||||||
|
|
||||||
Points[0] = lcMul31(Points[0], CurrentTransform);
|
Points[0] = lcMul31(Points[0], CurrentTransform);
|
||||||
Points[1] = lcMul31(Points[1], CurrentTransform);
|
Points[1] = lcMul31(Points[1], CurrentTransform);
|
||||||
Points[2] = lcMul31(Points[2], CurrentTransform);
|
Points[2] = lcMul31(Points[2], CurrentTransform);
|
||||||
|
|
||||||
CleanTextureName(FileName);
|
CleanTextureName(Map.Name);
|
||||||
|
|
||||||
lcMeshLoaderTextureMap& Map = mTextureStack.Add();
|
// Map.Texture = Library->FindTexture(Map.Name, mCurrentProject, mSearchProjectFolder);
|
||||||
Map.Next = false;
|
Map.Type = lcMeshLoaderMaterialType::Spherical;
|
||||||
Map.Fallback = false;
|
|
||||||
Map.Texture = Library->FindTexture(FileName, mCurrentProject, mSearchProjectFolder);
|
|
||||||
Map.Type = lcMeshLoaderTextureMapType::Spherical;
|
|
||||||
|
|
||||||
lcVector3 Front = lcNormalize(Points[1] - Points[0]);
|
lcVector3 Front = lcNormalize(Points[1] - Points[0]);
|
||||||
lcVector3 Plane1Normal = lcNormalize(lcCross(Front, Points[2] - Points[0]));
|
lcVector3 Plane1Normal = lcNormalize(lcCross(Front, Points[2] - Points[0]));
|
||||||
|
@ -1579,18 +1616,18 @@ bool lcMeshLoader::ReadMeshData(lcFile& File, const lcMatrix44& CurrentTransform
|
||||||
{
|
{
|
||||||
TextureMap = &mTextureStack[mTextureStack.GetSize() - 1];
|
TextureMap = &mTextureStack[mTextureStack.GetSize() - 1];
|
||||||
|
|
||||||
if (TextureMap->Texture)
|
// if (TextureMap->Texture)
|
||||||
{
|
{
|
||||||
if (TextureMap->Fallback)
|
if (TextureMap->Fallback)
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
else
|
// else
|
||||||
{
|
// {
|
||||||
if (!TextureMap->Fallback)
|
// if (!TextureMap->Fallback)
|
||||||
continue;
|
// continue;
|
||||||
|
//
|
||||||
TextureMap = nullptr;
|
// TextureMap = nullptr;
|
||||||
}
|
// }
|
||||||
}
|
}
|
||||||
|
|
||||||
int Dummy;
|
int Dummy;
|
||||||
|
@ -1656,7 +1693,7 @@ bool lcMeshLoader::ReadMeshData(lcFile& File, const lcMatrix44& CurrentTransform
|
||||||
Points[0] = lcMul31(Points[0], CurrentTransform);
|
Points[0] = lcMul31(Points[0], CurrentTransform);
|
||||||
Points[1] = lcMul31(Points[1], CurrentTransform);
|
Points[1] = lcMul31(Points[1], CurrentTransform);
|
||||||
|
|
||||||
mMeshData.mData[MeshDataType].ProcessLine(LineType, ColorCode, WindingCCW, Points, mOptimize);
|
mMeshData.mData[MeshDataType].ProcessLine(LineType, mMeshData.GetMaterial(ColorCode), WindingCCW, Points, mOptimize);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 3:
|
case 3:
|
||||||
|
@ -1667,16 +1704,16 @@ bool lcMeshLoader::ReadMeshData(lcFile& File, const lcMatrix44& CurrentTransform
|
||||||
Points[1] = lcMul31(Points[1], CurrentTransform);
|
Points[1] = lcMul31(Points[1], CurrentTransform);
|
||||||
Points[2] = lcMul31(Points[2], CurrentTransform);
|
Points[2] = lcMul31(Points[2], CurrentTransform);
|
||||||
|
|
||||||
if (TextureMap)
|
if (!TextureMap)
|
||||||
|
mMeshData.mData[MeshDataType].ProcessLine(LineType, mMeshData.GetMaterial(ColorCode), WindingCCW, Points, mOptimize);
|
||||||
|
else
|
||||||
{
|
{
|
||||||
mMeshData.mHasTextures = true;
|
mMeshData.mHasTextures = true;
|
||||||
mMeshData.mData[MeshDataType].ProcessTexturedLine(LineType, ColorCode, WindingCCW, *TextureMap, Points, mOptimize);
|
mMeshData.mData[MeshDataType].ProcessTexturedLine(LineType, mMeshData.GetTexturedMaterial(ColorCode, *TextureMap), WindingCCW, *TextureMap, Points, mOptimize);
|
||||||
|
|
||||||
if (TextureMap->Next)
|
if (TextureMap->Next)
|
||||||
mTextureStack.RemoveIndex(mTextureStack.GetSize() - 1);
|
mTextureStack.RemoveIndex(mTextureStack.GetSize() - 1);
|
||||||
}
|
}
|
||||||
else
|
|
||||||
mMeshData.mData[MeshDataType].ProcessLine(LineType, ColorCode, WindingCCW, Points, mOptimize);
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 4:
|
case 4:
|
||||||
|
@ -1688,16 +1725,16 @@ bool lcMeshLoader::ReadMeshData(lcFile& File, const lcMatrix44& CurrentTransform
|
||||||
Points[2] = lcMul31(Points[2], CurrentTransform);
|
Points[2] = lcMul31(Points[2], CurrentTransform);
|
||||||
Points[3] = lcMul31(Points[3], CurrentTransform);
|
Points[3] = lcMul31(Points[3], CurrentTransform);
|
||||||
|
|
||||||
if (TextureMap)
|
if (!TextureMap)
|
||||||
|
mMeshData.mData[MeshDataType].ProcessLine(LineType, mMeshData.GetMaterial(ColorCode), WindingCCW, Points, mOptimize);
|
||||||
|
else
|
||||||
{
|
{
|
||||||
mMeshData.mHasTextures = true;
|
mMeshData.mHasTextures = true;
|
||||||
mMeshData.mData[MeshDataType].ProcessTexturedLine(LineType, ColorCode, WindingCCW, *TextureMap, Points, mOptimize);
|
mMeshData.mData[MeshDataType].ProcessTexturedLine(LineType, mMeshData.GetTexturedMaterial(ColorCode, *TextureMap), WindingCCW, *TextureMap, Points, mOptimize);
|
||||||
|
|
||||||
if (TextureMap->Next)
|
if (TextureMap->Next)
|
||||||
mTextureStack.RemoveIndex(mTextureStack.GetSize() - 1);
|
mTextureStack.RemoveIndex(mTextureStack.GetSize() - 1);
|
||||||
}
|
}
|
||||||
else
|
|
||||||
mMeshData.mData[MeshDataType].ProcessLine(LineType, ColorCode, WindingCCW, Points, mOptimize);
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 5:
|
case 5:
|
||||||
|
@ -1709,7 +1746,7 @@ bool lcMeshLoader::ReadMeshData(lcFile& File, const lcMatrix44& CurrentTransform
|
||||||
Points[2] = lcMul31(Points[2], CurrentTransform);
|
Points[2] = lcMul31(Points[2], CurrentTransform);
|
||||||
Points[3] = lcMul31(Points[3], CurrentTransform);
|
Points[3] = lcMul31(Points[3], CurrentTransform);
|
||||||
|
|
||||||
mMeshData.mData[MeshDataType].ProcessLine(LineType, ColorCode, WindingCCW, Points, mOptimize);
|
mMeshData.mData[MeshDataType].ProcessLine(LineType, mMeshData.GetMaterial(ColorCode), WindingCCW, Points, mOptimize);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -4,6 +4,9 @@
|
||||||
#include "lc_math.h"
|
#include "lc_math.h"
|
||||||
#include "lc_mesh.h"
|
#include "lc_mesh.h"
|
||||||
|
|
||||||
|
class lcLibraryMeshData;
|
||||||
|
class lcMeshLoader;
|
||||||
|
|
||||||
#define LC_LIBRARY_VERTEX_UNTEXTURED 0x1
|
#define LC_LIBRARY_VERTEX_UNTEXTURED 0x1
|
||||||
#define LC_LIBRARY_VERTEX_TEXTURED 0x2
|
#define LC_LIBRARY_VERTEX_TEXTURED 0x2
|
||||||
|
|
||||||
|
@ -29,39 +32,46 @@ struct lcMeshLoaderConditionalVertex
|
||||||
lcVector3 Position[4];
|
lcVector3 Position[4];
|
||||||
};
|
};
|
||||||
|
|
||||||
class lcMeshLoaderSection
|
enum class lcMeshLoaderMaterialType
|
||||||
{
|
|
||||||
public:
|
|
||||||
lcMeshLoaderSection(lcMeshPrimitiveType PrimitiveType, quint32 Color, lcTexture* Texture)
|
|
||||||
: mIndices(1024, 1024)
|
|
||||||
{
|
|
||||||
mPrimitiveType = PrimitiveType;
|
|
||||||
mColor = Color;
|
|
||||||
mTexture = Texture;
|
|
||||||
}
|
|
||||||
|
|
||||||
lcMeshPrimitiveType mPrimitiveType;
|
|
||||||
quint32 mColor;
|
|
||||||
lcTexture* mTexture;
|
|
||||||
lcArray<quint32> mIndices;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct lcMergeSection
|
|
||||||
{
|
|
||||||
lcMeshLoaderSection* Shared;
|
|
||||||
lcMeshLoaderSection* Lod;
|
|
||||||
};
|
|
||||||
|
|
||||||
enum class lcMeshLoaderTextureMapType
|
|
||||||
{
|
{
|
||||||
|
Solid,
|
||||||
Planar,
|
Planar,
|
||||||
Cylindrical,
|
Cylindrical,
|
||||||
Spherical
|
Spherical
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct lcMeshLoaderMaterial
|
||||||
|
{
|
||||||
|
lcMeshLoaderMaterialType Type = lcMeshLoaderMaterialType::Solid;
|
||||||
|
quint32 Color = 16;
|
||||||
|
lcVector3 Points[3] = {};
|
||||||
|
float Angles[2] = {};
|
||||||
|
char Name[256] = {};
|
||||||
|
};
|
||||||
|
|
||||||
|
class lcMeshLoaderSection
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
lcMeshLoaderSection(lcMeshPrimitiveType PrimitiveType, lcMeshLoaderMaterial* Material)
|
||||||
|
: mMaterial(Material), mPrimitiveType(PrimitiveType), mIndices(1024, 1024)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
lcMeshLoaderMaterial* mMaterial;
|
||||||
|
lcMeshPrimitiveType mPrimitiveType;
|
||||||
|
lcArray<quint32> mIndices;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct lcMeshLoaderFinalSection
|
||||||
|
{
|
||||||
|
quint32 Color;
|
||||||
|
lcMeshPrimitiveType PrimitiveType;
|
||||||
|
char Name[256];
|
||||||
|
};
|
||||||
|
|
||||||
struct lcMeshLoaderTextureMap
|
struct lcMeshLoaderTextureMap
|
||||||
{
|
{
|
||||||
lcTexture* Texture;
|
// lcTexture* Texture;
|
||||||
|
|
||||||
union lcTextureMapParams
|
union lcTextureMapParams
|
||||||
{
|
{
|
||||||
|
@ -94,9 +104,13 @@ struct lcMeshLoaderTextureMap
|
||||||
} Spherical;
|
} Spherical;
|
||||||
} Params;
|
} Params;
|
||||||
|
|
||||||
lcMeshLoaderTextureMapType Type;
|
lcMeshLoaderMaterialType Type;
|
||||||
bool Fallback;
|
lcVector3 Points[3];
|
||||||
bool Next;
|
float Angles[2];
|
||||||
|
char Name[LC_MAXPATH];
|
||||||
|
|
||||||
|
bool Fallback = false;
|
||||||
|
bool Next = false;
|
||||||
};
|
};
|
||||||
|
|
||||||
class lcMeshLoaderTypeData
|
class lcMeshLoaderTypeData
|
||||||
|
@ -123,7 +137,12 @@ public:
|
||||||
mConditionalVertices.RemoveAll();
|
mConditionalVertices.RemoveAll();
|
||||||
}
|
}
|
||||||
|
|
||||||
lcMeshLoaderSection* AddSection(lcMeshPrimitiveType PrimitiveType, quint32 ColorCode, lcTexture* Texture);
|
void SetMeshData(lcLibraryMeshData* MeshData)
|
||||||
|
{
|
||||||
|
mMeshData = MeshData;
|
||||||
|
}
|
||||||
|
|
||||||
|
lcMeshLoaderSection* AddSection(lcMeshPrimitiveType PrimitiveType, lcMeshLoaderMaterial* Material);
|
||||||
|
|
||||||
quint32 AddVertex(const lcVector3& Position, bool Optimize);
|
quint32 AddVertex(const lcVector3& Position, bool Optimize);
|
||||||
quint32 AddVertex(const lcVector3& Position, const lcVector3& Normal, bool Optimize);
|
quint32 AddVertex(const lcVector3& Position, const lcVector3& Normal, bool Optimize);
|
||||||
|
@ -131,8 +150,8 @@ public:
|
||||||
quint32 AddTexturedVertex(const lcVector3& Position, const lcVector3& Normal, const lcVector2& TexCoord, bool Optimize);
|
quint32 AddTexturedVertex(const lcVector3& Position, const lcVector3& Normal, const lcVector2& TexCoord, bool Optimize);
|
||||||
quint32 AddConditionalVertex(const lcVector3 (&Position)[4]);
|
quint32 AddConditionalVertex(const lcVector3 (&Position)[4]);
|
||||||
|
|
||||||
void ProcessLine(int LineType, quint32 ColorCode, bool WindingCCW, lcVector3 (&Vertices)[4], bool Optimize);
|
void ProcessLine(int LineType, lcMeshLoaderMaterial* Material, bool WindingCCW, lcVector3 (&Vertices)[4], bool Optimize);
|
||||||
void ProcessTexturedLine(int LineType, quint32 ColorCode, bool WindingCCW, const lcMeshLoaderTextureMap& Map, const lcVector3* Vertices, bool Optimize);
|
void ProcessTexturedLine(int LineType, lcMeshLoaderMaterial* Material, bool WindingCCW, const lcMeshLoaderTextureMap& Map, const lcVector3* Vertices, bool Optimize);
|
||||||
|
|
||||||
void AddMeshData(const lcMeshLoaderTypeData& Data, const lcMatrix44& Transform, quint32 CurrentColorCode, bool InvertWinding, bool InvertNormals, lcMeshLoaderTextureMap* TextureMap);
|
void AddMeshData(const lcMeshLoaderTypeData& Data, const lcMatrix44& Transform, quint32 CurrentColorCode, bool InvertWinding, bool InvertNormals, lcMeshLoaderTextureMap* TextureMap);
|
||||||
void AddMeshDataNoDuplicateCheck(const lcMeshLoaderTypeData& Data, const lcMatrix44& Transform, quint32 CurrentColorCode, bool InvertWinding, bool InvertNormals, lcMeshLoaderTextureMap* TextureMap);
|
void AddMeshDataNoDuplicateCheck(const lcMeshLoaderTypeData& Data, const lcMatrix44& Transform, quint32 CurrentColorCode, bool InvertWinding, bool InvertNormals, lcMeshLoaderTextureMap* TextureMap);
|
||||||
|
@ -140,6 +159,9 @@ public:
|
||||||
std::vector<std::unique_ptr<lcMeshLoaderSection>> mSections;
|
std::vector<std::unique_ptr<lcMeshLoaderSection>> mSections;
|
||||||
lcArray<lcMeshLoaderVertex> mVertices;
|
lcArray<lcMeshLoaderVertex> mVertices;
|
||||||
lcArray<lcMeshLoaderConditionalVertex> mConditionalVertices;
|
lcArray<lcMeshLoaderConditionalVertex> mConditionalVertices;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
lcLibraryMeshData* mMeshData;
|
||||||
};
|
};
|
||||||
|
|
||||||
class lcLibraryMeshData
|
class lcLibraryMeshData
|
||||||
|
@ -149,6 +171,9 @@ public:
|
||||||
{
|
{
|
||||||
mHasTextures = false;
|
mHasTextures = false;
|
||||||
mHasStyleStud = false;
|
mHasStyleStud = false;
|
||||||
|
|
||||||
|
for (lcMeshLoaderTypeData& Data : mData)
|
||||||
|
Data.SetMeshData(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
lcLibraryMeshData(const lcLibraryMeshData&) = delete;
|
lcLibraryMeshData(const lcLibraryMeshData&) = delete;
|
||||||
|
@ -172,19 +197,30 @@ public:
|
||||||
mHasStyleStud = false;
|
mHasStyleStud = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void SetMeshLoader(lcMeshLoader* MeshLoader)
|
||||||
|
{
|
||||||
|
mMeshLoader = MeshLoader;
|
||||||
|
}
|
||||||
|
|
||||||
lcMesh* CreateMesh();
|
lcMesh* CreateMesh();
|
||||||
void AddVertices(lcMeshDataType MeshDataType, int VertexCount, int* BaseVertex, lcMeshLoaderVertex** VertexBuffer);
|
void AddVertices(lcMeshDataType MeshDataType, int VertexCount, int* BaseVertex, lcMeshLoaderVertex** VertexBuffer);
|
||||||
void AddIndices(lcMeshDataType MeshDataType, lcMeshPrimitiveType PrimitiveType, quint32 ColorCode, int IndexCount, quint32** IndexBuffer);
|
void AddIndices(lcMeshDataType MeshDataType, lcMeshPrimitiveType PrimitiveType, quint32 ColorCode, int IndexCount, quint32** IndexBuffer);
|
||||||
void AddMeshData(const lcLibraryMeshData& Data, const lcMatrix44& Transform, quint32 CurrentColorCode, bool InvertWinding, bool InvertNormals, lcMeshLoaderTextureMap* TextureMap, lcMeshDataType OverrideDestIndex);
|
void AddMeshData(const lcLibraryMeshData& Data, const lcMatrix44& Transform, quint32 CurrentColorCode, bool InvertWinding, bool InvertNormals, lcMeshLoaderTextureMap* TextureMap, lcMeshDataType OverrideDestIndex);
|
||||||
void AddMeshDataNoDuplicateCheck(const lcLibraryMeshData& Data, const lcMatrix44& Transform, quint32 CurrentColorCode, bool InvertWinding, bool InvertNormals, lcMeshLoaderTextureMap* TextureMap, lcMeshDataType OverrideDestIndex);
|
void AddMeshDataNoDuplicateCheck(const lcLibraryMeshData& Data, const lcMatrix44& Transform, quint32 CurrentColorCode, bool InvertWinding, bool InvertNormals, lcMeshLoaderTextureMap* TextureMap, lcMeshDataType OverrideDestIndex);
|
||||||
|
|
||||||
|
lcMeshLoaderMaterial* GetMaterial(quint32 ColorCode);
|
||||||
|
lcMeshLoaderMaterial* GetTexturedMaterial(quint32 ColorCode, const lcMeshLoaderTextureMap& TextureMap);
|
||||||
|
|
||||||
std::array<lcMeshLoaderTypeData, LC_NUM_MESHDATA_TYPES> mData;
|
std::array<lcMeshLoaderTypeData, LC_NUM_MESHDATA_TYPES> mData;
|
||||||
bool mHasTextures;
|
bool mHasTextures;
|
||||||
bool mHasStyleStud;
|
bool mHasStyleStud;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
lcMeshLoader* mMeshLoader = nullptr;
|
||||||
|
std::vector<std::unique_ptr<lcMeshLoaderMaterial>> mMaterials;
|
||||||
|
|
||||||
template<typename IndexType>
|
template<typename IndexType>
|
||||||
void WriteSections(lcMesh* Mesh, const lcArray<lcMergeSection> (&MergeSections)[LC_NUM_MESH_LODS], int (&BaseVertices)[LC_NUM_MESHDATA_TYPES], int (&BaseTexturedVertices)[LC_NUM_MESHDATA_TYPES], int (&BaseConditionalVertices)[LC_NUM_MESHDATA_TYPES]);
|
void WriteSections(lcMesh* Mesh, const lcArray<lcMeshLoaderFinalSection> (&FinalSections)[LC_NUM_MESH_LODS], int (&BaseVertices)[LC_NUM_MESHDATA_TYPES], int (&BaseTexturedVertices)[LC_NUM_MESHDATA_TYPES], int (&BaseConditionalVertices)[LC_NUM_MESHDATA_TYPES]);
|
||||||
|
|
||||||
static void UpdateMeshBoundingBox(lcMesh* Mesh);
|
static void UpdateMeshBoundingBox(lcMesh* Mesh);
|
||||||
template<typename IndexType>
|
template<typename IndexType>
|
||||||
|
@ -198,12 +234,14 @@ public:
|
||||||
|
|
||||||
bool LoadMesh(lcFile& File, lcMeshDataType MeshDataType);
|
bool LoadMesh(lcFile& File, lcMeshDataType MeshDataType);
|
||||||
|
|
||||||
|
Project* mCurrentProject;
|
||||||
|
bool mSearchProjectFolder;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
bool ReadMeshData(lcFile& File, const lcMatrix44& CurrentTransform, quint32 CurrentColorCode, bool InvertWinding, lcMeshDataType MeshDataType);
|
bool ReadMeshData(lcFile& File, const lcMatrix44& CurrentTransform, quint32 CurrentColorCode, bool InvertWinding, lcMeshDataType MeshDataType);
|
||||||
|
|
||||||
lcArray<lcMeshLoaderTextureMap> mTextureStack;
|
lcArray<lcMeshLoaderTextureMap> mTextureStack;
|
||||||
|
|
||||||
lcLibraryMeshData& mMeshData;
|
lcLibraryMeshData& mMeshData;
|
||||||
bool mOptimize;
|
bool mOptimize;
|
||||||
Project* mCurrentProject;
|
|
||||||
bool mSearchProjectFolder;
|
|
||||||
};
|
};
|
||||||
|
|
Loading…
Add table
Reference in a new issue