Coverage Report

Created: 2025-08-29 06:18

/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