1 #pragma once
2 
3 #include <stdio.h>
4 #include "lc_math.h"
5 #include "lc_array.h"
6 
7 enum class lcPieceInfoType
8 {
9 	Part,
10 	Placeholder,
11 	Model,
12 	Project
13 };
14 
15 #define LC_PIECE_NAME_LEN 256
16 
17 enum lcPieceInfoState
18 {
19 	LC_PIECEINFO_UNLOADED,
20 	LC_PIECEINFO_LOADING,
21 	LC_PIECEINFO_LOADED
22 };
23 
24 struct lcModelPartsEntry
25 {
26 	lcMatrix44 WorldMatrix;
27 	const PieceInfo* Info;
28 	lcMesh* Mesh;
29 	int ColorIndex;
30 };
31 
32 class lcSynthInfo;
33 enum class lcZipFileType;
34 
35 class PieceInfo
36 {
37 public:
38 	PieceInfo();
39 	~PieceInfo();
40 
41 	PieceInfo(const PieceInfo&) = delete;
42 	PieceInfo(PieceInfo&&) = delete;
43 	PieceInfo& operator=(const PieceInfo&) = delete;
44 	PieceInfo& operator=(PieceInfo&&) = delete;
45 
GetBoundingBox()46 	const lcBoundingBox& GetBoundingBox() const
47 	{
48 		return mBoundingBox;
49 	}
50 
SetBoundingBox(const lcVector3 & Min,const lcVector3 & Max)51 	void SetBoundingBox(const lcVector3& Min, const lcVector3& Max)
52 	{
53 		mBoundingBox.Min = Min;
54 		mBoundingBox.Max = Max;
55 	}
56 
GetSynthInfo()57 	lcSynthInfo* GetSynthInfo() const
58 	{
59 		return mSynthInfo;
60 	}
61 
SetSynthInfo(lcSynthInfo * SynthInfo)62 	void SetSynthInfo(lcSynthInfo* SynthInfo)
63 	{
64 		mSynthInfo = SynthInfo;
65 	}
66 
GetMesh()67 	lcMesh* GetMesh() const
68 	{
69 		return mMesh;
70 	}
71 
GetModel()72 	lcModel* GetModel() const
73 	{
74 		return mModel;
75 	}
76 
GetProject()77 	Project* GetProject() const
78 	{
79 		return mProject;
80 	}
81 
82 	void SetMesh(lcMesh* Mesh);
83 
AddRef()84 	int AddRef()
85 	{
86 		mRefCount++;
87 		return mRefCount;
88 	}
89 
Release()90 	int Release()
91 	{
92 		mRefCount--;
93 		return mRefCount;
94 	}
95 
GetRefCount()96 	int GetRefCount() const
97 	{
98 		return mRefCount;
99 	}
100 
IsPlaceholder()101 	bool IsPlaceholder() const
102 	{
103 		return mType == lcPieceInfoType::Placeholder;
104 	}
105 
IsModel()106 	bool IsModel() const
107 	{
108 		return mType == lcPieceInfoType::Model;
109 	}
110 
IsProject()111 	bool IsProject() const
112 	{
113 		return mType == lcPieceInfoType::Project;
114 	}
115 
IsTemporary()116 	bool IsTemporary() const
117 	{
118 		return mType != lcPieceInfoType::Part;
119 	}
120 
SetZipFile(lcZipFileType ZipFileType,int ZipFileIndex)121 	void SetZipFile(lcZipFileType ZipFileType, int ZipFileIndex)
122 	{
123 		mZipFileType = ZipFileType;
124 		mZipFileIndex = ZipFileIndex;
125 	}
126 
IsPatterned()127 	bool IsPatterned() const
128 	{
129 		if (mType != lcPieceInfoType::Part)
130 			return false;
131 
132 		const char* Name = mFileName;
133 
134 		// Heuristic: Names matching '^[Uu]?[0-9]*[A-Za-z][^.][^.]' are patterned.
135 
136 		if (*Name == 'U' || *Name == 'u')
137 			Name++;
138 
139 		while (*Name)
140 		{
141 			if (*Name < '0' || *Name > '9')
142 				break;
143 
144 			Name++;
145 		}
146 
147 		if (!*Name || !((*Name >= 'A' && *Name <= 'Z') || (*Name >= 'a' && *Name <= 'z')))
148 			return false;
149 
150 		if (Name[1] && Name[1] != '.' && Name[2] && Name[2] != '.')
151 			return true;
152 
153 		return false;
154 	}
155 
IsSubPiece()156 	bool IsSubPiece() const
157 	{
158 		return (m_strDescription[0] == '~');
159 	}
160 
161 	void ZoomExtents(float FoV, float AspectRatio, lcMatrix44& ProjectionMatrix, lcMatrix44& ViewMatrix) const;
162 	void AddRenderMesh(lcScene& Scene);
163 	void AddRenderMeshes(lcScene* Scene, const lcMatrix44& WorldMatrix, int ColorIndex, lcRenderMeshState RenderMeshState, bool ParentActive) const;
164 
165 	void CreatePlaceholder(const char* Name);
166 
167 	void SetPlaceholder();
168 	void SetModel(lcModel* Model, bool UpdateMesh, Project* CurrentProject, bool SearchProjectFolder);
169 	void CreateProject(Project* Project, const char* PieceName);
170 	bool GetPieceWorldMatrix(lcPiece* Piece, lcMatrix44& WorldMatrix) const;
171 	bool IncludesModel(const lcModel* Model) const;
172 	bool MinIntersectDist(const lcVector3& Start, const lcVector3& End, float& MinDistance) const;
173 	bool BoxTest(const lcMatrix44& WorldMatrix, const lcVector4 Planes[6]) const;
174 	void GetPartsList(int DefaultColorIndex, bool ScanSubModels, bool AddSubModels, lcPartsList& PartsList) const;
175 	void GetModelParts(const lcMatrix44& WorldMatrix, int DefaultColorIndex, std::vector<lcModelPartsEntry>& ModelParts) const;
176 	void CompareBoundingBox(const lcMatrix44& WorldMatrix, lcVector3& Min, lcVector3& Max) const;
177 	void AddSubModelBoundingBoxPoints(const lcMatrix44& WorldMatrix, std::vector<lcVector3>& Points) const;
178 	void UpdateBoundingBox(std::vector<lcModel*>& UpdatedModels);
179 
180 	void Load();
181 	void Unload();
182 
183 public:
184 	char mFileName[LC_PIECE_NAME_LEN];
185 	char m_strDescription[128];
186 	lcZipFileType mZipFileType;
187 	int mZipFileIndex;
188 	lcPieceInfoState mState;
189 	int mFolderType;
190 	int mFolderIndex;
191 
192 protected:
193 	void ReleaseMesh();
194 
195 	int mRefCount;
196 	lcPieceInfoType mType;
197 	lcModel* mModel;
198 	Project* mProject;
199 	lcMesh* mMesh;
200 	lcBoundingBox mBoundingBox;
201 	lcSynthInfo* mSynthInfo;
202 };
203 
204