Paranoia2/utils/p2rad/qrad.h

516 lines
15 KiB
C

/***
*
* Copyright (c) 1996-2002, Valve LLC. All rights reserved.
*
* This product contains software technology licensed from Id
* Software, Inc. ("Id Technology"). Id Technology (c) 1996 Id Software, Inc.
* All Rights Reserved.
*
****/
#include <windows.h>
#include <io.h>
#include <fcntl.h>
#include "cmdlib.h"
#include "mathlib.h"
#include "bspfile.h"
#include "polylib.h"
#include "threads.h"
#include "stringlib.h"
#include "filesystem.h"
#include "utlarray.h"
#define DEFAULT_FASTMODE false
#define DEFAULT_EXTRAMODE false
#define DEFAULT_TEXSCALE true
#define DEFAULT_CHOP 128.0
#define DEFAULT_TEXCHOP 32.0
#define DEFAULT_DLIGHT_SCALE 2.0
#define DEFAULT_LIGHT_SCALE 1.0
#define DEFAULT_LERP_ENABLED false
#define DEFAULT_WADTEXTURES false
#define DEFAULT_DIRTMAPPING false
#define DEFAULT_TEXREFLECTGAMMA (1.0 / 2.2) // turn back to linear space
#define DEFAULT_TEXREFLECTSCALE 1.0
#define DEFAULT_BLUR 1.0
#define DEFAULT_BOUNCE 3
#define DEFAULT_LIGHTCLIP 196
#define DEFAULT_SMOOTHVALUE 50.0
#define DEFAULT_INDIRECT_SUN 1.0
#define DEFAULT_GAMMA 0.5
#define DLIGHT_THRESHOLD 10.0
// worldcraft predefined angles
#define ANGLE_UP -1
#define ANGLE_DOWN -2
#define DIRECT_SCALE 0.1
#define DEFAULT_HUNT_OFFSET 0.5
#define DEFAULT_EDGE_WIDTH 0.8
#define HUNT_WALL_EPSILON (ON_EPSILON * 3)
#define DIFFUSE_DIRECTION_SCALE (2.0 / 3.0)
#define MINIMUM_PATCH_DISTANCE ON_EPSILON
#define ACCURATEBOUNCE_THRESHOLD 4.0 // If the receiver patch is closer to emitter patch than
// EXACTBOUNCE_THRESHOLD * emitter_patch->radius, calculate the exact visibility amount.
#define ACCURATEBOUNCE_DEFAULT_SKYLEVEL 5 // sample 1026 normals
#define SKYLEVELMAX 8
#define SKYLEVEL_SOFTSKYON 7
#define SKYLEVEL_SOFTSKYOFF 4
#define SUNSPREAD_SKYLEVEL 7
#define SUNSPREAD_THRESHOLD 15.0
#define NUMVERTEXNORMALS 162
#define LF_SCALE 128.0 // TyrUtils magic value
#define DEFAULT_GAMMAMODE 0
#define FRAC_EPSILON (1.0f / 32.0f)
#define MAX_SINGLEMAP ((MAX_CUSTOM_SURFACE_EXTENT+1) * (MAX_CUSTOM_SURFACE_EXTENT+1) * 3)
#define MAX_SINGLEMAP_MODEL ((MAX_MODEL_SURFACE_EXTENT+1) * (MAX_MODEL_SURFACE_EXTENT+1) * 3)
#define MAX_SUBDIVIDE 16384
#define MAX_TEXLIGHTS 1024
// Paranoia settings
#define LIGHTFLAG_NOT_NORMAL 2
#define LIGHTFLAG_NOT_RENDERER 4
enum
{
STYLE_ORIGINAL_LIGHT = 0, // direct + indirect, used while gl_renderer is 0
STYLE_BUMPED_LIGHT = 1,
STYLE_INDIRECT_LIGHT = 2, // store indirect lighting from patches
};
// buz
enum
{
BUMP_BASELIGHT_MAP = 1, // indirect
BUMP_LIGHTVECS_MAP = 2, // light vectors
BUMP_ADDLIGHT_MAP = 3, // direct
BUMP_BASELIGHT_STYLE = 61,
BUMP_ADDLIGHT_STYLE = 62,
BUMP_LIGHTVECS_STYLE = 63,
};
typedef struct
{
char name[256];
const char *filename;
vec3_t value;
vec_t fade;
} texlight_t;
typedef CUtlArray<int> CIntVector;
typedef struct dlight_s
{
// private part
struct dlight_s *next;
vec_t patch_area;
vec_t patch_emitter_range;
struct patch_s *patch;
byte *pvs; // accumulated domain of the light
int flags; // buz: how to work without flags???
// sun spread stuff
vec_t *sunnormalweights;
vec_t sunspreadangle;
int numsunnormals;
vec3_t *sunnormals;
// this part is shared with dworldlight_t
emittype_t type;
int style;
vec_t fade; // falloff scaling 1.0 = normal, 0.5 = farther, 2.0 = shorter etc
byte falloff; // falloff style 0,2 = inverse square, 1 = inverse falloff
word lightnum; // worldlight number
vec3_t origin;
vec3_t intensity;
vec3_t diffuse_intensity; // skylight only
vec3_t normal; // for surfaces and spotlights
float stopdot; // for spotlights
float stopdot2; // for spotlights
float lf_scale; // 1.0 for half-life, 128.0 for quake
bool topatch;
int facenum;
word modelnum;
float radius;
} directlight_t;
typedef struct
{
vec3_t point; // originally that called a surfpt
bool occluded; // luxel was occluded
vec3_t position;
int surface;
} surfpt_t;
typedef struct
{
union
{
int surfnum;
entity_t *mapent;
};
// reuse it for studiomodels
union
{
const dplane_t *plane; // faceplane
struct tface_t *tface;
};
union
{
dface_t *face;
struct tmesh_t *mesh;
};
vec3_t texorg;
vec3_t worldtotex[2]; // s = (world - texorg) . worldtotex[0]
vec3_t textoworld[2]; // world = texorg + s * textoworld[0]
vec_t exactmins[2];
vec_t exactmaxs[2];
int texmins[2];
int texsize[2];
surfpt_t *surfpt; // product of CalcPoints
int numsurfpt;
int lmcache_side;
int lmcache_density; // shared by both s and t direction
int lmcache_offset; // shared by both s and t direction
int lmcachewidth;
int lmcacheheight;
vec3_t (*light)[MAXLIGHTMAPS];
#ifdef HLRAD_DELUXEMAPPING
vec3_t *normals;
vec3_t (*deluxe)[MAXLIGHTMAPS];
#ifdef HLRAD_SHADOWMAPPING
vec_t (*shadow)[MAXLIGHTMAPS];
#endif
#endif
} lightinfo_t;
typedef struct
{
vec3_t facenormal; // face normal
int numneighbors; // neighboring faces that share vertices
int *neighbor; // neighboring face list (max of 64)
short texmins[2]; // also used for face testing
short extents[2];
short lightmapmins[2]; // lightmatrix
short lightextents[2];
} faceneighbor_t;
typedef struct
{
dface_t *faces[2];
vec3_t interface_normal;
vec3_t vertex_normal[2];
bool coplanar, smooth;
vec_t cos_normals_angle;
matrix3x4 textotex[2]; // how we translate texture coordinates from one face to the other face
} edgeshare_t;
struct trace_t
{
int contents;
float fraction; // time completed, 1.0 = didn't hit anything
int surface; // return the facenum
};
#ifdef HLRAD_SHRINK_MEMORY
#define TRANSFER_SCALE_VAL (1.0)
#else
#define TRANSFER_SCALE_VAL (16384)
#endif
#define TRANSFER_SCALE (1.0f / TRANSFER_SCALE_VAL)
#define INVERSE_TRANSFER_SCALE (TRANSFER_SCALE_VAL)
#define TRANSFER_SCALE_MAX (65536.0f)
#define MAX_COMPRESSED_TRANSFER_INDEX ( BIT( 12 ) - 1 )
typedef struct
{
uint size : 12;
uint index : 20;
} transfer_index_t;
#ifdef HLRAD_SHRINK_MEMORY
typedef half transfer_data_t;
#else
typedef unsigned short transfer_data_t;
#endif
#define PATCH_OUTSIDE BIT( 0 )
#define PATCH_EMITLIGHT BIT( 1 ) // is the emit_surface patch
#define PATCH_SOURCE BIT( 2 ) // non subdivided patch
#define PATCH_CHILD BIT( 3 ) // subdivised from parent patch
#define MAX_PATCHES (65536 * 4) // probably enough
typedef struct patch_s
{
struct patch_s *next; // next in face
vec3_t origin;
vec_t area;
vec_t exposure;
vec_t fade;
winding_t *winding;
vec_t scale; // scaling of texture in s & t
byte flags;
vec_t chop; // smallest acceptable width of patch face
int leafnum;
int faceNumber;
word modelnum;
word lightnum;
vec_t emitter_range; // Range from patch origin (cached info calculated from winding)
byte emitter_skylevel; // The "skylevel" used for sampling of normals, when the receiver patch is
// within the range of ACCURATEBOUNCE_THRESHOLD * this->radius.
// input
byte emitstyle; // for switchable texlights
vec3_t baselight; // emissivity only, uses emitstyle
vec3_t reflectivity; // Average RGB of texture, modified by material type.
// light transport
uint iIndex;
uint iData;
transfer_index_t *tIndex;
transfer_data_t *tData;
// output
byte totalstyle[MAXLIGHTMAPS]; // gives the styles for use by the new switchable totallight values
vec3_t totallight[MAXLIGHTMAPS]; // accumulated by radiosity does NOT include light accounted for by direct lighting
vec3_t directlight[MAXLIGHTMAPS]; // direct light only
vec3_t samplelight[MAXLIGHTMAPS];
vec_t samples[MAXLIGHTMAPS]; // for averaging direct light
#ifdef HLRAD_DELUXEMAPPING
vec3_t totallight_dir[MAXLIGHTMAPS];
vec3_t directlight_dir[MAXLIGHTMAPS];
vec3_t samplelight_dir[MAXLIGHTMAPS];
#endif
} patch_t;
#ifdef HLRAD_SHRINK_MEMORY
typedef struct
{
// in local luxel space
bool occluded; // luxel was occluded
int surface; // this sample can grow into another face
#ifdef HLRAD_DELUXEMAPPING
hvec3_t normal; // phong normal
#endif
vec3_t pos; // in world units
hvec3_t light[MAXLIGHTMAPS]; // total lightvalue
#ifdef HLRAD_DELUXEMAPPING
hvec3_t deluxe[MAXLIGHTMAPS]; // direct lightnormal (ignoring occlusion)
#ifdef HLRAD_SHADOWMAPPING
half shadow[MAXLIGHTMAPS]; // shadow value (occlusion only)
#endif
#endif
} sample_t;
#else
typedef struct
{
// in local luxel space
bool occluded; // luxel was occluded
int surface; // this sample can grow into another face
#ifdef HLRAD_DELUXEMAPPING
vec3_t normal; // phong normal
#endif
vec3_t pos; // in world units
vec3_t light[MAXLIGHTMAPS]; // total lightvalue
#ifdef HLRAD_DELUXEMAPPING
vec3_t deluxe[MAXLIGHTMAPS]; // direct lightnormal (ignoring occlusion)
#ifdef HLRAD_SHADOWMAPPING
vec_t shadow[MAXLIGHTMAPS]; // shadow value (occlusion only)
#endif
#endif
} sample_t;
#endif
typedef struct
{
unsigned short numsamples;
sample_t *samples;
} facelight_t;
extern patch_t *g_face_patches[MAX_MAP_FACES];
extern entity_t *g_face_entity[MAX_MAP_FACES];
extern vec3_t g_face_offset[MAX_MAP_FACES]; // for rotating bmodels
extern vec3_t g_face_centroids[MAX_MAP_FACES];
extern faceneighbor_t g_faceneighbor[MAX_MAP_FACES];
extern facelight_t g_facelight[MAX_MAP_FACES];
extern vec_t *g_skynormalsizes[SKYLEVELMAX+1];
extern int g_numskynormals[SKYLEVELMAX+1];
extern vec3_t *g_skynormals[SKYLEVELMAX+1];
extern int g_overflowed_styles_onface[MAX_THREADS];
extern int g_overflowed_styles_onpatch[MAX_THREADS];
extern int g_direct_luxels[MAX_THREADS];
extern int g_lighted_luxels[MAX_THREADS];
extern vec_t g_anorms[NUMVERTEXNORMALS][3];
extern size_t g_transfer_data_size[MAX_THREADS];
extern edgeshare_t *g_edgeshare;
extern patch_t *g_patches;
extern uint g_num_patches;
//==============================================
//==============================================
extern bool g_extra;
extern vec3_t g_ambient;
extern bool g_fastmode;
extern float g_maxlight;
extern uint g_numbounce;
extern vec_t g_direct_scale;
extern vec_t g_indirect_scale;
extern float g_indirect_sun;
extern float g_smoothing_threshold;
extern bool g_lightbalance;
extern char source[MAX_PATH];
extern bool g_lerp_enabled;
extern bool g_nomodelshadow;
extern vec_t g_smoothvalue;
extern bool g_drawsample;
extern bool g_wadtextures;
extern bool g_dirtmapping;
extern bool g_onlylights;
extern int g_numdlights;
extern uint g_gammamode;
extern vec_t g_gamma;
extern vec_t g_blur;
//
// ambientcube.c
//
void ComputeLeafAmbientLighting( void );
//
// facepos.c
//
void TranslateWorldToTex( int facenum, matrix3x4 out );
void FindFacePositions( int facenum, int threadnum = -1 );
void FreeFacePositions( void );
bool FindNearestPosition( int facenum, const winding_t *w, vec_t s, vec_t t, vec3_t pos, vec_t *out_s, vec_t *out_t, vec_t *dist );
void CalcPositionsSize( void );
//
// dirtmap.c
//
void SetupDirt( void );
float GatherSampleDirt( int threadnum, int fn, const vec3_t pos, const vec3_t normal, entity_t *ignoreent );
//
// qrad.c
//
const dplane_t *GetPlaneFromFace( const dface_t *face );
const dplane_t *GetPlaneFromFace( const uint facenum );
dleaf_t *HuntForWorld( vec3_t point, const vec3_t plane_offset, const dplane_t *plane, int hunt_size, vec_t hunt_scale, vec_t hunt_offset );
vec_t CalcSightArea( const vec3_t receiver_origin, const vec3_t receiver_normal, const winding_t *emitter_winding, int skylevel );
void GetAlternateOrigin( const vec3_t pos, const vec3_t normal, const patch_t *patch, vec3_t origin );
vec_t BaseLightForFace( dface_t *f, vec3_t light, vec3_t reflectivity );
void InitWorldLightFromPatch( dworldlight_t *wl, patch_t *p );
void InitWorldLightFromDlight( directlight_t *dl, int leafnum );
int GetVisCache( int lastoffset, int offset, byte *pvs );
void SetDLightVis( directlight_t *dl, int leafnum );
void MergeDLightVis( directlight_t *dl, int leafnum );
winding_t *WindingFromFace( const dface_t *f );
void CalcTransferSize( void );
void PairEdges( void );
void FreeSharedEdges( void );
void BuildFaceNeighbors( void );
void FreeFaceNeighbors( void );
void BuildDiffuseNormals( void );
void FreeDiffuseNormals( void );
void BuildFaceLights( int facenum, int threadnum = -1 );
void PrecompLightmapOffsets();
void FinalLightFace( int facenum, int threadnum = -1 );
bool PvsForOrigin( const vec3_t org, byte *pvs );
void CreateDirectLights (void);
void DeleteDirectLights (void);
vec_t PatchPlaneDist( patch_t *patch );
void GetPhongNormal( int facenum, const vec3_t spot, vec3_t phongnormal );
void GetPhongNormal2( int facenum, const vec3_t spot, vec3_t phongnormal );
void FreeFaceLights( void );
void ReduceLightmap( void );
//
// lerp.c
//
extern void CreateTriangulations( int facenum, int threadnum );
extern void GetTriangulationPatches( int facenum, int *numpatches, const int **patches );
extern void InterpolateSampleLight( const vec3_t position, int surface, int numstyles, const int *styles, vec3_t *outs, vec3_t *outs_dir = NULL );
extern void FreeTriangulations( void );
//
// lightmap.c
//
void GatherSampleLight( int threadnum, int fn, const vec3_t pos, int leafnum, const vec3_t normal,
vec3_t *s_light, vec3_t *s_dir, vec_t *s_occ, byte *styles, byte *vislight, bool topatch, entity_t *ignoreent = NULL );
void TexelSpaceToWorld( const lightinfo_t *l, vec3_t world, const vec_t s, const vec_t t );
void WorldToTexelSpace( const lightinfo_t *l, const vec3_t world, vec_t &s, vec_t &t );
int ParseLightIntensity( const char *pLight, vec3_t intensity, vec_t multiplier = 255.0 );
void TranslateWorldToTex( int facenum, matrix3x4 out );
void InitLightinfo( lightinfo_t *pl, int facenum );
vec_t *GetTotalLight( patch_t *patch, int style );
vec_t *GetTotalDirection( patch_t *patch, int style );
void ScaleDirectLights( void );
void CreateFacelightDependencyList( void );
void FacePatchLights( int facenum, int threadnum = -1 );
void FreeFacelightDependencyList( void );
void CalcSampleSize( void );
void CalcLuxelsCount( void );
//
// vertexlight.c
//
void BuildVertexLights( void );
void VertexPatchLights( void );
void FinalLightVertex( void );
//
// model_lightmaps.c
//
void BuildModelLightmaps( void );
void CalcModelSampleSize( void );
void ScaleModelDirectLights( void );
void PrecompModelLightmapOffsets( void );
void FinalModelLightFace( void );
void FreeModelFaceLights( void );
void ReduceModelLightmap( byte *oldlightdata, byte *olddeluxdata, byte *oldshadowdata );
void WriteModelLighting( void );
//
// alias.c
//
void LoadAlias( entity_t *ent, void *buffer, long fileLength, int flags );
void AliasGetBounds( entity_t *ent, vec3_t mins, vec3_t maxs );
//
// studio.c
//
void LoadStudio( entity_t *ent, void *buffer, long fileLength, int flags );
void StudioGetBounds( entity_t *ent, vec3_t mins, vec3_t maxs );
//
// textures.c
//
void TEX_LoadTextures( void );
miptex_t *GetTextureByMiptex( int miptex );
void TEX_FreeTextures( void );
//
// trace.c
//
void InitWorldTrace( void );
int TestLine( int threadnum, const vec3_t start, const vec3_t end, bool nomodels = false, entity_t *ignoreent = NULL );
void TestLine( int threadnum, const vec3_t start, const vec3_t stop, trace_t *trace );
void FreeWorldTrace( void );
dleaf_t *PointInLeaf( const vec3_t point );
dleaf_t *PointInLeaf2( const vec3_t point );
dvertex_t *GetVertexByNumber( int vertexnum );