summaryrefslogtreecommitdiff
path: root/indra/newview/llspatialpartition.h
blob: 012e3a9e82b32ffd327c542914f562a978ea455b (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
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
/** 
 * @file llspatialpartition.h
 * @brief LLSpatialGroup header file including definitions for supporting functions
 *
 * Copyright (c) 2003-$CurrentYear$, Linden Research, Inc.
 * $License$
 */

#ifndef LL_LLSPATIALPARTITION_H
#define LL_LLSPATIALPARTITION_H

#define SG_MIN_DIST_RATIO 0.00001f

#include "llmemory.h"
#include "lldrawable.h"
#include "lloctree.h"
#include "llgltypes.h"

#include <queue>

class LLCullInfo
{
public:
	LLVector3 mPos;
	F32 mRadius;
	LLPointer<LLDrawable> mDrawablep;
};

#define SG_STATE_INHERIT_MASK (CULLED | OCCLUDED)
class LLSpatialPartition;

class LLSpatialGroup : public LLOctreeListener<LLDrawable>
{
	friend class LLSpatialPartition;
public:

	typedef LLOctreeListener<LLDrawable>	BaseType;
	typedef LLOctreeListener<LLDrawable>	OctreeListener;
	typedef LLTreeNode<LLDrawable>			TreeNode;
	typedef LLOctreeNode<LLDrawable>		OctreeNode;
	typedef LLOctreeRoot<LLDrawable>		OctreeRoot;
	typedef LLOctreeState<LLDrawable>		OctreeState;
	typedef LLOctreeTraveler<LLDrawable>	OctreeTraveler;

	typedef enum
	{
		IN_QUEUE				= 0x00000001,
		QUERY_PENDING			= 0x00000002,
		CULLED					= 0x00000004,
		OCCLUDED				= 0x00000008,
		DEAD					= 0x00000010,
		ACTIVE_OCCLUSION		= 0x00000020,
		EARLY_FAIL				= 0x00000040,
		DEACTIVATE_OCCLUSION	= 0x00000080,
		RESHADOW				= 0x00000100,
		RESHADOW_QUEUE			= 0x00000200,
		DIRTY					= 0x00000400,
		OBJECT_DIRTY			= 0x00000800,
		DISCARD_QUERY			= 0x00001000,
		QUERY_OUT				= 0x00002000,
		OCCLUDING				= 0x00004000,
		SKIP_FRUSTUM_CHECK		= 0x00008000,
	} eSpatialState;

	typedef enum
	{
		STATE_MODE_SINGLE = 0,		//set one node
		STATE_MODE_BRANCH,			//set entire branch
		STATE_MODE_DIFF				//set entire branch as long as current state is different
	} eSetStateMode;

	LLSpatialGroup(OctreeNode* node, LLSpatialPartition* part);
	BOOL safeToDelete();
	virtual ~LLSpatialGroup();

	S32 getCount() const					{ return mObjects.size(); }
	BOOL isDead()							{ return isState(DEAD); }
	BOOL isState(U32 state) const			{ return mState & state ? TRUE : FALSE; }
	U32 getState()							{ return mState; }
	void setState(U32 state)				{ mState |= state; }
	void clearState(U32 state)				{ mState &= ~state; }
	
	void validate();

	void setState(U32 state, S32 mode);


	void clearState(U32 state, S32 mode);
	BOOL addObject(LLDrawable *drawablep, BOOL add_all = FALSE, BOOL from_octree = FALSE);
	BOOL removeObject(LLDrawable *drawablep, BOOL from_octree = FALSE);
	BOOL updateInGroup(LLDrawable *drawablep, BOOL immediate = FALSE); // Update position if it's in the group
	BOOL isVisible();
	void shift(const LLVector3 &offset);
	BOOL boundObjects(BOOL empty, LLVector3& newMin, LLVector3& newMax);
	void unbound();
	BOOL rebound();
	BOOL changeLOD();
		
	 //LISTENER FUNCTIONS
	virtual void handleInsertion(const TreeNode* node, LLDrawable* face);
	virtual void handleRemoval(const TreeNode* node, LLDrawable* face);
	virtual void handleDestruction(const TreeNode* node);
	virtual void handleStateChange(const TreeNode* node);
	virtual void handleChildAddition(const OctreeNode* parent, OctreeNode* child);
	virtual void handleChildRemoval(const OctreeNode* parent, const OctreeNode* child);

protected:
	std::vector<LLCullInfo> mObjects;
	U32 mState;
	S32 mLODHash;
	static S32 sLODSeed;

public:
	OctreeNode* mOctreeNode;
	LLSpatialPartition* mSpatialPartition;
	LLVector3 mBounds[2];
	LLVector3 mExtents[2];
	LLVector3 mObjectExtents[2];
	LLVector3 mObjectBounds[2];

};

class LLSpatialPartition
{
public:
	LLSpatialPartition();
	virtual ~LLSpatialPartition();

	LLSpatialGroup *put(LLDrawable *drawablep);
	BOOL remove(LLDrawable *drawablep, LLSpatialGroup *curp);
	
	LLDrawable*	pickDrawable(const LLVector3& start, const LLVector3& end, LLVector3& collision);
	
	// If the drawable moves, move it here.
	virtual void move(LLDrawable *drawablep, LLSpatialGroup *curp, BOOL immediate = FALSE);
	void shift(const LLVector3 &offset);

	S32 cull(LLCamera &camera, std::vector<LLDrawable *>* results = NULL, BOOL for_select = FALSE); // Cull on arbitrary frustum
	BOOL checkOcclusion(LLSpatialGroup* group, LLCamera* camera);
	void processOcclusion(LLCamera* camera);
	void doOcclusion(LLCamera* camera);
	BOOL isVisible(const LLVector3& v);
	
	S32 getObjects(const LLVector3& pos,  F32 rad,  LLDrawable::drawable_set_t &results );
	S32 getLights(const LLVector3& pos,  F32 rad,  LLDrawable::drawable_set_t &results );
	
	void renderDebug();
	void restoreGL();
	
protected:
	S32 getDrawables(const LLVector3& pos,  F32 rad,  LLDrawable::drawable_set_t &results, BOOL get_lights );
	
	LLSpatialGroup *mLastAddedGroupp;

	typedef std::set<LLSpatialGroup*> spatial_group_set_t;
	spatial_group_set_t mSpatialGroups;

	//things that might be occluded
	std::queue<LLSpatialGroup*> mOcclusionQueue;

	//things awaiting query
	std::queue<LLSpatialGroup*> mQueryQueue;

	std::vector<LLGLuint> mOcclusionQueries;	

public:
	LLSpatialGroup::OctreeNode* mOctree;

	//things that are occluded
	std::vector<LLSpatialGroup*> mOccludedList;

	std::queue<LLSpatialGroup*> mReshadowQueue;

};

// class for creating bridges between spatial partitions
class LLSpatialBridge : public LLDrawable, public LLSpatialPartition
{
public:
	LLSpatialBridge(LLDrawable* root);
	virtual ~LLSpatialBridge();
	
	virtual BOOL		isSpatialBridge() const		{ return TRUE; }

	virtual void updateSpatialExtents();
	virtual void updateBinRadius();
	virtual void setVisible(LLCamera& camera_in, std::vector<LLDrawable*>* results = NULL, BOOL for_select = FALSE);
	virtual void updateDistance(LLCamera& camera_in);
	virtual void makeActive();
	virtual void makeStatic();
	virtual void move(LLDrawable *drawablep, LLSpatialGroup *curp, BOOL immediate = FALSE);
	virtual BOOL updateMove();
	virtual void shiftPos(const LLVector3& vec);
	virtual void cleanupReferences();
	virtual LLSpatialPartition* asPartition()		{ return this; }
	LLCamera transformCamera(LLCamera& camera);
	
	LLDrawable* mDrawable;
};

extern const F32 SG_BOX_SIDE;
extern const F32 SG_BOX_OFFSET;
extern const F32 SG_BOX_RAD;

extern const F32 SG_OBJ_SIDE;
extern const F32 SG_MAX_OBJ_RAD;

#endif //LL_LLSPATIALPARTITION_H