forked from hitmen047/Source-PlusPlus
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathvrad.h
619 lines (485 loc) · 18.9 KB
/
vrad.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
//========= Copyright Valve Corporation, All rights reserved. ============//
//
// Purpose:
//
// $Workfile: $
// $Date: $
//
//-----------------------------------------------------------------------------
// $Log: $
//
// $NoKeywords: $
//=============================================================================//
#ifndef VRAD_H
#define VRAD_H
#pragma once
#include "commonmacros.h"
#include "worldsize.h"
#include "cmdlib.h"
#include "mathlib/mathlib.h"
#include "bsplib.h"
#include "polylib.h"
#include "threads.h"
#include "builddisp.h"
#include "VRAD_DispColl.h"
#include "UtlMemory.h"
#include "UtlHash.h"
#include "utlvector.h"
#include "iincremental.h"
#include "raytrace.h"
#ifdef _WIN32
#include <windows.h>
#endif
#include <sys/types.h>
#include <sys/stat.h>
#pragma warning(disable: 4142 4028)
#include <io.h>
#pragma warning(default: 4142 4028)
#include <fcntl.h>
#include <direct.h>
#include <ctype.h>
// Can remove these options if they don't generate problems.
//#define SAMPLEHASH_USE_AREA_PATCHES // Add patches to sample hash based on their AABB instead of as a single point.
#define SAMPLEHASH_QUERY_ONCE // Big optimization - causes way less sample hash queries.
extern float dispchop; // "-dispchop" tightest number of luxel widths for a patch, used on edges
extern float g_MaxDispPatchRadius;
//-----------------------------------------------------------------------------
// forward declarations
//-----------------------------------------------------------------------------
struct Ray_t;
#define TRANSFER_EPSILON 0.0000001
struct directlight_t
{
int index;
directlight_t *next;
dworldlight_t light;
byte *pvs; // accumulated domain of the light
int facenum; // domain of attached lights
int texdata; // texture source of traced lights
Vector snormal;
Vector tnormal;
float sscale;
float tscale;
float soffset;
float toffset;
int dorecalc; // position, vector, spot angle, etc.
IncrementalLightID m_IncrementalID;
// hard-falloff lights (lights that fade to an actual zero). between m_flStartFadeDistance and
// m_flEndFadeDistance, a smoothstep to zero will be done, so that the light goes to zero at
// the end.
float m_flStartFadeDistance;
float m_flEndFadeDistance;
float m_flCapDist; // max distance to feed in
directlight_t(void)
{
m_flEndFadeDistance = -1.0; // end<start indicates not set
m_flStartFadeDistance= 0.0;
m_flCapDist = 1.0e22;
}
};
struct bumplights_t
{
Vector light[NUM_BUMP_VECTS+1];
};
struct transfer_t
{
int patch;
float transfer;
};
struct LightingValue_t
{
Vector m_vecLighting;
float m_flDirectSunAmount;
FORCEINLINE bool IsValid( void ) const
{
return ( m_vecLighting.x >= 0 &&
m_vecLighting.y >= 0 &&
m_vecLighting.z >= 0 &&
m_vecLighting.x < 1e10 &&
m_vecLighting.y < 1e10 &&
m_vecLighting.z < 1e10 );
}
FORCEINLINE void Zero( void )
{
m_vecLighting.Init( 0, 0, 0 );
m_flDirectSunAmount = 0.0;
}
FORCEINLINE void Scale( float m_flScale )
{
m_vecLighting *= m_flScale;
m_flDirectSunAmount *= m_flScale;
}
FORCEINLINE void AddWeighted( LightingValue_t const &src, float flWeight )
{
m_vecLighting += flWeight * src.m_vecLighting;
m_flDirectSunAmount += flWeight * src.m_flDirectSunAmount;
}
FORCEINLINE void AddWeighted( Vector const &src, float flWeight )
{
m_vecLighting += flWeight * src;
}
FORCEINLINE float Intensity( void ) const
{
return m_vecLighting.x + m_vecLighting.y + m_vecLighting.z;
}
FORCEINLINE void AddLight( float flAmount, Vector const &vecColor, float flSunAmount = 0.0 )
{
VectorMA( m_vecLighting, flAmount, vecColor, m_vecLighting );
m_flDirectSunAmount += flSunAmount;
Assert( this->IsValid() );
}
FORCEINLINE void AddLight( LightingValue_t const &src )
{
m_vecLighting += src.m_vecLighting;
m_flDirectSunAmount += src.m_flDirectSunAmount;
Assert( this->IsValid() );
}
FORCEINLINE void Init( float x, float y, float z )
{
m_vecLighting.Init( x, y, z );
m_flDirectSunAmount = 0.0;
}
};
#define MAX_PATCHES (4*65536)
struct CPatch
{
winding_t *winding;
Vector mins, maxs, face_mins, face_maxs;
Vector origin; // adjusted off face by face normal
dplane_t *plane; // plane (corrected for facing)
unsigned short m_IterationKey; // Used to prevent touching the same patch multiple times in the same query.
// See IncrementPatchIterationKey().
// these are packed into one dword
unsigned int normalMajorAxis : 2; // the major axis of base face normal
unsigned int sky : 1;
unsigned int needsBumpmap : 1;
unsigned int pad : 28;
Vector normal; // adjusted for phong shading
float planeDist; // Fixes up patch planes for brush models with an origin brush
float chop; // smallest acceptable width of patch face
float luxscale; // average luxels per world coord
float scale[2]; // Scaling of texture in s & t
bumplights_t totallight; // accumulated by radiosity
// does NOT include light
// accounted for by direct lighting
Vector baselight; // emissivity only
float basearea; // surface per area per baselight instance
Vector directlight; // direct light value
float area;
Vector reflectivity; // Average RGB of texture, modified by material type.
Vector samplelight;
float samplearea; // for averaging direct light
int faceNumber;
int clusterNumber;
int parent; // patch index of parent
int child1; // patch index for children
int child2;
int ndxNext; // next patch index in face
int ndxNextParent; // next parent patch index in face
int ndxNextClusterChild; // next terminal child index in cluster
// struct patch_s *next; // next in face
// struct patch_s *nextparent; // next in face
// struct patch_s *nextclusterchild; // next terminal child in cluster
int numtransfers;
transfer_t *transfers;
short indices[3]; // displacement use these for subdivision
};
extern CUtlVector<CPatch> g_Patches;
extern CUtlVector<int> g_FacePatches; // constains all patches, children first
extern CUtlVector<int> faceParents; // contains only root patches, use next parent to iterate
extern CUtlVector<int> clusterChildren;
struct sky_camera_t
{
Vector origin;
float world_to_sky;
float sky_to_world;
int area;
};
extern int num_sky_cameras;
extern sky_camera_t sky_cameras[MAX_MAP_AREAS];
extern int area_sky_cameras[MAX_MAP_AREAS];
void ProcessSkyCameras();
extern entity_t *face_entity[MAX_MAP_FACES];
extern Vector face_offset[MAX_MAP_FACES]; // for rotating bmodels
extern Vector face_centroids[MAX_MAP_EDGES];
extern int leafparents[MAX_MAP_LEAFS];
extern int nodeparents[MAX_MAP_NODES];
extern float lightscale;
extern float dlight_threshold;
extern float coring;
extern qboolean g_bDumpPatches;
extern bool bRed2Black;
extern bool g_bNoSkyRecurse;
extern bool bDumpNormals;
extern bool g_bFastAmbient;
extern float maxchop;
extern FileHandle_t pFileSamples[4][4];
extern qboolean g_bLowPriority;
extern qboolean do_fast;
extern bool g_bInterrupt; // Was used with background lighting in WC. Tells VRAD to stop lighting.
extern IIncremental *g_pIncremental; // null if not doing incremental lighting
extern bool g_bDumpPropLightmaps;
extern bool g_bIgnoreModelVersions;
extern bool g_bAllowDynamicPropsAsStatic;
extern bool g_bAllowDX90VTX;
extern float g_flSkySampleScale; // extra sampling factor for indirect light
extern bool g_bLargeDispSampleRadius;
extern bool g_bStaticPropPolys;
extern bool g_bTextureShadows;
extern bool g_bShowStaticPropNormals;
extern bool g_bDisablePropSelfShadowing;
extern CUtlVector<char const *> g_NonShadowCastingMaterialStrings;
extern void ForceTextureShadowsOnModel( const char *pModelName );
extern bool IsModelTextureShadowsForced( const char *pModelName );
// Raytracing
#define TRACE_ID_SKY 0x01000000 // sky face ray blocker
#define TRACE_ID_OPAQUE 0x02000000 // everyday light blocking face
#define TRACE_ID_STATICPROP 0x04000000 // static prop - lower bits are prop ID
extern RayTracingEnvironment g_RtEnv;
#include "mpivrad.h"
void MakeShadowSplits (void);
//==============================================
void BuildVisMatrix (void);
void BuildClusterTable( void );
void AddDispsToClusterTable( void );
void FreeVisMatrix (void);
// qboolean CheckVisBit (unsigned int p1, unsigned int p2);
void TouchVMFFile (void);
//==============================================
extern qboolean do_extra;
extern qboolean do_fast;
extern qboolean do_centersamples;
extern int extrapasses;
extern Vector ambient;
extern float maxlight;
extern unsigned numbounce;
extern qboolean g_bLogHashData;
extern bool debug_extra;
extern directlight_t *activelights;
extern directlight_t *freelights;
// because of hdr having two face lumps (light styles can cause them to be different, among other
// things), we need to always access (r/w) face data though this pointer
extern dface_t *g_pFaces;
extern bool g_bMPIProps;
extern byte nodehit[MAX_MAP_NODES];
extern float gamma_value;
extern float indirect_sun;
extern float smoothing_threshold;
extern int dlight_map;
extern float g_flMaxDispSampleSize;
extern float g_SunAngularExtent;
extern char source[MAX_PATH];
// Used by incremental lighting to trivial-reject faces.
// There is a bit in here for each face telling whether or not any of the
// active lights can see the face.
extern CUtlVector<byte> g_FacesVisibleToLights;
void MakeTnodes (dmodel_t *bm);
void PairEdges (void);
void SaveVertexNormals( void );
qboolean IsIncremental(char *filename);
int SaveIncremental(char *filename);
int PartialHead (void);
void BuildFacelights (int facenum, int threadnum);
void PrecompLightmapOffsets();
void FinalLightFace (int threadnum, int facenum);
void PvsForOrigin (Vector& org, byte *pvs);
void ConvertRGBExp32ToRGBA8888( const ColorRGBExp32 *pSrc, unsigned char *pDst, Vector* _optOutLinear = NULL );
void ConvertRGBExp32ToLinear(const ColorRGBExp32 *pSrc, Vector* pDst);
void ConvertLinearToRGBA8888( const Vector *pSrc, unsigned char *pDst );
inline byte PVSCheck( const byte *pvs, int iCluster )
{
if ( iCluster >= 0 )
{
return pvs[iCluster >> 3] & ( 1 << ( iCluster & 7 ) );
}
else
{
// PointInLeaf still returns -1 for valid points sometimes and rather than
// have black samples, we assume the sample is in the PVS.
return 1;
}
}
// outputs 1 in fractionVisible if no occlusion, 0 if full occlusion, and in-between values
void TestLine( FourVectors const& start, FourVectors const& stop, fltx4 *pFractionVisible, int static_prop_index_to_ignore=-1);
void TestLine_IgnoreSky( FourVectors const& start, FourVectors const& stop, fltx4 *pFractionVisible, int static_prop_index_to_ignore = -1 );
// returns 1 if the ray sees the sky, 0 if it doesn't, and in-between values for partial coverage
void TestLine_DoesHitSky( FourVectors const& start, FourVectors const& stop,
fltx4 *pFractionVisible, bool canRecurse = true, int static_prop_to_skip=-1, bool bDoDebug = false );
// converts any marked brush entities to triangles for shadow casting
void ExtractBrushEntityShadowCasters ( void );
void AddBrushesForRayTrace ( void );
void BaseLightForFace( dface_t *f, Vector& light, float *parea, Vector& reflectivity );
void CreateDirectLights (void);
void GetPhongNormal( int facenum, Vector const& spot, Vector& phongnormal );
int LightForString( const char *pLight, Vector& intensity );
void MakeTransfer( int ndxPatch1, int ndxPatch2, transfer_t *all_transfers );
void MakeScales( int ndxPatch, transfer_t *all_transfers );
// Run startup code like initialize mathlib.
void VRAD_Init();
// Load the BSP file and prepare to do the lighting.
// This is called after any command-line parameters have been set.
void VRAD_LoadBSP( char const *pFilename );
int VRAD_Main(int argc, char **argv);
// This performs an actual lighting pass.
// Returns true if the process was interrupted (with g_bInterrupt).
bool RadWorld_Go();
dleaf_t *PointInLeaf (Vector const& point);
int ClusterFromPoint( Vector const& point );
winding_t *WindingFromFace (dface_t *f, Vector& origin );
void WriteWinding (FileHandle_t out, winding_t *w, Vector& color );
void WriteNormal( FileHandle_t out, Vector const &nPos, Vector const &nDir,
float length, Vector const &color );
void WriteLine( FileHandle_t out, const Vector &vecPos1, const Vector &vecPos2, const Vector &color );
void WriteTrace( const char *pFileName, const FourRays &rays, const RayTracingResult& result );
#ifdef STATIC_FOG
qboolean IsFog( dface_t * f );
#endif
#define CONTENTS_EMPTY 0
#define TEX_SPECIAL (SURF_SKY|SURF_NOLIGHT)
//=============================================================================
// trace.cpp
bool AddDispCollTreesToWorld( void );
int PointLeafnum( Vector const &point );
float TraceLeafBrushes( int leafIndex, const Vector &start, const Vector &end, CBaseTrace &traceOut );
//=============================================================================
// dispinfo.cpp
struct SSE_sampleLightOutput_t
{
fltx4 m_flDot[NUM_BUMP_VECTS+1];
fltx4 m_flFalloff;
fltx4 m_flSunAmount;
};
#define GATHERLFLAGS_FORCE_FAST 1
#define GATHERLFLAGS_IGNORE_NORMALS 2
// SSE Gather light stuff
void GatherSampleLightSSE( SSE_sampleLightOutput_t &out, directlight_t *dl, int facenum,
FourVectors const& pos, FourVectors *pNormals, int normalCount, int iThread,
int nLFlags = 0, // GATHERLFLAGS_xxx
int static_prop_to_skip=-1,
float flEpsilon = 0.0 );
//void GatherSampleSkyLightSSE( SSE_sampleLightOutput_t &out, directlight_t *dl, int facenum,
// FourVectors const& pos, FourVectors *pNormals, int normalCount, int iThread,
// int nLFlags = 0,
// int static_prop_to_skip=-1,
// float flEpsilon = 0.0 );
//void GatherSampleAmbientSkySSE( SSE_sampleLightOutput_t &out, directlight_t *dl, int facenum,
// FourVectors const& pos, FourVectors *pNormals, int normalCount, int iThread,
// int nLFlags = 0, // GATHERLFLAGS_xxx
// int static_prop_to_skip=-1,
// float flEpsilon = 0.0 );
//void GatherSampleStandardLightSSE( SSE_sampleLightOutput_t &out, directlight_t *dl, int facenum,
// FourVectors const& pos, FourVectors *pNormals, int normalCount, int iThread,
// int nLFlags = 0, // GATHERLFLAGS_xxx
// int static_prop_to_skip=-1,
// float flEpsilon = 0.0 );
//-----------------------------------------------------------------------------
// VRad Displacements
//-----------------------------------------------------------------------------
struct facelight_t;
typedef struct radial_s radial_t;
struct lightinfo_t;
// NOTE: should probably come up with a bsptreetested_t struct or something,
// see below (PropTested_t)
struct DispTested_t
{
int m_Enum;
int *m_pTested;
};
class IVRadDispMgr
{
public:
// creation/destruction
virtual void Init( void ) = 0;
virtual void Shutdown( void ) = 0;
// "CalcPoints"
virtual bool BuildDispSamples( lightinfo_t *pLightInfo, facelight_t *pFaceLight, int ndxFace ) = 0;
virtual bool BuildDispLuxels( lightinfo_t *pLightInfo, facelight_t *pFaceLight, int ndxFace ) = 0;
virtual bool BuildDispSamplesAndLuxels_DoFast( lightinfo_t *pLightInfo, facelight_t *pFaceLight, int ndxFace ) = 0;
// patching functions
virtual void MakePatches( void ) = 0;
virtual void SubdividePatch( int iPatch ) = 0;
// pre "FinalLightFace"
virtual void InsertSamplesDataIntoHashTable( void ) = 0;
virtual void InsertPatchSampleDataIntoHashTable( void ) = 0;
// "FinalLightFace"
virtual radial_t *BuildLuxelRadial( int ndxFace, int ndxStyle, bool bBump ) = 0;
virtual bool SampleRadial( int ndxFace, radial_t *pRadial, Vector const &vPos, int ndxLxl, LightingValue_t *pLightSample, int sampleCount, bool bPatch ) = 0;
virtual radial_t *BuildPatchRadial( int ndxFace, bool bBump ) = 0;
// utility
virtual void GetDispSurfNormal( int ndxFace, Vector &pt, Vector &ptNormal, bool bInside ) = 0;
virtual void GetDispSurf( int ndxFace, CVRADDispColl **ppDispTree ) = 0;
// bsp tree functions
virtual bool ClipRayToDisp( DispTested_t &dispTested, Ray_t const &ray ) = 0;
virtual bool ClipRayToDispInLeaf( DispTested_t &dispTested, Ray_t const &ray, int ndxLeaf ) = 0;
virtual void ClipRayToDispInLeaf( DispTested_t &dispTested, Ray_t const &ray,
int ndxLeaf, float& dist, dface_t*& pFace, Vector2D& luxelCoord ) = 0;
virtual void ClipRayToDispInLeaf( DispTested_t &dispTested, Ray_t const &ray,
int ndxLeaf, float& dist, Vector *pNormal ) = 0;
virtual void StartRayTest( DispTested_t &dispTested ) = 0;
virtual void AddPolysForRayTrace() = 0;
// general timing -- should be moved!!
virtual void StartTimer( const char *name ) = 0;
virtual void EndTimer( void ) = 0;
};
IVRadDispMgr *StaticDispMgr( void );
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
inline bool ValidDispFace( dface_t *pFace )
{
if( !pFace ) { return false; }
if( pFace->dispinfo == -1 ) { return false; }
if( pFace->numedges != 4 ) { return false; }
return true;
}
#define SAMPLEHASH_VOXEL_SIZE 64.0f
typedef unsigned int SampleHandle_t; // the upper 16 bits = facelight index (works because max face are 65536)
// the lower 16 bits = sample index inside of facelight
struct sample_t;
struct SampleData_t
{
unsigned short x, y, z;
CUtlVector<SampleHandle_t> m_Samples;
};
struct PatchSampleData_t
{
unsigned short x, y, z;
CUtlVector<int> m_ndxPatches;
};
UtlHashHandle_t SampleData_AddSample( sample_t *pSample, SampleHandle_t sampleHandle );
void PatchSampleData_AddSample( CPatch *pPatch, int ndxPatch );
unsigned short IncrementPatchIterationKey();
void SampleData_Log( void );
extern CUtlHash<SampleData_t> g_SampleHashTable;
extern CUtlHash<PatchSampleData_t> g_PatchSampleHashTable;
extern int samplesAdded;
extern int patchSamplesAdded;
//-----------------------------------------------------------------------------
// Computes lighting for the detail props
//-----------------------------------------------------------------------------
void ComputeDetailPropLighting( int iThread );
void ComputeIndirectLightingAtPoint( Vector &position, Vector &normal, Vector &outColor,
int iThread, bool force_fast = false, bool bIgnoreNormals = false );
//-----------------------------------------------------------------------------
// VRad static props
//-----------------------------------------------------------------------------
class IPhysicsCollision;
struct PropTested_t
{
int m_Enum;
int* m_pTested;
IPhysicsCollision *pThreadedCollision;
};
class IVradStaticPropMgr
{
public:
// methods of IStaticPropMgr
virtual void Init() = 0;
virtual void Shutdown() = 0;
virtual void ComputeLighting( int iThread ) = 0;
virtual void AddPolysForRayTrace() = 0;
};
//extern PropTested_t s_PropTested[MAX_TOOL_THREADS+1];
extern DispTested_t s_DispTested[MAX_TOOL_THREADS+1];
IVradStaticPropMgr* StaticPropMgr();
extern float ComputeCoverageFromTexture( float b0, float b1, float b2, int32 hitID );
#endif // VRAD_H