This repository has been archived on 2025-02-27. You can view files and clone it, but cannot push or open issues or pull requests.
CnC_Renegade/Code/Tools/LightMap/Lightscape.h

524 lines
16 KiB
C
Raw Permalink Normal View History

/*
** Command & Conquer Renegade(tm)
** Copyright 2025 Electronic Arts Inc.
**
** This program is free software: you can redistribute it and/or modify
** it under the terms of the GNU General Public License as published by
** the Free Software Foundation, either version 3 of the License, or
** (at your option) any later version.
**
** This program is distributed in the hope that it will be useful,
** but WITHOUT ANY WARRANTY; without even the implied warranty of
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
** GNU General Public License for more details.
**
** You should have received a copy of the GNU General Public License
** along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
/***********************************************************************************************
*** Confidential - Westwood Studios ***
***********************************************************************************************
* *
* Project Name : LightMap *
* *
* $Archive:: /Commando/Code/Tool $*
* *
* $Author:: Ian_l $*
* *
* $Modtime:: 7/03/01 3:07p $*
* *
* $Revision:: 38 $*
* *
*---------------------------------------------------------------------------------------------*
* Functions: *
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
#ifndef _LIGHTSCAPE_H
#define _LIGHTSCAPE_H
// Includes.
#include "Chunk.h"
#include "LightMapPacker.h"
#include "Triangle.h"
#include "arraylistof.h"
#include "light.h"
#include "lsbasebuilders.h"
#include "ltttypes.h"
#include "rmap.h"
#include "vector.h"
#include "vector2.h"
#include "vector3.h"
#include "vector3i.h"
#include "wwmath.h"
#include "w3d_file.h"
class TextureNameNode;
class SolveStatistics {
public:
enum SolveStatisticEnum {
VERTEX_NOT_FOUND,
VERTEX_NO_COLOR,
FACE_NOT_FOUND,
FACE_NO_LIGHTMAP,
VERTEX_NOT_SMOOTH,
FACE_AMBIGUOUS,
FACE_DEGENERATE,
FACE_UNDERSIZED,
EDGE_MATCH,
ALL_FILL_COLOR,
NULL_TEXTURE,
SOLVE_STATISTIC_COUNT
};
SolveStatistics ()
{
VertexCount = 0;
FaceCount = 0;
for (unsigned s = 0; s < SOLVE_STATISTIC_COUNT; s++) Count [s] = 0;
}
SolveStatistics (unsigned vertexcount, unsigned facecount)
{
VertexCount = vertexcount;
FaceCount = facecount;
for (unsigned s = 0; s < SOLVE_STATISTIC_COUNT; s++) Count [s] = 0;
}
bool Valid_Vertex_Solve() const {
return (((Count [VERTEX_NOT_FOUND] == 0) || (Count [VERTEX_NOT_FOUND] < VertexCount)) && (Count [VERTEX_NO_COLOR] == 0));
}
bool Valid_Lightmap_Solve() const {
return (((Count [FACE_NOT_FOUND] == 0) || (Count [FACE_NOT_FOUND] < FaceCount)) && (Count [FACE_NO_LIGHTMAP] == 0));
}
bool operator == (unsigned c) {
unsigned sum;
sum = 0;
for (unsigned s = 0; s < SOLVE_STATISTIC_COUNT; s++) sum += Count [s];
return (sum == c);
}
unsigned VertexCount;
unsigned FaceCount;
unsigned Count [SOLVE_STATISTIC_COUNT];
};
// Class wrapper for floating point color vectors.
class ColorVector : public Vector3
{
public:
ColorVector () : Vector3() {}
ColorVector (float r, float g, float b) : Vector3 (r, g, b) {}
void Set (float r, float g, float b)
{
Vector3::Set (r, g, b);
}
void Set (const LtTRGBColor &irradiance, const RadianceMap &radiancemap)
{
const double oopi = 1.0 / M_PI;
X = irradiance.GetR() * oopi;
Y = irradiance.GetG() * oopi;
Z = irradiance.GetB() * oopi;
radiancemap.ToColor (X, Y, Z);
}
};
class LightscapeSolve : public LightmapPacker
{
public:
// Member functions.
LightscapeSolve (const char *solvedirectoryname, const char *solvefilenamelist, CStatusBar* statusptr, const char *statusbarmessage, bool blendnoise = false);
Finish();
~LightscapeSolve ();
// Database ammendment functions.
void Set_Is_Solution (bool issolution) {IsSolution = issolution;}
void Set_Brightness (float brightness) {Brightness = brightness;}
void Set_Contrast (float contrast) {Contrast = contrast;}
void Set_Is_Daylight (bool isdaylight) {IsDaylight = isdaylight;}
void Set_Is_Exterior (bool isexterior) {IsExterior = isexterior;}
void Set_Patch_Cluster_Count (int count) {PatchClusterCount = count;}
void Set_Is_M2T_Solve (bool ism2tsolve) {IsM2TSolve = ism2tsolve;}
void Add_Material_Texture_Name (const char *materialname, const char *texturename);
void Add_Texture_Name (unsigned patchindex, const char *materialname);
void Add_Light (LightClass *light);
bool Add_Vertex (unsigned vertexindex, const Vector3 &p, const Vector3 &n, unsigned patchindex, const Vector2 &t);
bool Add_Vertex (unsigned vertexindex, const Vector3 &p, const Vector3 &n, unsigned patchindex, const ColorVector &c);
bool Add_Patch_Face (unsigned patchfaceindex, unsigned patchindex, unsigned vertexindexcount, unsigned *vertexindices);
// Database query functions.
float Get_Brightness() {return (Brightness);}
float Get_Contrast() {return (Contrast);}
bool Is_Daylight() {return (IsDaylight);}
bool Is_Exterior() {return (IsExterior);}
bool Is_M2T_Solve() {return (IsM2TSolve);}
float Filter_Sharpness() {return (FilterSharpness);}
ProceduralTexture *Procedural_Texture() {return (ProceduralTexture);}
unsigned Light_Count() {return (Lights.Count());}
LightClass *Get_Light (unsigned l) {return (Lights [l]);}
const char *Light_Exclusion_String() {return (LightExclusionString);}
void Find_Vertex (const Vector3 &point, const Vector3 *smoothingnormalptr, W3dRGBStruct &vertexcolor, SolveStatistics &solvestatistics);
void Find_Triangle (const Vector3 *points, const Vector3 &normal, PackingTriangle &triangle, SolveStatistics &solvestatistics);
void Submit_Triangle (PackingTriangle &triangle);
const TextureNameNode *Texture_Name (unsigned patchindex);
void Pack();
// Update the progress bar.
void Step_It() {ProgressBar->StepIt();}
// Static functions.
static LightscapeSolve *Importer() {return (_ActiveImporter);}
static const char *Asset_Directory() {return (LightmapPacker::Asset_Directory());}
static const char *Asset_Directory (const char *filename) {return (LightmapPacker::Asset_Directory (filename));}
static void Copy_Assets (const char *pathname) {LightmapPacker::Copy_Assets (pathname);}
private:
// Result of finding a face.
enum FaceResultEnum {
FACE_NOT_FOUND,
FACE_AMBIGUOUS,
FACE_FOUND
};
// Area of the face.
enum FaceSizeEnum {
FACE_DEGENERATE,
FACE_UNDERSIZED,
FACE_NOT_UNDERSIZED
};
struct VerticesStruct {
// Equality operator.
bool operator == (const VerticesStruct &v) {
return ((Point == v.Point) &&
(FaceNormal == v.FaceNormal) &&
(PatchIndex == v.PatchIndex) &&
(ValidColor == v.ValidColor) &&
(Color == v.Color) &&
(ValidUV == v.ValidUV) &&
(UV == v.UV));
}
// Inequality operator.
bool operator != (const VerticesStruct &v) {
return (!(*this == v));
}
Vector3 Point;
Vector3 FaceNormal;
unsigned PatchIndex;
bool ValidColor;
ColorVector Color;
bool ValidUV;
Vector2 UV;
};
struct PatchFaceStruct {
enum VerticesPerPatchFace {
VERTICES_PER_PATCH_FACE = 4
};
// To indicate whether a patch face vertex index is valid.
enum VertexIndexValidity {
VERTEX_INDEX_INVALID = -1
};
// Equality operator.
bool operator == (const PatchFaceStruct &p) {
return ((PatchIndex == p.PatchIndex) &&
(VertexIndices [0] == p.VertexIndices [0]) &&
(VertexIndices [1] == p.VertexIndices [1]) &&
(VertexIndices [2] == p.VertexIndices [2]) &&
(VertexIndices [3] == p.VertexIndices [3]));
}
// Inequality operator.
bool operator != (const PatchFaceStruct &p) {
return (!(*this == p));
}
unsigned PatchIndex;
unsigned VertexIndices [VERTICES_PER_PATCH_FACE];
};
// Member functions.
void Find_Adjacent_Triangles (const PackingTriangle &principaltriangle, DynamicVectorClass <Triangle> &adjtriangles);
void Find_Triangle (const Vector3 *points, const Vector3 &facenormal, VerticesStruct *vertices, FaceResultEnum &faceresult);
void Find_Triangle (const Vector3 *points, float tolerance, bool centroidtest, const Vector3 *facenormal, VerticesStruct *vertices, FaceResultEnum &faceresult);
void Find_Vertices (const Vector3 &point, float tolerance, DynamicVectorClass <VerticesStruct*> &vertices);
// Miscellaneous convenience functions.
FaceSizeEnum Face_Size (const Vector3 *points, unsigned count);
unsigned Longest_Edge (const Vector3 *points, unsigned count, bool *usededges);
float Manhatten_Distance (const Vector3 &v)
{
return (WWMath::Fabs (v.X) + WWMath::Fabs (v.Y) + WWMath::Fabs (v.Z));
}
// Comparison functions.
static int Compare_Material_Texture_Names (const void *materialname0, const void *materialname1);
static int Compare_Vertices (const void *vertexindexptr0, const void *vertexindexptr1);
static int Compare_Patch_Faces (const void *patchface0, const void *patchface1);
// Member data.
float SmoothingAngle;
float SpatialTolerance;
float FilterSharpness;
bool IsSolution; // Is the currently imported file a valid solve file?
int PatchClusterCount; // Total patch cluster count over all parsed solve files.
float Brightness;
float Contrast;
bool IsDaylight;
bool IsExterior;
bool IsM2TSolve;
ProceduralTexture *ProceduralTexture;
CProgressCtrl *ProgressBar;
DynamicVectorClass <char *> MaterialTextureNames; // <material name, texture pathname> pairs for all materials in the solve.
DynamicVectorClass <TextureNameNode*> TextureNames; // <texture pathname> for all patches in the solve.
DynamicVectorClass <VerticesStruct> Vertices; // <point, uv coordinate, normal, material index> tuples for all vertices in the solve.
DynamicVectorClass <unsigned> VertexIndices; // Indices into Vertices.
DynamicVectorClass <PatchFaceStruct> PatchFaces; // <patch index, face> pairs for all faces in the solve.
DynamicVectorClass <LightClass*> Lights; // All active lights in the solve.
const char *LightExclusionString; // Do not add lights that contain this string.
// Static data.
static LightscapeSolve *_ActiveImporter; // Object currently importing (reading a solution file) (otherwise NULL).
};
class LsInformationFactory : public LtTBuilderFactory
{
protected:
virtual LtTInfoBuilderApi *OnGetInfoBuilder();
virtual LtTParameterBuilderApi *OnGetParameterBuilder();
};
class LsPreparationFactory : public LtTBuilderFactory
{
protected:
virtual LtTInfoBuilderApi *OnGetInfoBuilder();
virtual LtTParameterBuilderApi *OnGetParameterBuilder();
virtual LtTMaterialBuilderApi *OnGetMaterialBuilder();
virtual LtTLampBuilderApi *OnGetLampBuilder();
virtual LtTMeshBuilderApi *OnGetMeshBuilder();
};
class LsMainFactory : public LtTBuilderFactory
{
public:
LsMainFactory();
unsigned Patch_Face_Count() {return (PatchFaceIndex);}
void Patch_Face_Increment() {PatchFaceIndex++;}
unsigned Vertex_Count() {return (VertexIndex);}
void Vertex_Increment() {VertexIndex++;}
unsigned Patch_Count() {return (PatchIndex);}
void Patch_Increment() {PatchIndex++; LightscapeSolve::Importer()->Step_It();}
protected:
virtual LtTInfoBuilderApi *OnGetInfoBuilder();
virtual LtTParameterBuilderApi *OnGetParameterBuilder();
virtual LtTMeshBuilderApi *OnGetMeshBuilder();
private:
unsigned PatchFaceIndex;
unsigned VertexIndex;
unsigned PatchIndex;
};
class LsInfoBuilder : public LtTBaseInfoBuilder
{
protected:
LsInfoBuilder (LtTBuilderFactory *factory);
LtTBool Finish();
friend class LsInformationFactory;
friend class LsPreparationFactory;
friend class LsMainFactory;
};
class LsParameterBuilder : public LtTBaseParameterBuilder
{
protected:
LsParameterBuilder (LtTBuilderFactory *factory);
LtTBool Finish();
friend class LsInformationFactory;
friend class LsPreparationFactory;
friend class LsMainFactory;
};
class LsMaterialBuilder : public LtTBaseMaterialBuilder
{
protected:
LsMaterialBuilder (LtTBuilderFactory *factory);
LtTBool Finish();
friend class LsPreparationFactory;
};
class LsLampBuilder : public LtTBaseLampBuilder
{
protected:
LsLampBuilder (LtTBuilderFactory *factory);
LtTBool Finish();
friend class LsPreparationFactory;
};
class LsMeshInquirer : public LtTBaseMeshBuilder
{
protected:
LsMeshInquirer (LtTBuilderFactory *factory);
LtTBool Finish();
friend class LsPreparationFactory;
};
class LsMeshBuilder : public LtTBaseMeshBuilder
{
protected:
LsMeshBuilder (LtTBuilderFactory *factory);
~LsMeshBuilder();
LtTBool Finish();
void SetFaces (const int facecount, const LtTFace *v);
int GetFaceCount() const;
const LtTFace *GetFaces() const;
LsMainFactory *FactoryPtr;
private:
struct FaceVertexStruct {
// Equality operator.
bool operator == (const FaceVertexStruct &fv) {
return ((Point == fv.Point) && (Color == fv.Color) && (Weight == fv.Weight));
}
// Inequality operator.
bool operator != (const FaceVertexStruct &fv) {
return (!(*this == fv));
}
Vector3 Point;
ColorVector Color;
float Weight;
};
LtTFace *Faces;
int FaceCount;
int AllocatedCount;
friend class LsMainFactory;
friend class VertexUser;
};
class VertexUser
{
public:
VertexUser (const LsMeshBuilder &meshbuilder);
~VertexUser () {delete [] UsedVertexIndices;}
bool Is_Used (unsigned vertexindex)
{
ASSERT (vertexindex < Count);
return (UsedVertexIndices [vertexindex] != UNUSED);
}
void Set_Index (unsigned vertexindex, unsigned usedvertexindex)
{
ASSERT (Is_Used (vertexindex));
UsedVertexIndices [vertexindex] = usedvertexindex;
}
unsigned Get_Index (unsigned vertexindex)
{
ASSERT (vertexindex < Count);
// This vertex must have previously been set.
ASSERT (UsedVertexIndices [vertexindex] >= 0);
return (UsedVertexIndices [vertexindex]);
}
private:
enum VertexUsage {
UNUSED = -2,
USED = -1
};
VertexUser() {}
unsigned Count;
int *UsedVertexIndices;
};
class LightscapeMeshSolve
{
public:
LightscapeMeshSolve (LightscapeSolve &solve, ChunkClass &trianglechunk, ChunkClass &vertexchunk);
~LightscapeMeshSolve();
W3dRGBStruct Vertex_Color (unsigned vertexindex) const;
unsigned Vertex_Color_Count() const {return (VertexCount);}
const char *Lightmap_Pathname (unsigned lightmapindex) const;
unsigned Lightmap_Index (unsigned faceindex) const;
W3dTexCoordStruct Lightmap_UV (unsigned facevertexindex) const;
unsigned Lightmap_Count() const {return (LightmapCount);}
const SolveStatistics *Get_Statistics() const {return (&Statistics);}
private:
unsigned VertexCount; // No. of vertices in mesh.
unsigned FaceCount; // No. of faces in mesh.
unsigned FaceVertexCount; // No. of face-vertices in mesh.
unsigned LightmapCount; // No. of lightmaps used by mesh.
W3dRGBStruct *VertexColors; // Array of vertex colors.
Vector2 *FaceVertexUVs; // Array to map a face-vertex index to a UV coordinate.
unsigned *FaceRemapLightmapIndices; // Array to map a face to a zero-based lightmap index.
unsigned *LightmapIndices; // Array to map a zero-based lightmap index to a 'real' lightmap index.
SolveStatistics Statistics; // Statistics counters.
};
#endif // LIGHTSCAPE_H