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/LightMapDoc.h

386 lines
17 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/24/01 4:53p $*
* *
* $Revision:: 39 $*
* *
*---------------------------------------------------------------------------------------------*
* Functions: *
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
#ifndef LIGHTMAPDOC_H
#define LIGHTMAPDOC_H
// Includes.
#include "Rawfile.h"
#include "w3d_file.h"
#include "Chunk.h"
#include "Lightscape.h"
#include "meshmdl.h"
// Defines.
#define MAX_SOLVE_COUNT 2
#define TEMPORARY_SOLVE_FILENAME_COUNT 2
class LightMapDoc : public CDocument
{
public:
enum PrelitModeEnum {
UNLIT,
VERTEX,
MULTI_PASS,
MULTI_TEXTURE,
COUNT
};
// Flags for anomalies in a W3D model.
// WARNING: Do not exceed no. of bits in unsigned long.
enum MeshFlagsEnum {
// Unconditional errors.
MESH_HIDDEN,
MESH_PRELIT,
MESH_NO_VERTEX_MATERIALS,
MESH_NO_SHADERS,
MESH_HAS_HIERARCHY,
MESH_NOT_MODULATED_PRIMARY,
MESH_HAS_SPECULAR,
MESH_SPECULAR_TO_DIFFUSE,
MESH_W3D_CHUNK_DEFORM,
MESH_TWO_SIDED,
MESH_HAS_EMISSIVE,
MESH_HAS_SCG,
// Vertex specific errors.
MESH_HAS_DIG,
// Lightmap multi-pass specific errors.
MESH_TOO_MANY_PASSES,
MESH_ALPHATEST,
MESH_PASS_ZERO_DESTBLEND,
// Lightmap multi-texture specific errors.
MESH_TOO_MANY_STAGES,
// General warnings.
MESH_VERTEX_COLORING,
MESH_FLAG_COUNT,
// Unconditional errors.
MESH_ERROR_MASK = (1 << MESH_HIDDEN) |
(1 << MESH_PRELIT) |
(1 << MESH_NO_VERTEX_MATERIALS) |
(1 << MESH_NO_SHADERS) |
(1 << MESH_HAS_HIERARCHY) |
(1 << MESH_NOT_MODULATED_PRIMARY) |
(1 << MESH_HAS_SPECULAR) |
(1 << MESH_SPECULAR_TO_DIFFUSE) |
(1 << MESH_W3D_CHUNK_DEFORM) |
(1 << MESH_TWO_SIDED) |
(1 << MESH_HAS_EMISSIVE) |
(1 << MESH_HAS_SCG),
// Anomalies that will prevent a vertex solve from being inserted.
MESH_VERTEX_ERROR_MASK = MESH_ERROR_MASK |
(1 << MESH_HAS_DIG),
// Anomalies that will prevent a multi-pass lightmap solve from being inserted.
MESH_MULTI_PASS_ERROR_MASK = MESH_ERROR_MASK |
(1 << MESH_TOO_MANY_PASSES) |
(1 << MESH_ALPHATEST) |
(1 << MESH_PASS_ZERO_DESTBLEND),
// Anomalies that will prevent a multi-texture lightmap solve from being inserted.
MESH_MULTI_TEXTURE_ERROR_MASK = MESH_ERROR_MASK |
(1 << MESH_TOO_MANY_STAGES)
};
// Functions.
bool Is_Open() {return (W3dFile != NULL);}
bool Can_Insert_Solve() {return (CanInsertSolve && SolveCount < MAX_SOLVE_COUNT);}
void Insert_Solve (const char *solvedirectoryname, const char *solvefilenamelist, const char *inclusionstring, bool invertselection, bool blendnoise);
bool Solve_Inserted() {return (SolveCount > 0);}
unsigned Mesh_Count() {return (MeshStatus.Count());}
const char *Mesh_Name (unsigned index) {return (MeshStatus [index].Name);}
const char *Mesh_Anomalies_String (unsigned meshindex, bool verbose, StringBuilder &string);
const char *Solve_Anomalies_String (unsigned meshindex, bool verbose, StringBuilder &string);
const char *Vertex_Solve_Status_String (unsigned meshindex, StringBuilder &string);
const char *Lightmap_Solve_Status_String (unsigned meshindex, StringBuilder &string);
private:
struct MeshInfoStruct {
public:
MeshInfoStruct (FileClass &meshfile);
~MeshInfoStruct ();
unsigned Lightmap_Vertex_Material_Count() const {return (1);}
unsigned Lightmap_Shader_Count() const {return (1);}
W3dMeshHeader3Struct Header;
W3dMaterialInfoStruct MaterialInfo [PrelitModeEnum::COUNT];
ChunkClass *TriangleChunk;
ChunkClass *VertexChunk;
DynamicVectorClass <W3dVertexMaterialStruct> *VertexMaterials [PrelitModeEnum::COUNT];
ChunkClass *ShaderChunk [PrelitModeEnum::COUNT];
ChunkClass *ShaderIdChunk [PrelitModeEnum::COUNT][MeshMatDescClass::MAX_PASSES];
ChunkClass *SCGChunk [PrelitModeEnum::COUNT][MeshMatDescClass::MAX_PASSES];
bool SCGsExist;
bool DIGsExist;
bool DeformExists;
bool IsMultiStage;
bool VertexColorsExist;
private:
void Parse_Vertex_Materials (ChunkLoadClass &w3dchunk, unsigned prelitmode);
void Parse_Material_Pass (ChunkLoadClass &w3dchunk, unsigned prelitmode, unsigned materialpass);
void Parse_Prelit_Chunk (ChunkLoadClass &w3dchunk, unsigned prelitmode);
};
struct MeshAnomalyStruct {
public:
MeshAnomalyStruct (const MeshInfoStruct &meshinfo);
unsigned long MeshAnomalies;
};
struct MeshStatusStruct {
// Equality operator.
bool operator == (const MeshStatusStruct &m) {
return (strcmp (Name, m.Name) == 0);
}
// Inequality operator.
bool operator != (const MeshStatusStruct &m) {
return (!(*this == m));
}
MeshStatusStruct() {}
MeshStatusStruct (const char *name, unsigned trianglecount, unsigned long meshanomalies)
{
strcpy (Name, name);
TriangleCount = trianglecount;
MeshAnomalies = meshanomalies;
InsertedFlags = 0;
}
bool Can_Insert_Vertex_Solve() {
return (((MeshAnomalies & MESH_VERTEX_ERROR_MASK) == 0) && SolveStatistics.Valid_Vertex_Solve());
}
bool Can_Insert_Multi_Pass_Solve() {
return (((MeshAnomalies & MESH_MULTI_PASS_ERROR_MASK) == 0) && SolveStatistics.Valid_Lightmap_Solve());
}
bool Can_Insert_Multi_Texture_Solve() {
return (((MeshAnomalies & MESH_MULTI_TEXTURE_ERROR_MASK) == 0) && SolveStatistics.Valid_Lightmap_Solve());
}
bool Inserted_Vertex_Solve() {return ((InsertedFlags & W3D_MESH_FLAG_PRELIT_VERTEX) != 0);}
bool Inserted_Multi_Pass_Solve() {return ((InsertedFlags & W3D_MESH_FLAG_PRELIT_LIGHTMAP_MULTI_PASS) != 0);}
bool Inserted_Multi_Texture_Solve() {return ((InsertedFlags & W3D_MESH_FLAG_PRELIT_LIGHTMAP_MULTI_TEXTURE) != 0);}
unsigned long Prelit_Flags() {
unsigned long prelitflags;
// If a vertex solve cannot be inserted substitute an unlit solve.
if (Can_Insert_Vertex_Solve()) {
prelitflags = W3D_MESH_FLAG_PRELIT_VERTEX;
} else {
prelitflags = W3D_MESH_FLAG_PRELIT_UNLIT;
}
if (Can_Insert_Multi_Pass_Solve()) prelitflags |= W3D_MESH_FLAG_PRELIT_LIGHTMAP_MULTI_PASS;
if (Can_Insert_Multi_Texture_Solve()) prelitflags |= W3D_MESH_FLAG_PRELIT_LIGHTMAP_MULTI_TEXTURE;
return (prelitflags);
}
char Name [W3D_NAME_LEN];
unsigned TriangleCount;
unsigned long MeshAnomalies;
unsigned long InsertedFlags; // Which prelit mode types were inserted with the most recent solve?
SolveStatistics SolveStatistics;
};
struct SplitVertexInfoStruct {
public:
SplitVertexInfoStruct (const MeshInfoStruct &meshinfo, const LightscapeMeshSolve &meshsolve);
~SplitVertexInfoStruct();
unsigned Vertex_Count() const {return (VertexCount);}
uint32 Remap (unsigned v) const {ASSERT (v < Vertex_Count()); return (RemapTable [v]);}
uint32 Index (unsigned v) const {ASSERT (v < FaceVertexCount); return (IndexTable [v]);}
W3dTexCoordStruct *UV (unsigned v) const {ASSERT (v < Vertex_Count()); return (UVPtrTable [v]);}
private:
SplitVertexInfoStruct() {ASSERT (false);}
unsigned VertexCount;
unsigned FaceVertexCount;
uint32 *RemapTable;
uint32 *IndexTable;
W3dTexCoordStruct *UVTable;
W3dTexCoordStruct **UVPtrTable;
};
struct MeshReorderStruct {
// Equality operator.
bool operator == (const MeshReorderStruct &m) {
return ((Chunk == m.Chunk) && (Position == m.Position));
}
// Inequality operator.
bool operator != (const MeshReorderStruct &m) {
return (!(*this == m));
}
public:
ChunkClass *Chunk;
Vector3 Position;
};
// Functions.
bool Check_Document();
void Reorder();
void Optimize();
void Optimize_Prelit_Vertex_Material_Pass (ChunkLoadClass &w3dchunk, ChunkSaveClass &optimizechunk);
void Rename_Mesh (ChunkLoadClass &loadchunk, ChunkSaveClass &savechunk, const char *filename, const char *lightmapdirectory);
void Rename_Mesh_Header (ChunkLoadClass &loadchunk, ChunkSaveClass &savechunk, const char *filename);
void Rename_Prelit_Chunks (ChunkLoadClass &loadchunk, ChunkSaveClass &savechunk, const char *lightmapdirectory);
void Rename_Lightmaps (ChunkLoadClass &loadchunk, ChunkSaveClass &savechunk, const char *lightmapdirectory);
void Rename_Collection (ChunkLoadClass &loadchunk, ChunkSaveClass &savechunk, const char *filename);
void Rename_HLOD (ChunkLoadClass &loadchunk, ChunkSaveClass &savechunk, const char *filename);
void Rename_Dazzle (ChunkLoadClass &loadchunk, ChunkSaveClass &savechunk, const char *filename);
void Save_Lights (const char *pathname);
void Translate_Mesh_Header3 (ChunkLoadClass &w3dchunk, unsigned long prelitflags, ChunkSaveClass &solvechunk, const SplitVertexInfoStruct &splitvertexinfo);
void Translate_Vertices (ChunkLoadClass &w3dchunk, ChunkSaveClass &solvechunk, const SplitVertexInfoStruct &splitvertexinfo);
void Translate_Vertex_Normals (ChunkLoadClass &w3dchunk, ChunkSaveClass &solvechunk, const SplitVertexInfoStruct &splitvertexinfo);
void Translate_Vertex_Influences (ChunkLoadClass &w3dchunk, ChunkSaveClass &solvechunk, const SplitVertexInfoStruct &splitvertexinfo);
void Translate_Triangles (ChunkLoadClass &w3dchunk, ChunkSaveClass &solvechunk, const SplitVertexInfoStruct &splitvertexinfo);
void Translate_Vertex_Shade_Indices (ChunkLoadClass &w3dchunk, ChunkSaveClass &solvechunk, const SplitVertexInfoStruct &splitvertexinfo);
void Insert_Solve (PrelitModeEnum inputmode, FileClass &meshfile, PrelitModeEnum outputmode, ChunkSaveClass &solvechunk, const MeshInfoStruct &meshinfo, const LightscapeMeshSolve &meshsolve, const SplitVertexInfoStruct &splitvertexinfo);
void Insert_Solve (PrelitModeEnum inputmode, ChunkLoadClass &w3dchunk, PrelitModeEnum outputmode, ChunkSaveClass &solvechunk, const MeshInfoStruct &meshinfo, const LightscapeMeshSolve &meshsolve, const SplitVertexInfoStruct &splitvertexinfo);
void Translate_Material_Info (PrelitModeEnum inputmode, ChunkLoadClass &w3dchunk, PrelitModeEnum outputmode, ChunkSaveClass &solvechunk, const MeshInfoStruct &meshinfo, const LightscapeMeshSolve &meshsolve);
void Translate_Vertex_Materials (PrelitModeEnum inputmode, ChunkLoadClass &w3dchunk, PrelitModeEnum outputmode, ChunkSaveClass &solvechunk, const MeshInfoStruct &meshinfo);
void Translate_Shaders (PrelitModeEnum inputmode, ChunkLoadClass &w3dchunk, PrelitModeEnum outputmode, ChunkSaveClass &solvechunk, const MeshInfoStruct &meshinfo);
void Translate_Textures (ChunkLoadClass &w3dchunk, PrelitModeEnum outputmode, ChunkSaveClass &solvechunk, const LightscapeMeshSolve &meshsolve);
void Add_Lightmap_Textures (ChunkSaveClass &solvechunk, const LightscapeMeshSolve &meshsolve);
void Translate_Material_Pass (PrelitModeEnum inputmode, ChunkLoadClass &w3dchunk, unsigned materialpass, PrelitModeEnum outputmode, ChunkSaveClass &solvechunk, const MeshInfoStruct &meshinfo, const LightscapeMeshSolve &meshsolve, const SplitVertexInfoStruct &splitvertexinfo);
void Translate_DCGs (ChunkLoadClass &w3dchunk, ChunkSaveClass &solvechunk, const SplitVertexInfoStruct &splitvertexinfo);
void Translate_DIGs (PrelitModeEnum inputmode, ChunkLoadClass &w3dchunk, unsigned materialpass, ChunkSaveClass &solvechunk, const MeshInfoStruct &meshinfo, const LightscapeMeshSolve &meshsolve, const SplitVertexInfoStruct &splitvertexinfo);
void Add_DIGs (PrelitModeEnum inputmode, unsigned materialpass, ChunkSaveClass &solvechunk, const MeshInfoStruct &meshinfo, const LightscapeMeshSolve &meshsolve, const SplitVertexInfoStruct &splitvertexinfo);
void Translate_Vertex_Material_IDs (PrelitModeEnum inputmode, ChunkLoadClass &w3dchunk, ChunkSaveClass &solvechunk, const MeshInfoStruct &meshinfo, const SplitVertexInfoStruct &splitvertexinfo);
void Translate_Texture_Stage (ChunkLoadClass &w3dchunk, ChunkSaveClass &solvechunk, const SplitVertexInfoStruct &splitvertexinfo);
void Translate_Stage_Texcoords (ChunkLoadClass &w3dchunk, ChunkSaveClass &solvechunk, const SplitVertexInfoStruct &splitvertexinfo);
void Add_Lightmap_Material_Pass (PrelitModeEnum inputmode, unsigned materialpass, ChunkSaveClass &solvechunk, const MeshInfoStruct &meshinfo, const LightscapeMeshSolve &meshsolve, const SplitVertexInfoStruct &splitvertexinfo);
void Add_Lightmap_Stage (PrelitModeEnum inputmode, ChunkSaveClass &solvechunk, const MeshInfoStruct &meshinfo, const LightscapeMeshSolve &meshsolve, const SplitVertexInfoStruct &splitvertexinfo);
void Translate_Lightmap_Stage (PrelitModeEnum inputmode, ChunkLoadClass &w3dchunk, ChunkSaveClass &solvechunk, const MeshInfoStruct &meshinfo, const LightscapeMeshSolve &meshsolve, const SplitVertexInfoStruct &splitvertexinfo);
void Add_Lightmap_Stage_Chunks (PrelitModeEnum inputmode, ChunkSaveClass &solvechunk, const MeshInfoStruct &meshinfo, const LightscapeMeshSolve &meshsolve, const SplitVertexInfoStruct &splitvertexinfo);
void Copy_Chunk (ChunkLoadClass &loadchunk, ChunkSaveClass &savechunk);
// Member data.
char DocumentName [_MAX_FNAME]; // Name of this document.
RawFileClass *W3dFile; // Ptr to current open w3d document.
unsigned MeshCount; // Total no. of meshes in this w3d document.
unsigned TriangleCount; // Total no. of triangles in this w3d document.
bool CanInsertSolve; // Can a solve be inserted?
unsigned SolveCount; // No. of solves inserted so far.
DynamicVectorClass <MeshStatusStruct> MeshStatus; // Mesh information database.
DynamicVectorClass <LightClass*> Lights [MAX_SOLVE_COUNT]; // All active lights in the solves.
// Static data.
static const char *_TemporarySolveFilename [TEMPORARY_SOLVE_FILENAME_COUNT];
static const char *_TemporaryOptimizeFilename;
static const char *_TemporaryReorderFilename;
// The following is maintained by MFC tools.
protected: // create from serialization only
LightMapDoc();
DECLARE_DYNCREATE(LightMapDoc)
// Attributes
public:
// Operations
public:
// Overrides
// ClassWizard generated virtual function overrides
//{{AFX_VIRTUAL(LightMapDoc)
public:
virtual BOOL OnNewDocument();
virtual BOOL OnOpenDocument(LPCTSTR lpszPathName);
virtual void Serialize(CArchive& ar);
virtual BOOL OnSaveDocument(LPCTSTR lpszPathName);
virtual void DeleteContents();
//}}AFX_VIRTUAL
// Implementation
public:
virtual ~LightMapDoc();
#ifdef _DEBUG
virtual void AssertValid() const;
virtual void Dump(CDumpContext& dc) const;
#endif
// Generated message map functions
protected:
//{{AFX_MSG(LightMapDoc)
afx_msg void OnFileSave();
afx_msg void OnFileSaveAs();
afx_msg void OnUpdateFileSave(CCmdUI* pCmdUI);
afx_msg void OnUpdateFileSaveAs(CCmdUI* pCmdUI);
//}}AFX_MSG
DECLARE_MESSAGE_MAP()
};
#endif // LIGHTMAPDOC_H