Lightscape.h 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524
  1. /*
  2. ** Command & Conquer Renegade(tm)
  3. ** Copyright 2025 Electronic Arts Inc.
  4. **
  5. ** This program is free software: you can redistribute it and/or modify
  6. ** it under the terms of the GNU General Public License as published by
  7. ** the Free Software Foundation, either version 3 of the License, or
  8. ** (at your option) any later version.
  9. **
  10. ** This program is distributed in the hope that it will be useful,
  11. ** but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  13. ** GNU General Public License for more details.
  14. **
  15. ** You should have received a copy of the GNU General Public License
  16. ** along with this program. If not, see <http://www.gnu.org/licenses/>.
  17. */
  18. /***********************************************************************************************
  19. *** Confidential - Westwood Studios ***
  20. ***********************************************************************************************
  21. * *
  22. * Project Name : LightMap *
  23. * *
  24. * $Archive:: /Commando/Code/Tool $*
  25. * *
  26. * $Author:: Ian_l $*
  27. * *
  28. * $Modtime:: 7/03/01 3:07p $*
  29. * *
  30. * $Revision:: 38 $*
  31. * *
  32. *---------------------------------------------------------------------------------------------*
  33. * Functions: *
  34. * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
  35. #ifndef _LIGHTSCAPE_H
  36. #define _LIGHTSCAPE_H
  37. // Includes.
  38. #include "Chunk.h"
  39. #include "LightMapPacker.h"
  40. #include "Triangle.h"
  41. #include "arraylistof.h"
  42. #include "light.h"
  43. #include "lsbasebuilders.h"
  44. #include "ltttypes.h"
  45. #include "rmap.h"
  46. #include "vector.h"
  47. #include "vector2.h"
  48. #include "vector3.h"
  49. #include "vector3i.h"
  50. #include "wwmath.h"
  51. #include "w3d_file.h"
  52. class TextureNameNode;
  53. class SolveStatistics {
  54. public:
  55. enum SolveStatisticEnum {
  56. VERTEX_NOT_FOUND,
  57. VERTEX_NO_COLOR,
  58. FACE_NOT_FOUND,
  59. FACE_NO_LIGHTMAP,
  60. VERTEX_NOT_SMOOTH,
  61. FACE_AMBIGUOUS,
  62. FACE_DEGENERATE,
  63. FACE_UNDERSIZED,
  64. EDGE_MATCH,
  65. ALL_FILL_COLOR,
  66. NULL_TEXTURE,
  67. SOLVE_STATISTIC_COUNT
  68. };
  69. SolveStatistics ()
  70. {
  71. VertexCount = 0;
  72. FaceCount = 0;
  73. for (unsigned s = 0; s < SOLVE_STATISTIC_COUNT; s++) Count [s] = 0;
  74. }
  75. SolveStatistics (unsigned vertexcount, unsigned facecount)
  76. {
  77. VertexCount = vertexcount;
  78. FaceCount = facecount;
  79. for (unsigned s = 0; s < SOLVE_STATISTIC_COUNT; s++) Count [s] = 0;
  80. }
  81. bool Valid_Vertex_Solve() const {
  82. return (((Count [VERTEX_NOT_FOUND] == 0) || (Count [VERTEX_NOT_FOUND] < VertexCount)) && (Count [VERTEX_NO_COLOR] == 0));
  83. }
  84. bool Valid_Lightmap_Solve() const {
  85. return (((Count [FACE_NOT_FOUND] == 0) || (Count [FACE_NOT_FOUND] < FaceCount)) && (Count [FACE_NO_LIGHTMAP] == 0));
  86. }
  87. bool operator == (unsigned c) {
  88. unsigned sum;
  89. sum = 0;
  90. for (unsigned s = 0; s < SOLVE_STATISTIC_COUNT; s++) sum += Count [s];
  91. return (sum == c);
  92. }
  93. unsigned VertexCount;
  94. unsigned FaceCount;
  95. unsigned Count [SOLVE_STATISTIC_COUNT];
  96. };
  97. // Class wrapper for floating point color vectors.
  98. class ColorVector : public Vector3
  99. {
  100. public:
  101. ColorVector () : Vector3() {}
  102. ColorVector (float r, float g, float b) : Vector3 (r, g, b) {}
  103. void Set (float r, float g, float b)
  104. {
  105. Vector3::Set (r, g, b);
  106. }
  107. void Set (const LtTRGBColor &irradiance, const RadianceMap &radiancemap)
  108. {
  109. const double oopi = 1.0 / M_PI;
  110. X = irradiance.GetR() * oopi;
  111. Y = irradiance.GetG() * oopi;
  112. Z = irradiance.GetB() * oopi;
  113. radiancemap.ToColor (X, Y, Z);
  114. }
  115. };
  116. class LightscapeSolve : public LightmapPacker
  117. {
  118. public:
  119. // Member functions.
  120. LightscapeSolve (const char *solvedirectoryname, const char *solvefilenamelist, CStatusBar* statusptr, const char *statusbarmessage, bool blendnoise = false);
  121. Finish();
  122. ~LightscapeSolve ();
  123. // Database ammendment functions.
  124. void Set_Is_Solution (bool issolution) {IsSolution = issolution;}
  125. void Set_Brightness (float brightness) {Brightness = brightness;}
  126. void Set_Contrast (float contrast) {Contrast = contrast;}
  127. void Set_Is_Daylight (bool isdaylight) {IsDaylight = isdaylight;}
  128. void Set_Is_Exterior (bool isexterior) {IsExterior = isexterior;}
  129. void Set_Patch_Cluster_Count (int count) {PatchClusterCount = count;}
  130. void Set_Is_M2T_Solve (bool ism2tsolve) {IsM2TSolve = ism2tsolve;}
  131. void Add_Material_Texture_Name (const char *materialname, const char *texturename);
  132. void Add_Texture_Name (unsigned patchindex, const char *materialname);
  133. void Add_Light (LightClass *light);
  134. bool Add_Vertex (unsigned vertexindex, const Vector3 &p, const Vector3 &n, unsigned patchindex, const Vector2 &t);
  135. bool Add_Vertex (unsigned vertexindex, const Vector3 &p, const Vector3 &n, unsigned patchindex, const ColorVector &c);
  136. bool Add_Patch_Face (unsigned patchfaceindex, unsigned patchindex, unsigned vertexindexcount, unsigned *vertexindices);
  137. // Database query functions.
  138. float Get_Brightness() {return (Brightness);}
  139. float Get_Contrast() {return (Contrast);}
  140. bool Is_Daylight() {return (IsDaylight);}
  141. bool Is_Exterior() {return (IsExterior);}
  142. bool Is_M2T_Solve() {return (IsM2TSolve);}
  143. float Filter_Sharpness() {return (FilterSharpness);}
  144. ProceduralTexture *Procedural_Texture() {return (ProceduralTexture);}
  145. unsigned Light_Count() {return (Lights.Count());}
  146. LightClass *Get_Light (unsigned l) {return (Lights [l]);}
  147. const char *Light_Exclusion_String() {return (LightExclusionString);}
  148. void Find_Vertex (const Vector3 &point, const Vector3 *smoothingnormalptr, W3dRGBStruct &vertexcolor, SolveStatistics &solvestatistics);
  149. void Find_Triangle (const Vector3 *points, const Vector3 &normal, PackingTriangle &triangle, SolveStatistics &solvestatistics);
  150. void Submit_Triangle (PackingTriangle &triangle);
  151. const TextureNameNode *Texture_Name (unsigned patchindex);
  152. void Pack();
  153. // Update the progress bar.
  154. void Step_It() {ProgressBar->StepIt();}
  155. // Static functions.
  156. static LightscapeSolve *Importer() {return (_ActiveImporter);}
  157. static const char *Asset_Directory() {return (LightmapPacker::Asset_Directory());}
  158. static const char *Asset_Directory (const char *filename) {return (LightmapPacker::Asset_Directory (filename));}
  159. static void Copy_Assets (const char *pathname) {LightmapPacker::Copy_Assets (pathname);}
  160. private:
  161. // Result of finding a face.
  162. enum FaceResultEnum {
  163. FACE_NOT_FOUND,
  164. FACE_AMBIGUOUS,
  165. FACE_FOUND
  166. };
  167. // Area of the face.
  168. enum FaceSizeEnum {
  169. FACE_DEGENERATE,
  170. FACE_UNDERSIZED,
  171. FACE_NOT_UNDERSIZED
  172. };
  173. struct VerticesStruct {
  174. // Equality operator.
  175. bool operator == (const VerticesStruct &v) {
  176. return ((Point == v.Point) &&
  177. (FaceNormal == v.FaceNormal) &&
  178. (PatchIndex == v.PatchIndex) &&
  179. (ValidColor == v.ValidColor) &&
  180. (Color == v.Color) &&
  181. (ValidUV == v.ValidUV) &&
  182. (UV == v.UV));
  183. }
  184. // Inequality operator.
  185. bool operator != (const VerticesStruct &v) {
  186. return (!(*this == v));
  187. }
  188. Vector3 Point;
  189. Vector3 FaceNormal;
  190. unsigned PatchIndex;
  191. bool ValidColor;
  192. ColorVector Color;
  193. bool ValidUV;
  194. Vector2 UV;
  195. };
  196. struct PatchFaceStruct {
  197. enum VerticesPerPatchFace {
  198. VERTICES_PER_PATCH_FACE = 4
  199. };
  200. // To indicate whether a patch face vertex index is valid.
  201. enum VertexIndexValidity {
  202. VERTEX_INDEX_INVALID = -1
  203. };
  204. // Equality operator.
  205. bool operator == (const PatchFaceStruct &p) {
  206. return ((PatchIndex == p.PatchIndex) &&
  207. (VertexIndices [0] == p.VertexIndices [0]) &&
  208. (VertexIndices [1] == p.VertexIndices [1]) &&
  209. (VertexIndices [2] == p.VertexIndices [2]) &&
  210. (VertexIndices [3] == p.VertexIndices [3]));
  211. }
  212. // Inequality operator.
  213. bool operator != (const PatchFaceStruct &p) {
  214. return (!(*this == p));
  215. }
  216. unsigned PatchIndex;
  217. unsigned VertexIndices [VERTICES_PER_PATCH_FACE];
  218. };
  219. // Member functions.
  220. void Find_Adjacent_Triangles (const PackingTriangle &principaltriangle, DynamicVectorClass <Triangle> &adjtriangles);
  221. void Find_Triangle (const Vector3 *points, const Vector3 &facenormal, VerticesStruct *vertices, FaceResultEnum &faceresult);
  222. void Find_Triangle (const Vector3 *points, float tolerance, bool centroidtest, const Vector3 *facenormal, VerticesStruct *vertices, FaceResultEnum &faceresult);
  223. void Find_Vertices (const Vector3 &point, float tolerance, DynamicVectorClass <VerticesStruct*> &vertices);
  224. // Miscellaneous convenience functions.
  225. FaceSizeEnum Face_Size (const Vector3 *points, unsigned count);
  226. unsigned Longest_Edge (const Vector3 *points, unsigned count, bool *usededges);
  227. float Manhatten_Distance (const Vector3 &v)
  228. {
  229. return (WWMath::Fabs (v.X) + WWMath::Fabs (v.Y) + WWMath::Fabs (v.Z));
  230. }
  231. // Comparison functions.
  232. static int Compare_Material_Texture_Names (const void *materialname0, const void *materialname1);
  233. static int Compare_Vertices (const void *vertexindexptr0, const void *vertexindexptr1);
  234. static int Compare_Patch_Faces (const void *patchface0, const void *patchface1);
  235. // Member data.
  236. float SmoothingAngle;
  237. float SpatialTolerance;
  238. float FilterSharpness;
  239. bool IsSolution; // Is the currently imported file a valid solve file?
  240. int PatchClusterCount; // Total patch cluster count over all parsed solve files.
  241. float Brightness;
  242. float Contrast;
  243. bool IsDaylight;
  244. bool IsExterior;
  245. bool IsM2TSolve;
  246. ProceduralTexture *ProceduralTexture;
  247. CProgressCtrl *ProgressBar;
  248. DynamicVectorClass <char *> MaterialTextureNames; // <material name, texture pathname> pairs for all materials in the solve.
  249. DynamicVectorClass <TextureNameNode*> TextureNames; // <texture pathname> for all patches in the solve.
  250. DynamicVectorClass <VerticesStruct> Vertices; // <point, uv coordinate, normal, material index> tuples for all vertices in the solve.
  251. DynamicVectorClass <unsigned> VertexIndices; // Indices into Vertices.
  252. DynamicVectorClass <PatchFaceStruct> PatchFaces; // <patch index, face> pairs for all faces in the solve.
  253. DynamicVectorClass <LightClass*> Lights; // All active lights in the solve.
  254. const char *LightExclusionString; // Do not add lights that contain this string.
  255. // Static data.
  256. static LightscapeSolve *_ActiveImporter; // Object currently importing (reading a solution file) (otherwise NULL).
  257. };
  258. class LsInformationFactory : public LtTBuilderFactory
  259. {
  260. protected:
  261. virtual LtTInfoBuilderApi *OnGetInfoBuilder();
  262. virtual LtTParameterBuilderApi *OnGetParameterBuilder();
  263. };
  264. class LsPreparationFactory : public LtTBuilderFactory
  265. {
  266. protected:
  267. virtual LtTInfoBuilderApi *OnGetInfoBuilder();
  268. virtual LtTParameterBuilderApi *OnGetParameterBuilder();
  269. virtual LtTMaterialBuilderApi *OnGetMaterialBuilder();
  270. virtual LtTLampBuilderApi *OnGetLampBuilder();
  271. virtual LtTMeshBuilderApi *OnGetMeshBuilder();
  272. };
  273. class LsMainFactory : public LtTBuilderFactory
  274. {
  275. public:
  276. LsMainFactory();
  277. unsigned Patch_Face_Count() {return (PatchFaceIndex);}
  278. void Patch_Face_Increment() {PatchFaceIndex++;}
  279. unsigned Vertex_Count() {return (VertexIndex);}
  280. void Vertex_Increment() {VertexIndex++;}
  281. unsigned Patch_Count() {return (PatchIndex);}
  282. void Patch_Increment() {PatchIndex++; LightscapeSolve::Importer()->Step_It();}
  283. protected:
  284. virtual LtTInfoBuilderApi *OnGetInfoBuilder();
  285. virtual LtTParameterBuilderApi *OnGetParameterBuilder();
  286. virtual LtTMeshBuilderApi *OnGetMeshBuilder();
  287. private:
  288. unsigned PatchFaceIndex;
  289. unsigned VertexIndex;
  290. unsigned PatchIndex;
  291. };
  292. class LsInfoBuilder : public LtTBaseInfoBuilder
  293. {
  294. protected:
  295. LsInfoBuilder (LtTBuilderFactory *factory);
  296. LtTBool Finish();
  297. friend class LsInformationFactory;
  298. friend class LsPreparationFactory;
  299. friend class LsMainFactory;
  300. };
  301. class LsParameterBuilder : public LtTBaseParameterBuilder
  302. {
  303. protected:
  304. LsParameterBuilder (LtTBuilderFactory *factory);
  305. LtTBool Finish();
  306. friend class LsInformationFactory;
  307. friend class LsPreparationFactory;
  308. friend class LsMainFactory;
  309. };
  310. class LsMaterialBuilder : public LtTBaseMaterialBuilder
  311. {
  312. protected:
  313. LsMaterialBuilder (LtTBuilderFactory *factory);
  314. LtTBool Finish();
  315. friend class LsPreparationFactory;
  316. };
  317. class LsLampBuilder : public LtTBaseLampBuilder
  318. {
  319. protected:
  320. LsLampBuilder (LtTBuilderFactory *factory);
  321. LtTBool Finish();
  322. friend class LsPreparationFactory;
  323. };
  324. class LsMeshInquirer : public LtTBaseMeshBuilder
  325. {
  326. protected:
  327. LsMeshInquirer (LtTBuilderFactory *factory);
  328. LtTBool Finish();
  329. friend class LsPreparationFactory;
  330. };
  331. class LsMeshBuilder : public LtTBaseMeshBuilder
  332. {
  333. protected:
  334. LsMeshBuilder (LtTBuilderFactory *factory);
  335. ~LsMeshBuilder();
  336. LtTBool Finish();
  337. void SetFaces (const int facecount, const LtTFace *v);
  338. int GetFaceCount() const;
  339. const LtTFace *GetFaces() const;
  340. LsMainFactory *FactoryPtr;
  341. private:
  342. struct FaceVertexStruct {
  343. // Equality operator.
  344. bool operator == (const FaceVertexStruct &fv) {
  345. return ((Point == fv.Point) && (Color == fv.Color) && (Weight == fv.Weight));
  346. }
  347. // Inequality operator.
  348. bool operator != (const FaceVertexStruct &fv) {
  349. return (!(*this == fv));
  350. }
  351. Vector3 Point;
  352. ColorVector Color;
  353. float Weight;
  354. };
  355. LtTFace *Faces;
  356. int FaceCount;
  357. int AllocatedCount;
  358. friend class LsMainFactory;
  359. friend class VertexUser;
  360. };
  361. class VertexUser
  362. {
  363. public:
  364. VertexUser (const LsMeshBuilder &meshbuilder);
  365. ~VertexUser () {delete [] UsedVertexIndices;}
  366. bool Is_Used (unsigned vertexindex)
  367. {
  368. ASSERT (vertexindex < Count);
  369. return (UsedVertexIndices [vertexindex] != UNUSED);
  370. }
  371. void Set_Index (unsigned vertexindex, unsigned usedvertexindex)
  372. {
  373. ASSERT (Is_Used (vertexindex));
  374. UsedVertexIndices [vertexindex] = usedvertexindex;
  375. }
  376. unsigned Get_Index (unsigned vertexindex)
  377. {
  378. ASSERT (vertexindex < Count);
  379. // This vertex must have previously been set.
  380. ASSERT (UsedVertexIndices [vertexindex] >= 0);
  381. return (UsedVertexIndices [vertexindex]);
  382. }
  383. private:
  384. enum VertexUsage {
  385. UNUSED = -2,
  386. USED = -1
  387. };
  388. VertexUser() {}
  389. unsigned Count;
  390. int *UsedVertexIndices;
  391. };
  392. class LightscapeMeshSolve
  393. {
  394. public:
  395. LightscapeMeshSolve (LightscapeSolve &solve, ChunkClass &trianglechunk, ChunkClass &vertexchunk);
  396. ~LightscapeMeshSolve();
  397. W3dRGBStruct Vertex_Color (unsigned vertexindex) const;
  398. unsigned Vertex_Color_Count() const {return (VertexCount);}
  399. const char *Lightmap_Pathname (unsigned lightmapindex) const;
  400. unsigned Lightmap_Index (unsigned faceindex) const;
  401. W3dTexCoordStruct Lightmap_UV (unsigned facevertexindex) const;
  402. unsigned Lightmap_Count() const {return (LightmapCount);}
  403. const SolveStatistics *Get_Statistics() const {return (&Statistics);}
  404. private:
  405. unsigned VertexCount; // No. of vertices in mesh.
  406. unsigned FaceCount; // No. of faces in mesh.
  407. unsigned FaceVertexCount; // No. of face-vertices in mesh.
  408. unsigned LightmapCount; // No. of lightmaps used by mesh.
  409. W3dRGBStruct *VertexColors; // Array of vertex colors.
  410. Vector2 *FaceVertexUVs; // Array to map a face-vertex index to a UV coordinate.
  411. unsigned *FaceRemapLightmapIndices; // Array to map a face to a zero-based lightmap index.
  412. unsigned *LightmapIndices; // Array to map a zero-based lightmap index to a 'real' lightmap index.
  413. SolveStatistics Statistics; // Statistics counters.
  414. };
  415. #endif // LIGHTSCAPE_H