summaryrefslogtreecommitdiff
path: root/Runtime/Camera/LODGroupManager.h
blob: 7623b6368a1639fdfce5cc0a98720393073c9131 (plain)
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
#pragma once

#include "Runtime/Math/Vector3.h"
#include "Runtime/Utilities/dynamic_array.h"
#include "Runtime/Utilities/BitUtility.h"

class LODGroup;
struct CullingParameters;

enum
{
	kMaximumLODLevels = 8,
	kInvalidLODGroup = -1,

	// When an LOD group is disabled, we want to make all renderers be disabled.
	// For this purpose we have a single shared LODGroup index, with a mask that has all renderers always disabled.
	kDisabledLODGroup = 0 
};

#if UNITY_EDITOR
// LOD Visualization 
// (NOTE: Keep LODUtilityBindings.txt struct in sync)
struct LODVisualizationInformation
{
	int    triangleCount;
	int    vertexCount;
	int    rendererCount;
	int    submeshCount;
	
	int    activeLODLevel;
	float  activeLODFade;
	float  activeDistance;
	float  activeRelativeScreenSize;
	float  activePixelSize;
	float  activeWorldSpaceSize;
};
#endif

class LODGroupManager
{
	struct LODSelectionData
	{
		// The point we measure the LOD distance against
		Vector3f  worldReferencePoint;
		float     maxDistanceSqr;
		
		// LOD maximum distance values
		float     maxDistances[kMaximumLODLevels];
		int       maxDistancesCount;
		float     fadeDistance;
		
		// The associated lod group
		LODGroup* lodGroup; 
		
		UInt32     forceLODLevelMask;
	};
	
	dynamic_array<LODSelectionData>  m_SelectionData;
	float                            m_LODBias;
	UInt32                           m_MaximumLOD;
	
public:
	
	LODGroupManager (); 
	
	void   AddLODGroup (LODGroup& group, const Vector3f& position, float worldSpaceSize);
	void   RemoveLODGroup (LODGroup& group);
	
	void   UpdateLODGroupParameters (int index, LODGroup& group, const Vector3f& position, float worldSpaceSize);
	void   UpdateLODGroupPosition (int index, const Vector3f& position) { m_SelectionData[index].worldReferencePoint = position; }
	
	void   SetLODBias (float b)                                         { m_LODBias = b; }
	float  GetLODBias () const                                          { return m_LODBias; }
	
	void   SetMaximumLODLevel (UInt32 b)                                { m_MaximumLOD = b; }
	UInt32 GetMaximumLODLevel () const                                  { return m_MaximumLOD; }
	
	void   ResetLODBias ()                                              { SetLODBias(1.0F); }

	int    GetLODGroupCount () const                                    { return m_SelectionData.size(); }
	
	
	// Used by scene culling to determine 
	// /lodGroupIndex/ is the index of LODGroup into m_SelectionData & m_ActiveLOD
	// /activeLODMask/ is the LOD mask of the renderer. 
	// m_ActiveLOD[lodGroupIndex].activeMask is a bitmask specifying which LOD levels should be rendered.
	// When cross-fading between two LOD's multiple LOD's might be active in the same LODGroup
	static bool IsLODVisible (UInt32 lodGroupIndex, UInt32 activeLODMask, const UInt8* activeLOD)
	{
		if (activeLODMask == 0)
			return true;
		
		return activeLOD[lodGroupIndex] & activeLODMask;
	}

	void CalculateLODMasks (const CullingParameters& parameters, UInt8* outMasks, float* outFades);
	static float CalculateLODFade (UInt32 lodGroupIndex, UInt32 rendererActiveLODMask, const UInt8* lodMasks, const float* lodFades);
	
	static void CalculatePerspectiveLODMask (const LODSelectionData& selection, const Vector3f& position, int maximumLOD, int currentMask, const float* fieldOfViewFudge, UInt8* output, float* outputFade);
	static void CalculateOrthoLODMask (const LODSelectionData& selection, int maximumLOD, int currentMask, const float* fudge, UInt8* output, float* outputFade);

#if UNITY_EDITOR
	LODVisualizationInformation CalculateVisualizationData (const CullingParameters& cullingParameters, LODGroup& lodGroup, int lod);
	
#endif

	void   SetForceLODMask (int index, UInt32 forceEditorLODMask)     { m_SelectionData[index].forceLODLevelMask = forceEditorLODMask; }
	UInt32 GetForceLODMask (int index)                               { return m_SelectionData[index].forceLODLevelMask; }
	void   ClearAllForceLODMask ();

};

LODGroupManager* GetLODGroupManagerPtr ();
LODGroupManager& GetLODGroupManager ();
void CleanupLODGroupManager ();
void InitializeLODGroupManager ();