summaryrefslogtreecommitdiffstats
path: root/src/core/ZoneCull.h
blob: 10742ffb061c27d6b82ad130e1865f3d6a842c3d (plain) (blame)
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
class CEntity;

class CCullZone
{
public:
	CVector position;
	float minx;
	float maxx;
	float miny;
	float maxy;
	float minz;
	float maxz;

	int32 m_indexStart;
	int16 m_groupIndexCount[3];	// only useful during resolution stage
	int16 m_numBuildings;
	int16 m_numTreadablesPlus10m;
	int16 m_numTreadables;

	void DoStuffLeavingZone(void);
	static void DoStuffLeavingZone_OneBuilding(uint16 i);
	static void DoStuffLeavingZone_OneTreadableBoth(uint16 i);
	void DoStuffEnteringZone(void);
	static void DoStuffEnteringZone_OneBuilding(uint16 i);
	static void DoStuffEnteringZone_OneTreadablePlus10m(uint16 i);
	static void DoStuffEnteringZone_OneTreadable(uint16 i);


	static bool TestLine(CVector vec1, CVector vec2);
	static bool DoThoroughLineTest(CVector vec1, CVector vec2, CEntity *testEntity);
	float CalcDistToCullZoneSquared(float x, float y);
	float CalcDistToCullZone(float x, float y) { return Sqrt(CalcDistToCullZoneSquared(x, y)); };
	bool IsEntityCloseEnoughToZone(CEntity* entity, bool checkLevel);
	bool PointFallsWithinZone(CVector pos, float radius);
	bool TestEntityVisibilityFromCullZone(CEntity *entity, float extraDist, CEntity *LODentity);
	void FindTestPoints();

	void GetGroupStartAndSize(int32 groupid, int32 &start, int32 &size) {
		switch (groupid) {
		case 0:
		default:
			// buildings
			start = m_indexStart;
			size = m_groupIndexCount[0];
			break;
		case 1:
			// treadables + 10m
			start = m_groupIndexCount[0] + m_indexStart;
			size = m_groupIndexCount[1];
			break;
		case 2:
			// treadables
			start = m_groupIndexCount[0] + m_groupIndexCount[1] + m_indexStart;
			size = m_groupIndexCount[2];
			break;
		}
	}
};

enum eZoneAttribs
{
	ATTRZONE_CAMCLOSEIN		= 1,
	ATTRZONE_STAIRS			= 2,
	ATTRZONE_1STPERSON		= 4,
	ATTRZONE_NORAIN			= 8,
	ATTRZONE_NOPOLICE		= 0x10,
	ATTRZONE_NOTCULLZONE		= 0x20,
	ATTRZONE_DOINEEDCOLLISION	= 0x40,
	ATTRZONE_SUBWAYVISIBLE		= 0x80,
};

struct CAttributeZone
{
	float minx;
	float maxx;
	float miny;
	float maxy;
	float minz;
	float maxz;
	int16 attributes;
	int16 wantedLevel;
};

class CCullZones
{
public:
	static int32     NumCullZones;
	static CCullZone aZones[NUMCULLZONES];
	static int32     NumAttributeZones;
	static CAttributeZone aAttributeZones[NUMATTRIBZONES];
	static uint16        aIndices[NUMZONEINDICES];
	static int16         aPointersToBigBuildingsForBuildings[NUMBUILDINGS];
	static int16         aPointersToBigBuildingsForTreadables[NUMTREADABLES];

	static int32 CurrentWantedLevelDrop_Player;
	static int32 CurrentFlags_Camera;
	static int32 CurrentFlags_Player;
	static int32 OldCullZone;
	static int32 EntityIndicesUsed;
	static bool bCurrentSubwayIsInvisible;
	static bool bCullZonesDisabled;

	static void Init(void);
	static void ResolveVisibilities(void);
	static void Update(void);
	static void ForceCullZoneCoors(CVector coors);
	static int32 FindCullZoneForCoors(CVector coors);
	static int32 FindAttributesForCoors(CVector coors, int32 *wantedLevel);
	static CAttributeZone *FindZoneWithStairsAttributeForPlayer(void);
	static void MarkSubwayAsInvisible(bool visible);
	static void AddCullZone(CVector const &position,
		float minx, float maxx,
		float miny, float maxy,
		float minz, float maxz,
		uint16 flag, int16 wantedLevel);
	static bool CamCloseInForPlayer(void) { return (CurrentFlags_Player & ATTRZONE_CAMCLOSEIN) != 0; }
	static bool CamStairsForPlayer(void) { return (CurrentFlags_Player & ATTRZONE_STAIRS) != 0; }
	static bool Cam1stPersonForPlayer(void) { return (CurrentFlags_Player & ATTRZONE_1STPERSON) != 0; }
	static bool NoPolice(void) { return (CurrentFlags_Player & ATTRZONE_NOPOLICE) != 0; }
	static bool DoINeedToLoadCollision(void) { return (CurrentFlags_Player & ATTRZONE_DOINEEDCOLLISION) != 0; }
	static bool PlayerNoRain(void) { return (CurrentFlags_Player & ATTRZONE_NORAIN) != 0; }
	static bool CamNoRain(void) { return (CurrentFlags_Camera & ATTRZONE_NORAIN) != 0; }
	static int32 GetWantedLevelDrop(void) { return CurrentWantedLevelDrop_Player; }

	static void BuildListForBigBuildings();
	static void DoVisibilityTestCullZone(int zoneId, bool doIt);
	static bool DoWeHaveMoreThanXOccurencesOfSet(int32 count, uint16 *set);

	static void CompressIndicesArray();
	static bool PickRandomSetForGroup(int32 zone, int32 group, uint16 *set);
	static void ReplaceSetForAllGroups(uint16 *set, uint16 setid);
	static void TidyUpAndMergeLists(uint16 *extraIndices, int32 numExtraIndices);

	// debug
	static bool LoadTempFile(void);
	static void SaveTempFile(void);
};