Coverage Report

Created: 2025-08-25 06:44

/src/ogre/OgreMain/include/OgreBillboardChain.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
29
// Thanks to Vincent Cantin (karmaGfa) for the original implementation of this
30
// class, although it has now been mostly rewritten
31
32
#ifndef _BillboardChain_H__
33
#define _BillboardChain_H__
34
35
#include "OgrePrerequisites.h"
36
37
#include "OgreMovableObject.h"
38
#include "OgreRenderable.h"
39
#include "OgreResourceGroupManager.h"
40
#include "OgreHeaderPrefix.h"
41
42
namespace Ogre {
43
44
    /** \addtogroup Core
45
    *  @{
46
    */
47
    /** \addtogroup Effects
48
    *  @{
49
    */
50
51
    /** Allows the rendering of a chain of connected billboards.
52
53
        A billboard chain operates much like a traditional billboard, i.e. its
54
        segments always face the camera; the difference being that instead of
55
        a set of disconnected quads, the elements in this class are connected
56
        together in a chain which must always stay in a continuous strip. This
57
        kind of effect is useful for creating effects such as trails, beams,
58
        lightning effects, etc.
59
    @par
60
        A single instance of this class can actually render multiple separate
61
        chain segments in a single render operation, provided they all use the
62
        same material. To clarify the terminology: a 'segment' is a separate 
63
        sub-part of the chain with its own start and end (called the 'head'
64
        and the 'tail'). An 'element' is a single position / colour / texcoord
65
        entry in a segment. You can add items to the head of a chain, and 
66
        remove them from the tail, very efficiently. Each segment has a max
67
        size, and if adding an element to the segment would exceed this size, 
68
        the tail element is automatically removed and re-used as the new item
69
        on the head.
70
    @par
71
        This class has no auto-updating features to do things like alter the
72
        colour of the elements or to automatically add / remove elements over
73
        time - you have to do all this yourself as a user of the class. 
74
        Subclasses can however be used to provide this kind of behaviour 
75
        automatically. @see RibbonTrail
76
    */
77
    class _OgreExport BillboardChain : public MovableObject, public Renderable
78
    {
79
0
        bool getCastsShadows(void) const override { return getCastShadows(); }
80
    public:
81
82
        /** Contains the data of an element of the BillboardChain.
83
        */
84
        class _OgreExport Element
85
        {
86
87
        public:
88
0
            Element() {}
89
90
            Element(const Vector3& position, float width, float texCoord, const ColourValue& colour,
91
                    const Quaternion& orientation);
92
93
            Vector3 position;
94
            float width;
95
            /// U or V texture coord depending on options
96
            float texCoord;
97
            ColourValue colour;
98
            /// Only used when mFaceCamera == false
99
            Quaternion orientation;
100
        };
101
102
        /** Constructor (don't use directly, use factory) 
103
        @param name The name to give this object
104
        @param maxElements The maximum number of elements per chain
105
        @param numberOfChains The number of separate chain segments contained in this object
106
        @param useTextureCoords If true, use texture coordinates from the chain elements
107
        @param useColours If true, use vertex colours from the chain elements
108
        @param dynamic If true, buffers are created with the intention of being updated
109
        */
110
        BillboardChain(const String& name, size_t maxElements = 20, size_t numberOfChains = 1, 
111
            bool useTextureCoords = true, bool useColours = true, bool dynamic = true);
112
113
        ~BillboardChain();
114
115
        /** Set the maximum number of chain elements per chain 
116
        */
117
        virtual void setMaxChainElements(size_t maxElements);
118
        /** Get the maximum number of chain elements per chain 
119
        */
120
0
        virtual size_t getMaxChainElements(void) const { return mMaxElementsPerChain; }
121
        /** Set the number of chain segments (this class can render multiple chains
122
            at once using the same material). 
123
        */
124
        virtual void setNumberOfChains(size_t numChains);
125
        /** Get the number of chain segments (this class can render multiple chains
126
        at once using the same material). 
127
        */
128
0
        virtual size_t getNumberOfChains(void) const { return mChainCount; }
129
130
        /** Sets whether texture coordinate information should be included in the
131
            final buffers generated.
132
        @note You must use either texture coordinates or vertex colour since the
133
            vertices have no normals and without one of these there is no source of
134
            colour for the vertices.
135
        */
136
        virtual void setUseTextureCoords(bool use);
137
        /** Gets whether texture coordinate information should be included in the
138
            final buffers generated.
139
        */
140
0
        virtual bool getUseTextureCoords(void) const { return mUseTexCoords; }
141
142
        /** The direction in which texture coordinates from elements of the
143
            chain are used.
144
        */
145
        enum TexCoordDirection
146
        {
147
            /// Tex coord in elements is treated as the 'u' texture coordinate
148
            TCD_U,
149
            /// Tex coord in elements is treated as the 'v' texture coordinate
150
            TCD_V
151
        };
152
        /** Sets the direction in which texture coords specified on each element
153
            are deemed to run along the length of the chain.
154
        @param dir The direction, default is TCD_U.
155
        */
156
        virtual void setTextureCoordDirection(TexCoordDirection dir);
157
        /** Gets the direction in which texture coords specified on each element
158
            are deemed to run.
159
        */
160
0
        virtual TexCoordDirection getTextureCoordDirection(void) { return mTexCoordDir; }
161
162
        /** Set the range of the texture coordinates generated across the width of
163
            the chain elements.
164
        @param start Start coordinate, default 0.0
165
        @param end End coordinate, default 1.0
166
        */
167
        virtual void setOtherTextureCoordRange(Real start, Real end);
168
        /** Get the range of the texture coordinates generated across the width of
169
            the chain elements.
170
        */
171
0
        virtual const Real* getOtherTextureCoordRange(void) const { return mOtherTexCoordRange; }
172
173
        /** Sets whether vertex colour information should be included in the
174
            final buffers generated.
175
        @note You must use either texture coordinates or vertex colour since the
176
            vertices have no normals and without one of these there is no source of
177
            colour for the vertices.
178
        */
179
        virtual void setUseVertexColours(bool use);
180
        /** Gets whether vertex colour information should be included in the
181
            final buffers generated.
182
        */
183
0
        virtual bool getUseVertexColours(void) const { return mUseVertexColour; }
184
185
        /** Set the auto update state
186
187
            @copydetails BillboardSet::setAutoUpdate
188
        */
189
        void setAutoUpdate(bool autoUpdate);
190
191
        /** Return the auto update state */
192
0
        bool getAutoUpdate(void) const { return mAutoUpdate; }
193
        
194
        /** Add an element to the 'head' of a chain.
195
196
            If this causes the number of elements to exceed the maximum elements
197
            per chain, the last element in the chain (the 'tail') will be removed
198
            to allow the additional element to be added.
199
        @param chainIndex The index of the chain
200
        @param billboardChainElement The details to add
201
        */
202
        virtual void addChainElement(size_t chainIndex, 
203
            const Element& billboardChainElement);
204
        /** Remove an element from the 'tail' of a chain.
205
        @param chainIndex The index of the chain
206
        */
207
        virtual void removeChainElement(size_t chainIndex);
208
        /** Update the details of an existing chain element.
209
        @param chainIndex The index of the chain
210
        @param elementIndex The element index within the chain, measured from 
211
            the 'head' of the chain
212
        @param billboardChainElement The details to set
213
        */
214
        virtual void updateChainElement(size_t chainIndex, size_t elementIndex, 
215
            const Element& billboardChainElement);
216
        /** Get the detail of a chain element.
217
        @param chainIndex The index of the chain
218
        @param elementIndex The element index within the chain, measured from
219
            the 'head' of the chain
220
        */
221
        virtual const Element& getChainElement(size_t chainIndex, size_t elementIndex) const;
222
223
        /** Returns the number of chain elements. */
224
        virtual size_t getNumChainElements(size_t chainIndex) const;
225
226
        /** Remove all elements of a given chain (but leave the chain intact). */
227
        virtual void clearChain(size_t chainIndex);
228
        /** Remove all elements from all chains (but leave the chains themselves intact). */
229
        virtual void clearAllChains(void);
230
231
        /** Sets whether the billboard should always be facing the camera or a custom direction
232
            set by each point element.
233
234
            Billboards facing the camera are useful for smoke trails, light beams, etc by
235
            simulating a cylinder. However, because of this property, wide trails can cause
236
            several artefacts unless the head is properly covered.
237
            Therefore, non-camera-facing billboards are much more convenient for leaving big
238
            trails of movement from thin objects, for example a sword swing as seen in many
239
            fighting games.
240
        @param faceCamera True to be always facing the camera (Default value: True)
241
        @param normalVector Only used when faceCamera == false. Must be a non-zero vector.
242
        This vector is the "point of reference" for each point orientation. For example,
243
        if normalVector is Vector3::UNIT_Z, and the point's orientation is an identity
244
        matrix, the segment corresponding to that point will be facing towards UNIT_Z
245
        This vector is internally normalized.
246
        */
247
        void setFaceCamera( bool faceCamera, const Vector3 &normalVector=Vector3::UNIT_X );
248
249
        /// Get the material name in use
250
0
        virtual const String& getMaterialName(void) const { return mMaterial->getName(); }
251
        /// Set the material name to use for rendering
252
        virtual void setMaterialName( const String& name, const String& groupName = ResourceGroupManager::AUTODETECT_RESOURCE_GROUP_NAME );
253
254
255
        // Overridden members follow
256
        Real getSquaredViewDepth(const Camera* cam) const override;
257
        Real getBoundingRadius(void) const override;
258
        const AxisAlignedBox& getBoundingBox(void) const override;
259
        const MaterialPtr& getMaterial(void) const override;
260
        const String& getMovableType(void) const override;
261
        void _updateRenderQueue(RenderQueue *) override;
262
        void getRenderOperation(RenderOperation &) override;
263
        bool preRender(SceneManager* sm, RenderSystem* rsys) override;
264
        void getWorldTransforms(Matrix4 *) const override;
265
        const LightList& getLights(void) const override;
266
        /// @copydoc MovableObject::visitRenderables
267
        void visitRenderables(Renderable::Visitor* visitor, 
268
            bool debugRenderables = false) override;
269
270
271
272
    protected:
273
274
        /// Maximum length of each chain
275
        uint32 mMaxElementsPerChain;
276
        /// Number of chains
277
        uint32 mChainCount;
278
        /// Use texture coords?
279
        bool mUseTexCoords;
280
        /// Use vertex colour?
281
        bool mUseVertexColour;
282
        /// Tell if vertex buffer should be update automatically.
283
        bool mAutoUpdate;
284
        /// Is the vertex declaration dirty?
285
        bool mVertexDeclDirty;
286
        /// Do the buffers need recreating?
287
        bool mBuffersNeedRecreating;
288
        /// Do the bounds need redefining?
289
        mutable bool mBoundsDirty;
290
        /// Is the index buffer dirty?
291
        bool mIndexContentDirty;
292
        /// Is the vertex buffer dirty?
293
        bool mVertexContentDirty;
294
        /// AABB
295
        mutable AxisAlignedBox mAABB;
296
        /// Bounding radius
297
        mutable Real mRadius;
298
        /// Material 
299
        MaterialPtr mMaterial;
300
        /// Texture coord direction
301
        TexCoordDirection mTexCoordDir;
302
        /// Other texture coord range
303
        Real mOtherTexCoordRange[2];
304
        /// When true, the billboards always face the camera
305
        bool mFaceCamera;
306
307
        typedef std::vector<Element> ElementList;
308
        /// The list holding the chain elements
309
        ElementList mChainElementList;
310
311
        /** Simple struct defining a chain segment by referencing a subset of
312
            the preallocated buffer (which will be mMaxElementsPerChain * mChainCount
313
            long), by it's chain index, and a head and tail value which describe
314
            the current chain. The buffer subset wraps at mMaxElementsPerChain
315
            so that head and tail can move freely. head and tail are inclusive,
316
            when the chain is empty head and tail are filled with high-values.
317
        */
318
        struct ChainSegment
319
        {
320
            /// The start of this chains subset of the buffer
321
            size_t start;
322
            /// The 'head' of the chain, relative to start
323
            size_t head;
324
            /// The 'tail' of the chain, relative to start
325
            size_t tail;
326
        };
327
        typedef std::vector<ChainSegment> ChainSegmentList;
328
        ChainSegmentList mChainSegmentList;
329
330
        /// Chain segment has no elements
331
        static const size_t SEGMENT_EMPTY;
332
    private:
333
        /// Used when mFaceCamera == false; determines the billboard's "normal". i.e.
334
        /// when the orientation is identity, the billboard is perpendicular to this
335
        /// vector
336
        Vector3 mNormalBase;
337
        /// Camera last used to build the vertex buffer
338
        Camera *mVertexCameraUsed;
339
        /// Vertex data
340
        std::unique_ptr<VertexData> mVertexData;
341
        /// Index data (to allow multiple unconnected chains)
342
        std::unique_ptr<IndexData> mIndexData;
343
344
        /// Setup the STL collections
345
        void setupChainContainers(void);
346
        /// Setup vertex declaration
347
        virtual void setupVertexDeclaration(void);
348
        /// Setup buffers
349
        virtual void setupBuffers(void);
350
        /// Update the contents of the vertex buffer
351
        virtual void updateVertexBuffer(Camera* cam);
352
        /// Update the contents of the index buffer
353
        virtual void updateIndexBuffer(void);
354
        virtual void updateBoundingBox(void) const;
355
    };
356
    /** @} */
357
    /** @} */
358
359
} // namespace
360
361
#include "OgreHeaderSuffix.h"
362
363
#endif
364
365