Coverage Report

Created: 2025-10-10 06:42

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/ogre/OgreMain/include/OgreBillboardSet.h
Line
Count
Source
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
#ifndef __BillboardSet_H__
30
#define __BillboardSet_H__
31
32
#include "OgrePrerequisites.h"
33
34
#include "OgreMovableObject.h"
35
#include "OgreRenderable.h"
36
#include "OgreCommon.h"
37
#include "OgreResourceGroupManager.h"
38
#include "OgreHeaderPrefix.h"
39
40
namespace Ogre {
41
    /** \addtogroup Core
42
    *  @{
43
    */
44
    /** \addtogroup Effects
45
    *  @{
46
    */
47
48
    /** Enum covering what exactly a billboard's position means (center,
49
        top-left etc).
50
51
        This setting controls the fine tuning of where a billboard appears in relation to it's
52
        position. It could be that a billboard's position represents it's center (e.g. for fireballs),
53
        it could mean the center of the bottom edge (e.g. a tree which is positioned on the ground),
54
        the top-left corner (e.g. a cursor).
55
    */
56
    enum BillboardOrigin
57
    {
58
        BBO_TOP_LEFT,
59
        BBO_TOP_CENTER,
60
        BBO_TOP_RIGHT,
61
        BBO_CENTER_LEFT,
62
        BBO_CENTER,
63
        BBO_CENTER_RIGHT,
64
        BBO_BOTTOM_LEFT,
65
        BBO_BOTTOM_CENTER,
66
        BBO_BOTTOM_RIGHT
67
    };
68
    /** The rotation type of billboard.
69
     *
70
     * By default, billboard particles will rotate the texture coordinates to according with particle
71
     * rotation. But rotate texture coordinates has some disadvantage, e.g. the corners of the texture will
72
     * lost after rotate, and the corners of the billboard will fill with unwanted texture area when using
73
     * wrap address mode or sub-texture sampling. This settings allow you specifying other rotation type.
74
     */
75
    enum BillboardRotationType
76
    {
77
        /// Rotate the billboard's vertices around their facing direction
78
        BBR_VERTEX,
79
        /// Rotate the billboard's texture coordinates
80
        BBR_TEXCOORD
81
    };
82
    /** The type of billboard to use. */
83
    enum BillboardType
84
    {
85
        /// Standard point billboard (default), always faces the camera completely and is always upright
86
        BBT_POINT,
87
        /// Billboards are oriented around a shared direction vector (used as Y axis) and only rotate around this to face the camera
88
        BBT_ORIENTED_COMMON,
89
        /// Billboards are oriented around their own direction vector (their own Y axis) and only rotate around this to face the camera
90
        BBT_ORIENTED_SELF,
91
        /// Billboards are perpendicular to a shared direction vector (used as Z axis, the facing direction) and X, Y axis are determined by a shared up-vertor
92
        BBT_PERPENDICULAR_COMMON,
93
        /// Billboards are perpendicular to their own direction vector (their own Z axis, the facing direction) and X, Y axis are determined by a shared up-vertor
94
        BBT_PERPENDICULAR_SELF
95
    };
96
97
    /** A collection of billboards (faces which are always facing the given direction) with the same (default) dimensions, material
98
        and which are fairly close proximity to each other.
99
100
        Billboards are rectangles made up of 2 tris which are always facing the given direction. They are typically used
101
        for special effects like particles. This class collects together a set of billboards with the same (default) dimensions,
102
        material and relative locality in order to process them more efficiently. The entire set of billboards will be
103
        culled as a whole (by default, although this can be changed if you want a large set of billboards
104
        which are spread out and you want them culled individually), individual Billboards have locations which are relative to the set (which itself derives it's
105
        position from the SceneNode it is attached to since it is a MoveableObject), they will be rendered as a single rendering operation,
106
        and some calculations will be sped up by the fact that they use the same dimensions so some workings can be reused.
107
    @par
108
        A BillboardSet can be created using the SceneManager::createBillboardSet method. They can also be used internally
109
        by other classes to create effects.
110
    @note
111
        Billboard bounds are only automatically calculated when you create them.
112
        If you modify the position of a billboard you may need to call 
113
        _updateBounds if the billboard moves outside the original bounds. 
114
        Similarly, the bounds do no shrink when you remove a billboard, 
115
        if you want them to call _updateBounds, but note this requires a
116
        potentially expensive examination of every billboard in the set.
117
    */
118
    class _OgreExport BillboardSet : public MovableObject, public Renderable
119
    {
120
    protected:
121
        /** Private constructor (instances cannot be created directly).
122
        */
123
        BillboardSet();
124
125
0
        bool getCastsShadows(void) const override { return getCastShadows(); }
126
127
        /// Bounds of all billboards in this set
128
        AxisAlignedBox mAABB;
129
        /// Bounding radius
130
        Real mBoundingRadius;
131
132
        /// Origin of each billboard
133
        BillboardOrigin mOriginType;
134
        /// Rotation type of each billboard
135
        BillboardRotationType mRotationType;
136
137
        /// Default width of each billboard
138
        Real mDefaultWidth;
139
        /// Default height of each billboard
140
        Real mDefaultHeight;
141
142
        /// Pointer to the material to use
143
        MaterialPtr mMaterial;
144
145
        /// Flag indicating whether to autoextend pool
146
        bool mAutoExtendPool;
147
148
        /// Flag indicating whether the billboards has to be sorted
149
        bool mSortingEnabled;
150
151
        /// Use 'true' billboard to cam position facing, rather than camera direcion
152
        bool mAccurateFacing;
153
154
        bool mWorldSpace;
155
156
        typedef std::vector<Billboard*> BillboardPool;
157
158
        /** Active billboard count.
159
160
            This allows very fast activation / deactivation of billboards
161
            (required for particle systems etc.) as well as reuse of Billboard instances in the pool
162
            without construction & destruction which avoids memory thrashing.
163
        */
164
        size_t mActiveBillboards;
165
166
        /** Pool of billboard instances for use and reuse.
167
168
            This vector will be preallocated with the estimated size of the set,and will extend as required.
169
        */
170
        BillboardPool mBillboardPool;
171
172
        /// The vertex position data for all billboards in this set.
173
        std::unique_ptr<VertexData> mVertexData;
174
        /// Shortcut to main buffer (positions, colours, texture coords)
175
        HardwareVertexBufferSharedPtr mMainBuf;
176
        /// Locked pointer to buffer
177
        float* mLockPtr;
178
        /// Boundary offsets based on origin and camera orientation
179
        /// Vector3 vLeftOff, vRightOff, vTopOff, vBottomOff;
180
        /// Final vertex offsets, used where sizes all default to save calcs
181
        Vector3 mVOffset[4];
182
        /// Current camera
183
        Camera* mCurrentCamera;
184
        /// Parametric offsets of origin
185
        Real mLeftOff, mRightOff, mTopOff, mBottomOff;
186
        /// Camera axes in billboard space
187
        Vector3 mCamX, mCamY;
188
        /// Camera direction in billboard space
189
        Vector3 mCamDir;
190
        /// Camera orientation in billboard space
191
        Quaternion mCamQ;
192
        /// Camera position in billboard space
193
        Vector3 mCamPos;
194
195
        /// The vertex index data for all billboards in this set (1 set only)
196
        std::unique_ptr<IndexData> mIndexData;
197
198
        /// Flag indicating whether each billboard should be culled separately (default: false)
199
        bool mCullIndividual;
200
201
        typedef std::vector< Ogre::FloatRect > TextureCoordSets;
202
        TextureCoordSets mTextureCoords;
203
204
        /// The type of billboard to render
205
        BillboardType mBillboardType;
206
207
        /// Common direction for billboards of type BBT_ORIENTED_COMMON and BBT_PERPENDICULAR_COMMON
208
        Vector3 mCommonDirection;
209
        /// Common up-vector for billboards of type BBT_PERPENDICULAR_SELF and BBT_PERPENDICULAR_COMMON
210
        Vector3 mCommonUpVector;
211
212
        /// Internal method for culling individual billboards
213
        inline bool billboardVisible(Camera* cam, const Billboard& bill);
214
215
        /// Number of visible billboards (will be == getNumBillboards if mCullIndividual == false)
216
        unsigned short mNumVisibleBillboards;
217
218
        /// Internal method for increasing pool size
219
        void increasePool(size_t size);
220
221
222
        //-----------------------------------------------------------------------
223
        // The internal methods which follow are here to allow maximum flexibility as to 
224
        //  when various components of the calculation are done. Depending on whether the
225
        //  billboards are of fixed size and whether they are point or oriented type will
226
        //  determine how much calculation has to be done per-billboard. NOT a one-size fits all approach.
227
        //-----------------------------------------------------------------------
228
        /** Internal method for generating billboard corners. 
229
230
            Optional parameter pBill is only present for type BBT_ORIENTED_SELF and BBT_PERPENDICULAR_SELF
231
        */
232
        void genBillboardAxes(Vector3* pX, Vector3 *pY, const Billboard* pBill = 0);
233
234
        /** Internal method, generates parametric offsets based on origin.
235
        */
236
        void getParametricOffsets(Real& left, Real& right, Real& top, Real& bottom);
237
238
        /** Internal method for generating vertex data. 
239
        @param offsets Array of 4 Vector3 offsets
240
        @param pBillboard Reference to billboard
241
        */
242
        void genQuadVertices(const Vector3* const offsets, const Billboard& pBillboard);
243
244
        void genPointVertices(const Billboard& pBillboard);
245
246
        /** Internal method generates vertex offsets.
247
248
            Takes in parametric offsets as generated from getParametericOffsets, width and height values
249
            and billboard x and y axes as generated from genBillboardAxes. 
250
            Fills output array of 4 vectors with vector offsets
251
            from origin for left-top, right-top, left-bottom, right-bottom corners.
252
        */
253
        static void genVertOffsets(Real inleft, Real inright, Real intop, Real inbottom,
254
            Real width, Real height,
255
            const Vector3& x, const Vector3& y, Vector3* pDestVec);
256
257
258
        /** Sort by direction functor */
259
        struct SortByDirectionFunctor
260
        {
261
            /// Direction to sort in
262
            Vector3 sortDir;
263
264
            SortByDirectionFunctor(const Vector3& dir);
265
            float operator()(Billboard* bill) const;
266
        };
267
268
        /** Sort by distance functor */
269
        struct SortByDistanceFunctor
270
        {
271
            /// Position to sort in
272
            Vector3 sortPos;
273
274
            SortByDistanceFunctor(const Vector3& pos);
275
            float operator()(Billboard* bill) const;
276
        };
277
278
        /// Use point rendering?
279
        bool mPointRendering;
280
281
282
283
    private:
284
        /// Flag indicating whether the HW buffers have been created.
285
        bool mBuffersCreated;
286
        /// The number of billboard in the pool.
287
        size_t mPoolSize;
288
        /// Is external billboard data in use?
289
        bool mExternalData;
290
        /// Tell if vertex buffer should be update automatically.
291
        bool mAutoUpdate;
292
        /// True if the billboard data changed. Will cause vertex buffer update.
293
        bool mBillboardDataChanged;
294
295
        /** Internal method creates vertex and index buffers.
296
        */
297
        void _createBuffers(void);
298
        /** Internal method destroys vertex and index buffers.
299
        */
300
        void _destroyBuffers(void);
301
302
    public:
303
304
        /** Usual constructor - this is called by the SceneManager.
305
        @param name
306
            The name to give the billboard set (must be unique)
307
        @param poolSize
308
            The initial size of the billboard pool. Estimate of the number of billboards
309
            which will be required, and pass it using this parameter. The set will
310
            preallocate this number to avoid memory fragmentation. The default behaviour
311
            once this pool has run out is to double it.
312
        @param externalDataSource
313
            If @c true, the source of data for drawing the 
314
            billboards will not be the internal billboard list, but external 
315
            data. When driving the billboard from external data, you must call
316
            _notifyCurrentCamera to reorient the billboards, setPoolSize to set
317
            the maximum billboards you want to use, beginBillboards to 
318
            start the update, and injectBillboard per billboard, 
319
            followed by endBillboards.
320
        @see
321
            BillboardSet::setAutoextend
322
        */
323
        BillboardSet( const String& name, unsigned int poolSize = 20, 
324
            bool externalDataSource = false);
325
326
        virtual ~BillboardSet();
327
328
        /** Creates a new billboard and adds it to this set.
329
330
            Behaviour once the billboard pool has been exhausted depends on the
331
            BillboardSet::setAutoextend option.
332
        @param position
333
            The position of the new billboard relative to the center of the set
334
        @param colour
335
            Optional base colour of the billboard.
336
        @return
337
            On success, a pointer to a newly created Billboard is
338
            returned.
339
        @par
340
            On failure (i.e. no more space and can't autoextend),
341
            @c NULL is returned.
342
        @see
343
            BillboardSet::setAutoextend
344
        */
345
        Billboard* createBillboard(
346
            const Vector3& position,
347
            const ColourValue& colour = ColourValue::White );
348
349
        /// @overload
350
        Billboard* createBillboard(Real x, Real y, Real z, const ColourValue& colour = ColourValue::White)
351
0
        {
352
0
            return createBillboard(Vector3(x, y, z), colour);
353
0
        }
354
355
        /** Returns the number of active billboards which currently make up this set.
356
        */
357
0
        int getNumBillboards(void) const { return static_cast<int>(mActiveBillboards); }
358
359
        /** Tells the set whether to allow automatic extension of the pool of billboards.
360
361
            A BillboardSet stores a pool of pre-constructed billboards which are used as needed when
362
            a new billboard is requested. This allows applications to create / remove billboards efficiently
363
            without incurring construction / destruction costs (a must for sets with lots of billboards like
364
            particle effects). This method allows you to configure the behaviour when a new billboard is requested
365
            but the billboard pool has been exhausted.
366
        @par
367
            The default behaviour is to allow the pool to extend (typically this allocates double the current
368
            pool of billboards when the pool is expended), equivalent to calling this method with
369
            autoExtend = true. If you set the parameter to false however, any attempt to create a new billboard
370
            when the pool has expired will simply fail silently, returning a null pointer.
371
        @param autoextend
372
            @c true to double the pool every time it runs out, @c false to fail silently.
373
        */
374
0
        void setAutoextend(bool autoextend) { mAutoExtendPool = autoextend; }
375
376
        /** Returns true if the billboard pool automatically extends.
377
        @see
378
            BillboardSet::setAutoextend
379
        */
380
0
        bool getAutoextend(void) const { return mAutoExtendPool; }
381
382
        /** Enables sorting for this BillboardSet. (default: off)
383
        @param sortenable true to sort the billboards according to their distance to the camera
384
        */
385
0
        void setSortingEnabled(bool sortenable) { mSortingEnabled = sortenable; }
386
387
        /** Returns true if sorting of billboards is enabled based on their distance from the camera
388
        @see
389
            BillboardSet::setSortingEnabled
390
        */
391
0
        bool getSortingEnabled(void) const { return mSortingEnabled; }
392
393
        /** Adjusts the size of the pool of billboards available in this set.
394
395
            See the BillboardSet::setAutoextend method for full details of the billboard pool. This method adjusts
396
            the preallocated size of the pool. If you try to reduce the size of the pool, the set has the option
397
            of ignoring you if too many billboards are already in use. Bear in mind that calling this method will
398
            incur significant construction / destruction calls so should be avoided in time-critical code. The same
399
            goes for auto-extension, try to avoid it by estimating the pool size correctly up-front.
400
        @param size
401
            The new size for the pool.
402
        */
403
        void setPoolSize(size_t size);
404
405
        /** Returns the current size of the billboard pool.
406
        @return
407
            The current size of the billboard pool.
408
        @see
409
            BillboardSet::setAutoextend
410
        */
411
0
        unsigned int getPoolSize() const { return static_cast<unsigned int>(mBillboardPool.size()); }
412
413
        /** Empties this set of all billboards.
414
        */
415
        virtual void clear();
416
417
        /** Returns a pointer to the billboard at the supplied index.
418
419
        @param index
420
            The index of the billboard that is requested.
421
        @return
422
            On success, a valid pointer to the requested billboard is
423
            returned.
424
        @par
425
            On failure, @c NULL is returned.
426
        */
427
        virtual Billboard* getBillboard(unsigned int index) const;
428
429
        /** Removes the billboard at the supplied index.
430
        */
431
        virtual void removeBillboard(unsigned int index);
432
433
        /** Removes a billboard from the set.
434
        */
435
        virtual void removeBillboard(Billboard* pBill);
436
437
        /// @name Billboard positioning
438
        /// @{
439
        /** Sets the point which acts as the origin point for all billboards in this set.
440
441
            This setting controls the fine tuning of where a billboard appears in relation to it's
442
            position. It could be that a billboard's position represents it's center (e.g. for fireballs),
443
            it could mean the center of the bottom edge (e.g. a tree which is positioned on the ground),
444
            the top-left corner (e.g. a cursor).
445
446
            The default setting is #BBO_CENTER.
447
        @param origin
448
            A member of the BillboardOrigin enum specifying the origin for all the billboards in this set.
449
        */
450
0
        void setBillboardOrigin(BillboardOrigin origin) { mOriginType = origin; }
451
452
        /** Gets the point which acts as the origin point for all billboards in this set.
453
        @return
454
            A member of the BillboardOrigin enum specifying the origin for all the billboards in this set.
455
        */
456
0
        BillboardOrigin getBillboardOrigin(void) const { return mOriginType; }
457
458
        /** Sets billboard rotation type.
459
460
            This setting controls the billboard rotation type, you can deciding rotate the billboard's vertices
461
            around their facing direction or rotate the billboard's texture coordinates.
462
463
            The default settings is #BBR_TEXCOORD.
464
        @param rotationType
465
            A member of the BillboardRotationType enum specifying the rotation type for all the billboards in this set.
466
        */
467
0
        void setBillboardRotationType(BillboardRotationType rotationType) { mRotationType = rotationType; }
468
469
        /** Sets billboard rotation type.
470
        @return
471
            A member of the BillboardRotationType enum specifying the rotation type for all the billboards in this set.
472
        */
473
0
        BillboardRotationType getBillboardRotationType(void) const { return mRotationType; }
474
475
        /** Sets the default dimensions of the billboards in this set.
476
477
            All billboards in a set are created with these default dimensions. The set will render most efficiently if
478
            all the billboards in the set are the default size. It is possible to alter the size of individual
479
            billboards at the expense of extra calculation. See the Billboard class for more info.
480
        @param width
481
            The new default width for the billboards in this set.
482
        @param height
483
            The new default height for the billboards in this set.
484
        */
485
        void setDefaultDimensions(Real width, Real height)
486
0
        {
487
0
            mDefaultWidth = width;
488
0
            mDefaultHeight = height;
489
0
        }
490
491
        /** See setDefaultDimensions - this sets 1 component individually. */
492
0
        void setDefaultWidth(Real width) { mDefaultWidth = width; }
493
        /** See setDefaultDimensions - this gets 1 component individually. */
494
0
        Real getDefaultWidth(void) const { return mDefaultWidth; }
495
        /** See setDefaultDimensions - this sets 1 component individually. */
496
0
        void setDefaultHeight(Real height) { mDefaultHeight = height; }
497
        /** See setDefaultDimensions - this gets 1 component individually. */
498
0
        Real getDefaultHeight(void) const { return mDefaultHeight; }
499
        /// @}
500
501
        /** Sets the name of the material to be used for this billboard set.
502
        */
503
        virtual void setMaterialName( const String& name, const String& groupName = ResourceGroupManager::AUTODETECT_RESOURCE_GROUP_NAME );
504
505
        /** Sets the name of the material to be used for this billboard set.
506
        @return The name of the material that is used for this set.
507
        */
508
0
        const String& getMaterialName(void) const { return mMaterial->getName(); }
509
510
        void _notifyCurrentCamera(Camera* cam) override;
511
512
        /** Begin injection of billboard data; applicable when 
513
            constructing the BillboardSet for external data use.
514
        @param numBillboards If you know the number of billboards you will be 
515
            issuing, state it here to make the update more efficient.
516
        */
517
        void beginBillboards(size_t numBillboards = 0);
518
        /** Define a billboard. */
519
        void injectBillboard(const Billboard& bb);
520
        /** Finish defining billboards. */
521
        void endBillboards(void);
522
        /** Set the bounds of the BillboardSet.
523
524
            You may need to call this if you're injecting billboards manually, 
525
            and you're relying on the BillboardSet to determine culling.
526
        */
527
        void setBounds(const AxisAlignedBox& box, Real radius);
528
529
0
        const AxisAlignedBox& getBoundingBox(void) const override { return mAABB; }
530
0
        Real getBoundingRadius(void) const override { return mBoundingRadius; }
531
        void _updateRenderQueue(RenderQueue* queue) override;
532
0
        const MaterialPtr& getMaterial(void) const override { return mMaterial; }
533
534
        /** Sets the name of the material to be used for this billboard set.
535
        @param material
536
            The new material to use for this set.
537
         */
538
        virtual void setMaterial( const MaterialPtr& material );
539
540
541
        void getRenderOperation(RenderOperation& op) override;
542
        void getWorldTransforms(Matrix4* xform) const override;
543
544
        /** Returns whether or not billboards in this are tested individually for culling. */
545
0
        bool getCullIndividually(void) const { return mCullIndividual; }
546
        /** Sets whether culling tests billboards in this individually as well as in a group.
547
548
            Billboard sets are always culled as a whole group, based on a bounding box which 
549
            encloses all billboards in the set. For fairly localised sets, this is enough. However, you
550
            can optionally tell the set to also cull individual billboards in the set, i.e. to test
551
            each individual billboard before rendering. The default is not to do this.
552
        @par
553
            This is useful when you have a large, fairly distributed set of billboards, like maybe 
554
            trees on a landscape. You probably still want to group them into more than one
555
            set (maybe one set per section of landscape), which will be culled coarsely, but you also
556
            want to cull the billboards individually because they are spread out. Whilst you could have
557
            lots of single-tree sets which are culled separately, this would be inefficient to render
558
            because each tree would be issued as it's own rendering operation.
559
        @par
560
            By calling this method with a parameter of true, you can have large billboard sets which 
561
            are spaced out and so get the benefit of batch rendering and coarse culling, but also have
562
            fine-grained culling so unnecessary rendering is avoided.
563
        @param cullIndividual If true, each billboard is tested before being sent to the pipeline as well 
564
            as the whole set having to pass the coarse group bounding test.
565
        */
566
0
        void setCullIndividually(bool cullIndividual) { mCullIndividual = cullIndividual; }
567
568
        /// @name Billboard orientation
569
        /// @{
570
        /** Sets the orientation behaviour of the billboards to render.
571
572
            The default sort of billboard (#BBT_POINT), always has both x and y axes parallel to
573
            the camera's local axes. This is fine for 'point' style billboards (e.g. flares,
574
            smoke, anything which is symmetrical about a central point) but does not look good for
575
            billboards which have an orientation (e.g. an elongated raindrop). In this case, the
576
            oriented billboards are more suitable (#BBT_ORIENTED_COMMON or #BBT_ORIENTED_SELF) since
577
            they retain an independent Y axis and only the X axis is generated, perpendicular to both
578
            the local Y and the camera Z.
579
580
            In some case you might want the billboard has fixed Z axis and doesn't need to face to
581
            camera (e.g. an aureola around the player and parallel to the ground). You can use
582
            #BBT_PERPENDICULAR_SELF which the billboard plane perpendicular to the billboard own
583
            direction. Or #BBT_PERPENDICULAR_COMMON which the billboard plane perpendicular to the
584
            common direction.
585
        @note
586
            #BBT_PERPENDICULAR_SELF and #BBT_PERPENDICULAR_COMMON can't guarantee counterclockwise, you might
587
            use double-side material (#CULL_NONE) to ensure no billboard are culled.
588
        @param bbt The type of billboard to render
589
        */
590
0
        void setBillboardType(BillboardType bbt) { mBillboardType = bbt; }
591
592
        /** Returns the billboard type in use. */
593
0
        BillboardType getBillboardType(void) const { return mBillboardType; }
594
595
        /** Use this to specify the common direction given to billboards
596
597
            Use #BBT_ORIENTED_COMMON when you want oriented billboards but you know they are always going to
598
            be oriented the same way (e.g. rain in calm weather). It is faster for the system to calculate
599
            the billboard vertices if they have a common direction.
600
601
            The common direction also use in #BBT_PERPENDICULAR_COMMON, in this case the common direction
602
            treat as Z axis, and an additional common up-vector was use to determine billboard X and Y
603
            axis.
604
605
            @param vec The direction for all billboards. The vector is expected to be unit-length (normalised)
606
607
            @see setCommonUpVector
608
        */
609
0
        void setCommonDirection(const Vector3& vec) { mCommonDirection = vec; }
610
611
        /** Gets the common direction for all billboards (BBT_ORIENTED_COMMON) */
612
0
        const Vector3& getCommonDirection(void) const { return mCommonDirection; }
613
614
        /** Use this to specify the common up-vector given to billboards
615
616
            Use #BBT_PERPENDICULAR_SELF or #BBT_PERPENDICULAR_COMMON when you want oriented billboards
617
            perpendicular to specify direction vector (or, Z axis), and doesn't face to camera.
618
            In this case, we need an additional up-vector to determine the billboard X and Y axis.
619
            The generated billboard plane and X-axis guarantee perpendicular to specify direction.
620
621
            The specify direction is billboard own direction when billboard type is #BBT_PERPENDICULAR_SELF,
622
            and it's shared common direction when billboard type is #BBT_PERPENDICULAR_COMMON.
623
624
            @param vec The up-vector for all billboards. The vector is expected to be unit-length (normalised)
625
626
            @see setCommonDirection
627
        */
628
0
        void setCommonUpVector(const Vector3& vec) { mCommonUpVector = vec; }
629
630
        /** Gets the common up-vector for all billboards (BBT_PERPENDICULAR_SELF and BBT_PERPENDICULAR_COMMON) */
631
0
        const Vector3& getCommonUpVector(void) const { return mCommonUpVector; }
632
633
        /** Sets whether or not billboards should use an 'accurate' facing model
634
635
            By default, the axes for all billboards are calculated using the 
636
            camera's view direction, not the vector from the camera position to
637
            the billboard. The former is faster, and most of the time the difference
638
            is not noticeable. However for some purposes (e.g. very large, static
639
            billboards) the changing billboard orientation when rotating the camera
640
            can be off putting, therefore you can enable this option to use a
641
            more expensive, but more accurate version.
642
        @param acc True to use the slower but more accurate model. Default is false.
643
        */
644
0
        void setUseAccurateFacing(bool acc) { mAccurateFacing = acc; }
645
        /** Gets whether or not billboards use an 'accurate' facing model
646
647
            based on the vector from each billboard to the camera, rather than 
648
            an optimised version using just the camera direction.
649
        */
650
0
        bool getUseAccurateFacing(void) const { return mAccurateFacing; }
651
        /// @}
652
653
        const String& getMovableType(void) const override;
654
        Real getSquaredViewDepth(const Camera* cam) const override;
655
656
        /** Update the bounds of the billboardset */
657
        virtual void _updateBounds(void);
658
        /** @copydoc Renderable::getLights */
659
        const LightList& getLights(void) const override;
660
661
        /// @copydoc MovableObject::visitRenderables
662
        void visitRenderables(Renderable::Visitor* visitor, 
663
            bool debugRenderables = false) override;
664
665
        /** Sort the billboard set. Only called when enabled via setSortingEnabled */
666
        virtual void _sortBillboards( Camera* cam);
667
668
        /** Gets the sort mode of this billboard set */
669
        virtual SortMode _getSortMode(void) const;
670
671
        /** Sets whether billboards should be treated as being in world space. 
672
673
            This is most useful when you are driving the billboard set from 
674
            an external data source.
675
        */
676
0
        void setBillboardsInWorldSpace(bool ws) { mWorldSpace = ws; }
677
678
        /** Gets whether billboards are treated as being in world space.
679
         */
680
0
        bool getBillboardsInWorldSpace() { return mWorldSpace; }
681
682
        /// @name Billboard UV computation
683
        /// @{
684
        /** BillboardSet can use custom texture coordinates for various billboards.
685
            This is useful for selecting one of many particle images out of a tiled 
686
            texture sheet, or doing flipbook animation within a single texture.
687
        @par
688
            The generic functionality is setTextureCoords(), which will copy the 
689
            texture coordinate rects you supply into internal storage for the 
690
            billboard set. If your texture sheet is a square grid, you can also 
691
            use setTextureStacksAndSlices() for more convenience, which will construct 
692
            the set of texture coordinates for you.
693
        @par
694
            When a Billboard is created, it can be assigned a texture coordinate 
695
            set from within the sets you specify (that set can also be re-specified 
696
            later). When drawn, the billboard will use those texture coordinates, 
697
            rather than the full 0-1 range.
698
699
        @param coords is a vector of texture coordinates (in UV space) to choose 
700
            from for each billboard created in the set.
701
702
            Set 'coords' to 0 and/or 'numCoords' to 0 to reset the texture coord 
703
            rects to the initial set of a single rectangle spanning 0 through 1 in 
704
            both U and V (i e, the entire texture).
705
        @see
706
            BillboardSet::setTextureStacksAndSlices()
707
            Billboard::setTexcoordIndex()
708
        */
709
        void setTextureCoords(const std::vector<FloatRect>& coords);
710
711
        /// @deprecated
712
        OGRE_DEPRECATED void setTextureCoords(FloatRect const* coords, uint16 numCoords)
713
0
        {
714
0
            setTextureCoords(std::vector<FloatRect>(coords, coords + numCoords));
715
0
        }
716
717
        /** Generate texture coordinate rects for a tiled texture sheet
718
719
            A texture sheet is a grid of images that can be used to create simple animations.
720
            This method will generate the uv coordinates for the individual sub-rectangles.
721
722
            These can then be addressed by Ogre::Billboard::setTexcoordIndex().
723
724
            If the texture size is 512x512 and 'stacks' is 4 and 'slices' is 8, each sub-rectangle of the texture
725
            would be 128 texels tall and 64 texels wide.
726
727
            The numbering counts first across, then down, so top-left is 0, the one to the right
728
            of that is 1, and the lower-right is stacks*slices-1.
729
730
            If you need more flexibility, you can use Ogre::BillboardSet::setTextureCoords() instead.
731
732
            @param stacks number of vertical tiles (rows)
733
            @param slices number of horizontal tiles (columns)
734
        */
735
        void setTextureStacksAndSlices( uchar stacks, uchar slices );
736
737
        /** getTextureCoords() returns the current texture coordinate rects in 
738
            effect. By default, there is only one texture coordinate rect in the 
739
            set, spanning the entire texture from 0 through 1 in each direction.
740
        @see
741
            BillboardSet::setTextureCoords()
742
        */
743
0
        const std::vector<FloatRect>& getTextureCoords() const { return mTextureCoords; }
744
        /// @}
745
746
        /** Set whether or not the BillboardSet will use point rendering
747
            rather than manually generated quads.
748
749
            By default a billboardset is rendered by generating geometry for a
750
            textured quad in memory, taking into account the size and 
751
            orientation settings, and uploading it to the video card. 
752
            The alternative is to use hardware point rendering, which means that
753
            only one position needs to be sent per billboard rather than 4 and
754
            the hardware sorts out how this is rendered based on the render
755
            state.
756
757
            Using point rendering is faster than generating quads manually, but
758
            is more restrictive. The following restrictions apply:
759
            - Only the Ogre::BBT_POINT type is supported
760
            - Size and appearance of each billboard is controlled by the material
761
              - Ogre::Pass::setPointSize
762
              - Ogre::Pass::setPointAttenuation
763
              - Ogre::Pass::setPointSpritesEnabled
764
            - Per-billboard size is not supported (stems from the above)
765
            - Per-billboard rotation is not supported, this can only be
766
                controlled through texture unit rotation
767
            - Only Ogre::BBO_CENTER origin is supported
768
            - Per-billboard texture coordinates are not supported
769
770
            You will almost certainly want to enable in your material pass
771
            both point attenuation and point sprites if you use this option.
772
        */
773
        virtual void setPointRenderingEnabled(bool enabled);
774
775
        /** Returns whether point rendering is enabled. */
776
0
        bool isPointRenderingEnabled(void) const { return mPointRendering; }
777
778
        /// Override to return specific type flag
779
        uint32 getTypeFlags(void) const override;
780
781
        /** Set the auto update state of this billboard set.
782
783
            This methods controls the updating policy of the vertex buffer.
784
            By default auto update is true so the vertex buffer is being update every time this billboard set
785
            is about to be rendered. This behavior best fit when the billboards of this set changes frequently.
786
            When using static or semi-static billboards, it is recommended to set auto update to false.
787
            In that case one should call notifyBillboardDataChanged method to reflect changes made to the
788
            billboards data.
789
        */
790
        void setAutoUpdate(bool autoUpdate);
791
792
        /** Return the auto update state of this billboard set.*/
793
0
        bool getAutoUpdate(void) const { return mAutoUpdate; }
794
795
        /** When billboard set is not auto updating its GPU buffer, the user is responsible to inform it
796
            about any billboard changes in order to reflect them at the rendering stage.
797
            Calling this method will cause GPU buffers update in the next render queue update.
798
        */
799
0
        void notifyBillboardDataChanged(void) { mBillboardDataChanged = true; }
800
801
        /** @copydoc MovableObject::_releaseManualHardwareResources */
802
0
        void _releaseManualHardwareResources() override { _destroyBuffers(); }
803
804
    };
805
    /** @} */
806
    /** @} */
807
808
} // namespace Ogre
809
810
#include "OgreHeaderSuffix.h"
811
812
#endif // __BillboardSet_H__