1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227
|
#pragma once
#include "lc_math.h"
#include "lc_mesh.h"
class lcLibraryMeshData;
class lcMeshLoader;
enum lcMeshDataType
{
LC_MESHDATA_HIGH,
LC_MESHDATA_LOW,
LC_MESHDATA_SHARED,
LC_NUM_MESHDATA_TYPES
};
struct lcMeshLoaderVertex
{
lcVector3 Position;
lcVector3 Normal;
float NormalWeight;
};
struct lcMeshLoaderTexturedVertex
{
lcVector3 Position;
lcVector3 Normal;
lcVector2 TexCoords;
};
struct lcMeshLoaderConditionalVertex
{
lcVector3 Position[4];
};
enum class lcMeshLoaderMaterialType
{
Solid,
Planar,
Cylindrical,
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.reserve(1024);
}
lcMeshLoaderMaterial* mMaterial;
lcMeshPrimitiveType mPrimitiveType;
std::vector<quint32> mIndices;
};
struct lcMeshLoaderFinalSection
{
quint32 Color;
lcMeshPrimitiveType PrimitiveType;
char Name[256];
};
struct lcMeshLoaderTextureMap
{
union lcTextureMapParams
{
lcTextureMapParams()
{
}
struct lcTextureMapSphericalParams
{
} Spherical;
} Params;
lcMeshLoaderMaterialType Type;
lcVector3 Points[3];
float Angles[2];
char Name[LC_MAXPATH];
bool Fallback = false;
bool Next = false;
};
class lcMeshLoaderTypeData
{
public:
lcMeshLoaderTypeData() = default;
lcMeshLoaderTypeData(const lcMeshLoaderTypeData&) = delete;
lcMeshLoaderTypeData& operator=(const lcMeshLoaderTypeData&) = delete;
bool IsEmpty() const
{
return mSections.empty();
}
void Clear()
{
mSections.clear();
mVertices.clear();
mConditionalVertices.clear();
}
void SetMeshData(lcLibraryMeshData* MeshData)
{
mMeshData = MeshData;
}
lcMeshLoaderSection* AddSection(lcMeshPrimitiveType PrimitiveType, lcMeshLoaderMaterial* Material);
quint32 AddVertex(const lcVector3& Position, bool Optimize);
quint32 AddVertex(const lcVector3& Position, const lcVector3& Normal, float NormalWeight, bool Optimize);
quint32 AddConditionalVertex(const lcVector3 (&Position)[4]);
void ProcessLine(int LineType, lcMeshLoaderMaterial* Material, bool WindingCCW, lcVector3 (&Vertices)[4], bool Optimize);
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);
std::vector<std::unique_ptr<lcMeshLoaderSection>> mSections;
std::vector<lcMeshLoaderVertex> mVertices;
std::vector<lcMeshLoaderConditionalVertex> mConditionalVertices;
protected:
lcLibraryMeshData* mMeshData = nullptr;
};
class lcLibraryMeshData
{
public:
lcLibraryMeshData()
{
mHasTextures = false;
mHasStyleStud = false;
for (lcMeshLoaderTypeData& Data : mData)
Data.SetMeshData(this);
}
lcLibraryMeshData(const lcLibraryMeshData&) = delete;
lcLibraryMeshData& operator=(const lcLibraryMeshData&) = delete;
bool IsEmpty() const
{
for (const lcMeshLoaderTypeData& Data : mData)
if (!Data.IsEmpty())
return false;
return true;
}
void Clear()
{
for (lcMeshLoaderTypeData& Data : mData)
Data.Clear();
mHasTextures = false;
mHasStyleStud = false;
}
void SetMeshLoader(lcMeshLoader* MeshLoader)
{
mMeshLoader = MeshLoader;
}
lcMesh* CreateMesh();
void AddVertices(lcMeshDataType MeshDataType, size_t VertexCount, int* BaseVertex, lcMeshLoaderVertex** VertexBuffer);
void AddIndices(lcMeshDataType MeshDataType, lcMeshPrimitiveType PrimitiveType, quint32 ColorCode, size_t IndexCount, quint32** IndexBuffer);
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);
lcMeshLoaderMaterial* GetMaterial(quint32 ColorCode);
lcMeshLoaderMaterial* GetTexturedMaterial(quint32 ColorCode, const lcMeshLoaderTextureMap& TextureMap);
std::array<lcMeshLoaderTypeData, LC_NUM_MESHDATA_TYPES> mData;
bool mHasTextures;
bool mHasStyleStud;
protected:
lcMeshLoader* mMeshLoader = nullptr;
std::vector<std::unique_ptr<lcMeshLoaderMaterial>> mMaterials;
std::vector<lcMeshLoaderTexturedVertex> mTexturedVertices;
void GenerateTexturedVertices();
void GeneratePlanarTexcoords(lcMeshLoaderSection* Section, const lcMeshLoaderTypeData& Data);
void GenerateCylindricalTexcoords(lcMeshLoaderSection* Section, const lcMeshLoaderTypeData& Data);
void GenerateSphericalTexcoords(lcMeshLoaderSection* Section, const lcMeshLoaderTypeData& Data);
quint32 AddTexturedVertex(const lcVector3& Position, const lcVector3& Normal, const lcVector2& TexCoords);
template<typename IndexType>
void WriteSections(lcMesh* Mesh, const std::vector<lcMeshLoaderFinalSection> (&FinalSections)[LC_NUM_MESH_LODS], int (&BaseVertices)[LC_NUM_MESHDATA_TYPES], int (&BaseConditionalVertices)[LC_NUM_MESHDATA_TYPES]);
static void UpdateMeshBoundingBox(lcMesh* Mesh);
template<typename IndexType>
static void UpdateMeshSectionBoundingBox(const lcMesh* Mesh, const lcMeshSection& Section, lcVector3& SectionMin, lcVector3& SectionMax);
};
class lcMeshLoader
{
public:
lcMeshLoader(lcLibraryMeshData& MeshData, bool Optimize, Project* CurrentProject, bool SearchProjectFolder);
bool LoadMesh(lcFile& File, lcMeshDataType MeshDataType);
Project* mCurrentProject;
bool mSearchProjectFolder;
protected:
bool ReadMeshData(lcFile& File, const lcMatrix44& CurrentTransform, quint32 CurrentColorCode, bool InvertWinding, lcMeshDataType MeshDataType);
std::vector<lcMeshLoaderTextureMap> mTextureStack;
lcLibraryMeshData& mMeshData;
bool mOptimize;
};
|