/src/ogre/PlugIns/BSPSceneManager/include/OgreBspLevel.h
Line | Count | Source (jump to first uncovered line) |
1 | | /* |
2 | | ----------------------------------------------------------------------------- |
3 | | This source file is part of OGRE |
4 | | (Object-oriented Graphics Rendering Engine) |
5 | | For the latest info, see http://www.ogre3d.org/ |
6 | | |
7 | | Copyright (c) 2000-2014 Torus Knot Software Ltd |
8 | | |
9 | | Permission is hereby granted, free of charge, to any person obtaining a copy |
10 | | of this software and associated documentation files (the "Software"), to deal |
11 | | in the Software without restriction, including without limitation the rights |
12 | | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell |
13 | | copies of the Software, and to permit persons to whom the Software is |
14 | | furnished to do so, subject to the following conditions: |
15 | | |
16 | | The above copyright notice and this permission notice shall be included in |
17 | | all copies or substantial portions of the Software. |
18 | | |
19 | | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |
20 | | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
21 | | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE |
22 | | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER |
23 | | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, |
24 | | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN |
25 | | THE SOFTWARE. |
26 | | ----------------------------------------------------------------------------- |
27 | | */ |
28 | | #ifndef _BspLevel_H__ |
29 | | #define _BspLevel_H__ |
30 | | |
31 | | #include "OgreBspPrerequisites.h" |
32 | | #include "OgreResource.h" |
33 | | #include "OgreStaticFaceGroup.h" |
34 | | #include "OgreSceneManager.h" |
35 | | #include "OgreBspNode.h" |
36 | | #include "OgreHardwareBufferManager.h" |
37 | | #include "OgreDefaultHardwareBufferManager.h" |
38 | | #include "OgreQuake3Level.h" |
39 | | |
40 | | |
41 | | namespace Ogre { |
42 | | /** \addtogroup Plugins Plugins |
43 | | * @{ |
44 | | */ |
45 | | /** \defgroup BSPSceneManager BSPSceneManager |
46 | | * Binary Space Parition (BSP) based indoor level scene manager |
47 | | * @{ |
48 | | */ |
49 | | |
50 | | /** Holds all the data associated with a Binary Space Parition |
51 | | (BSP) based indoor level. |
52 | | The data used here is populated by loading level files via |
53 | | the BspLevelManager::load method, although application users |
54 | | are more likely to call SceneManager::setWorldGeometry which will |
55 | | automatically arrange the loading of the level. Note that this assumes |
56 | | that you have asked for an indoor-specialised SceneManager (specify |
57 | | ST_INDOOR when calling Root::getSceneManager). |
58 | | Ogre currently only supports loading from Quake3 Arena level files, |
59 | | although any source that can be converted into this classes structure |
60 | | could also be used. The Quake3 level load process is in a different |
61 | | class called Quake3Level to keep the specifics separate. |
62 | | */ |
63 | | class BspLevel : public Resource, public Renderable |
64 | | { |
65 | | friend class BspSceneManager; |
66 | | |
67 | | using Resource::load; |
68 | | public: |
69 | | /** Default constructor - used by BspResourceManager (do not call directly) */ |
70 | | BspLevel(ResourceManager* creator, const String& name, ResourceHandle handle, |
71 | | const String& group, bool isManual = false, ManualResourceLoader* loader = 0); |
72 | | ~BspLevel(); |
73 | | |
74 | | /** Determines if one leaf node is visible from another. */ |
75 | | bool isLeafVisible(const BspNode* from, const BspNode* to) const; |
76 | | |
77 | | /** Returns a pointer to the root node (BspNode) of the BSP tree. */ |
78 | | const BspNode* getRootNode(void); |
79 | | |
80 | | /** Walks the entire BSP tree and returns the leaf |
81 | | which contains the given point. |
82 | | */ |
83 | | BspNode* findLeaf(const Vector3& point) const; |
84 | | |
85 | | /** Ensures that the MovableObject is attached to the right leaves of the |
86 | | BSP tree. |
87 | | */ |
88 | | void _notifyObjectMoved(const MovableObject* mov, |
89 | | const Vector3& pos); |
90 | | /** Internal method, makes sure an object is removed from the leaves when detached from a node. */ |
91 | | void _notifyObjectDetached(const MovableObject* mov); |
92 | | /** Gets a pointer to the start of the leaf nodes. */ |
93 | 0 | BspNode* getLeafStart(void) {return &mRootNode[mLeafStart]; } |
94 | | /** Gets the number of leaf nodes */ |
95 | 0 | int getNumLeaves(void) const { return mNumLeaves; } |
96 | | |
97 | | /** Calculate the number of loading stages required for a given level */ |
98 | | static size_t calculateLoadingStages(const String& levelName); |
99 | | /** Calculate the number of loading stages required for a given level */ |
100 | | static size_t calculateLoadingStages(DataStreamPtr& stream); |
101 | | |
102 | | /** Load direct from stream */ |
103 | | void load(const DataStreamPtr& stream); |
104 | | |
105 | | /** Is sky enabled? */ |
106 | | bool isSkyEnabled(void) const; |
107 | | /** Get Sky material name */ |
108 | | const String& getSkyMaterialName(void) const; |
109 | | /** Get sky curvature */ |
110 | | Real getSkyCurvature(void) const; |
111 | | |
112 | | void getRenderOperation(RenderOperation &op) override |
113 | 0 | { |
114 | 0 | op = mRenderOp; |
115 | 0 | } |
116 | | |
117 | | void getWorldTransforms(Matrix4* xform) const override |
118 | 0 | { |
119 | 0 | *xform = Matrix4::IDENTITY; |
120 | 0 | } |
121 | | |
122 | | Real getSquaredViewDepth(const Camera *cam) const override |
123 | 0 | { |
124 | | // always visible |
125 | 0 | return -1; |
126 | 0 | } |
127 | | |
128 | | const LightList& getLights() const override |
129 | 0 | { |
130 | 0 | static LightList lights; |
131 | 0 | return lights; |
132 | 0 | } |
133 | | |
134 | | const MaterialPtr& getMaterial(void) const override |
135 | 0 | { |
136 | 0 | static MaterialPtr nullPtr; |
137 | 0 | return nullPtr; |
138 | 0 | } |
139 | | |
140 | | /** Utility class just to enable queueing of patches */ |
141 | | protected: |
142 | | /** Caches a face group for imminent rendering. */ |
143 | | uint32 cacheGeometry(uint32* pIndexes, const StaticFaceGroup* faceGroup); |
144 | | bool cacheGeometry(const std::vector<StaticFaceGroup*>& materialFaceGroup); |
145 | | |
146 | | /** @copydoc Resource::loadImpl. */ |
147 | | void loadImpl(void) override; |
148 | | /** @copydoc Resource::unloadImpl. */ |
149 | | void unloadImpl(void) override; |
150 | | /** @copydoc Resource::calculateSize. */ |
151 | | size_t calculateSize(void) const override; |
152 | | /** Pointer to the root node of the BSP tree; |
153 | | This pointer actually has a dual purpose; to avoid allocating lots of small chunks of |
154 | | memory, the BspLevel actually allocates all nodes required through this pointer. So this |
155 | | pointer is the handle for the allocation of memory for all nodes. It also happens to point |
156 | | to the root node, since the first one in the memory chunk is the root node. |
157 | | */ |
158 | | BspNode* mRootNode; |
159 | | int mNumNodes; |
160 | | int mNumLeaves; |
161 | | int mNumBrushes; |
162 | | int mLeafStart; /// The index at which leaf nodes begin |
163 | | |
164 | | /** Vertex format for fixed geometry. |
165 | | Note that in this case vertex components (position, normal, texture coords etc) |
166 | | are held interleaved in the same buffer. However, the format here is different from |
167 | | the format used by Quake because older Direct3d drivers like the vertex elements |
168 | | to be in a particular order within the buffer. See VertexDeclaration for full |
169 | | details of this marvellous(not) feature. |
170 | | */ |
171 | | struct BspVertex |
172 | | { |
173 | | float position[3]; |
174 | | float normal[3]; |
175 | | int colour; |
176 | | float texcoords[2]; |
177 | | float lightmap[2]; |
178 | | }; |
179 | | |
180 | | /// Vertex data holding all the data for the level, but able to render parts of it |
181 | | RenderOperation mRenderOp; |
182 | | |
183 | | /** Array of indexes into the mFaceGroups array. This buffer is organised |
184 | | by leaf node so leaves can just use contiguous chunks of it and |
185 | | get repointed to the actual entries in mFaceGroups. */ |
186 | | int* mLeafFaceGroups; |
187 | | int mNumLeafFaceGroups; |
188 | | |
189 | | /** Array of face groups, indexed into by contents of mLeafFaceGroups. */ |
190 | | StaticFaceGroup* mFaceGroups; |
191 | | int mNumFaceGroups; |
192 | | |
193 | | /// Indexes for the whole level, will be copied to the real indexdata per frame |
194 | | HardwareIndexBufferSharedPtr mIndexes; |
195 | | |
196 | | /// Brushes as used for collision, main memory is here |
197 | | BspNode::Brush *mBrushes; |
198 | | |
199 | | /** Vector of player start points */ |
200 | | std::vector<ViewPoint> mPlayerStarts; |
201 | | |
202 | | /** Internal utility function for loading data from Quake3. */ |
203 | | void loadQuake3Level(const Quake3Level& q3lvl); |
204 | | /** Internal lookup table to determine visibility between leaves. |
205 | | Leaf nodes are assigned to 'clusters' of nodes, which are used to group nodes together for |
206 | | visibility testing. This data holds a lookup table which is used to determine if one cluster of leaves |
207 | | is visible from another cluster. Whilst it would be possible to expand all this out so that |
208 | | each node had a list of pointers to other visible nodes, this would be very expensive in terms |
209 | | of storage (using the cluster method there is a table which is 1-bit squared per cluster, rounded |
210 | | up to the nearest byte obviously, which uses far less space than 4-bytes per linked node per source |
211 | | node). Of course the limitation here is that you have to each leaf in turn to determine if it is visible |
212 | | rather than just following a list, but since this is only done once per frame this is not such a big |
213 | | overhead. |
214 | | Each row in the table is a 'from' cluster, with each bit in the row corresponding to a 'to' cluster, |
215 | | both ordered based on cluster index. A 0 in the bit indicates the 'to' cluster is not visible from the |
216 | | 'from' cluster, whilst a 1 indicates it is. |
217 | | As many will notice, this is lifted directly from the Quake implementation of PVS. |
218 | | */ |
219 | | struct VisData |
220 | | { |
221 | | unsigned char *tableData; |
222 | | int numClusters; /// Number of clusters, therefore number of rows |
223 | | int rowLength; /// Length in bytes of each row (num clusters / 8 rounded up) |
224 | | }; |
225 | | |
226 | | VisData mVisData; |
227 | | |
228 | | |
229 | | /** Internal method for parsing chosen entities. */ |
230 | | void loadEntities(const Quake3Level& q3lvl); |
231 | | |
232 | | typedef std::map<const MovableObject*, std::list<BspNode*> > MovableToNodeMap; |
233 | | /// Map for locating the nodes a movable is currently a member of |
234 | | MovableToNodeMap mMovableToNodeMap; |
235 | | |
236 | | void tagNodesWithMovable(BspNode* node, const MovableObject* mov, const Vector3& pos); |
237 | | |
238 | | /// Storage of patches |
239 | | typedef std::map<int, PatchSurface*> PatchMap; |
240 | | PatchMap mPatches; |
241 | | /// Total number of vertices required for all patches |
242 | | size_t mPatchVertexCount; |
243 | | /// Total number of indexes required for all patches |
244 | | size_t mPatchIndexCount; |
245 | | /// Sky enabled? |
246 | | bool mSkyEnabled; |
247 | | /// Sky material |
248 | | String mSkyMaterial; |
249 | | /// Sky details |
250 | | Real mSkyCurvature; |
251 | | |
252 | | |
253 | | void initQuake3Patches(const Quake3Level & q3lvl, VertexDeclaration* decl); |
254 | | void buildQuake3Patches(size_t vertOffset, size_t indexOffset); |
255 | | |
256 | | void quakeVertexToBspVertex(const bsp_vertex_t* src, BspVertex* dest); |
257 | | |
258 | | |
259 | | }; |
260 | | typedef SharedPtr<BspLevel> BspLevelPtr; |
261 | | /** @} */ |
262 | | /** @} */ |
263 | | } |
264 | | |
265 | | #endif |