File: lc_meshloader.h

package info (click to toggle)
leocad 25.09-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 9,008 kB
  • sloc: cpp: 51,794; xml: 11,265; python: 81; sh: 52; makefile: 16
file content (227 lines) | stat: -rw-r--r-- 6,238 bytes parent folder | download
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;
};