source: OGRE/trunk/ogrenew/OgreMain/include/OgreBillboardSet.h @ 657

Revision 657, 26.4 KB checked in by mattausch, 18 years ago (diff)

added ogre dependencies and patched ogre sources

Line 
1/*
2-----------------------------------------------------------------------------
3This source file is part of OGRE
4    (Object-oriented Graphics Rendering Engine)
5For the latest info, see http://www.ogre3d.org/
6
7Copyright (c) 2000-2005 The OGRE Team
8Also see acknowledgements in Readme.html
9
10This program is free software; you can redistribute it and/or modify it under
11the terms of the GNU Lesser General Public License as published by the Free Software
12Foundation; either version 2 of the License, or (at your option) any later
13version.
14
15This program is distributed in the hope that it will be useful, but WITHOUT
16ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
17FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
18
19You should have received a copy of the GNU Lesser General Public License along with
20this program; if not, write to the Free Software Foundation, Inc., 59 Temple
21Place - Suite 330, Boston, MA 02111-1307, USA, or go to
22http://www.gnu.org/copyleft/lesser.txt.
23-----------------------------------------------------------------------------
24*/
25
26#ifndef __BillboardSet_H__
27#define __BillboardSet_H__
28
29#include "OgrePrerequisites.h"
30
31#include "OgreMovableObject.h"
32#include "OgreRenderable.h"
33
34namespace Ogre {
35
36    /** Enum covering what exactly a billboard's position means (center,
37        top-left etc).
38        @see
39            BillboardSet::setBillboardOrigin
40    */
41    enum BillboardOrigin
42    {
43        BBO_TOP_LEFT,
44        BBO_TOP_CENTER,
45        BBO_TOP_RIGHT,
46        BBO_CENTER_LEFT,
47        BBO_CENTER,
48        BBO_CENTER_RIGHT,
49        BBO_BOTTOM_LEFT,
50        BBO_BOTTOM_CENTER,
51        BBO_BOTTOM_RIGHT
52    };
53    /** The type of billboard to use. */
54    enum BillboardType
55    {
56        /// Standard point billboard (default), always faces the camera completely and is always upright
57        BBT_POINT,
58        /// Billboards are oriented around a shared direction vector (used as Y axis) and only rotate around this to face the camera
59        BBT_ORIENTED_COMMON,
60        /// Billboards are oriented around their own direction vector (their own Y axis) and only rotate around this to face the camera
61        BBT_ORIENTED_SELF
62
63    };
64
65    /** A collection of billboards (faces which are always facing the camera) with the same (default) dimensions, material
66        and which are fairly close proximity to each other.
67        @remarks
68            Billboards are rectangles made up of 2 tris which are always facing the camera. They are typically used
69            for special effects like particles. This class collects together a set of billboards with the same (default) dimensions,
70            material and relative locality in order to process them more efficiently. The entire set of billboards will be
71            culled as a whole (by default, although this can be changed if you want a large set of billboards
72            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
73            position from the SceneNode it is attached to since it is a MoveableObject), they will be rendered as a single rendering operation,
74            and some calculations will be sped up by the fact that they use the same dimensions so some workings can be reused.
75        @par
76            A BillboardSet can be created using the SceneManager::createBillboardSet method. They can also be used internally
77            by other classes to create effects.
78                @note
79                        Billboard bounds are only automatically calculated when you create them.
80                        If you modify the position of a billboard you may need to call
81                        _updateBounds if the billboard moves outside the original bounds.
82                        Similarly, the bounds do no shrink when you remove a billboard,
83                        if you want them to call _updateBounds, but note this requires a
84                        potentially expensive examination of every billboard in the set.
85    */
86    class _OgreExport BillboardSet : public MovableObject, public Renderable
87    {
88    protected:
89        /** Private constructor (instances cannot be created directly).
90        */
91        BillboardSet();
92
93        /// Name of the entity; used for location in the scene.
94        String mName;
95
96        /// Bounds of all billboards in this set
97        AxisAlignedBox mAABB;
98                /// Bounding radius
99                Real mBoundingRadius;
100
101        /// Origin of each billboard
102        BillboardOrigin mOriginType;
103
104        /// Default width of each billboard
105        Real mDefaultWidth;
106        /// Default height of each billboard
107        Real mDefaultHeight;
108
109        /// Name of the material to use
110        String mMaterialName;
111        /// Pointer to the material to use
112        MaterialPtr mpMaterial;
113
114        /// True if no billboards in this set have been resized - greater efficiency.
115        bool mAllDefaultSize;
116
117        /// Flag indicating whether to autoextend pool
118        bool mAutoExtendPool;
119
120        bool mFixedTextureCoords;
121        bool mWorldSpace;
122
123        typedef std::list<Billboard*> ActiveBillboardList;
124        typedef std::deque<Billboard*> FreeBillboardQueue;
125        typedef std::vector<Billboard*> BillboardPool;
126
127        /** Active billboard list.
128            @remarks
129                This is a linked list of pointers to billboards in the billboard pool.
130            @par
131                This allows very fast instertions and deletions from anywhere in the list to activate / deactivate billboards
132                (required for particle systems etc)    as well as resuse of Billboard instances in the pool
133                without construction & destruction which avoids memory thrashing.
134        */
135        ActiveBillboardList mActiveBillboards;
136
137        /** Free billboard queue.
138            @remarks
139                This contains a list of the billboards free for use as new instances
140                as required by the set. Billboard instances are preconstructed up to the estimated size in the
141                mBillboardPool vector and are referenced on this deque at startup. As they get used this deque
142                reduces, as they get released back to to the set they get added back to the deque.
143        */
144        FreeBillboardQueue mFreeBillboards;
145
146        /** Pool of billboard instances for use and reuse in the active billboard list.
147            @remarks
148                This vector will be preallocated with the estimated size of the set,and will extend as required.
149        */
150        BillboardPool mBillboardPool;
151
152
153        /// The vertex position data for all billboards in this set.
154        VertexData* mVertexData;
155        /// Shortcut to main buffer (positions, colours, texture coords)
156        HardwareVertexBufferSharedPtr mMainBuf;
157        /// Locked pointer to buffer
158        float* mLockPtr;
159        /// Boundary offsets based on origin and camera orientation
160        /// Vector3 vLeftOff, vRightOff, vTopOff, vBottomOff;
161        /// Final vertex offsets, used where sizes all default to save calcs
162        Vector3 mVOffset[4];
163        /// Current camera
164        Camera* mCurrentCamera;
165        // Parametric offsets of origin
166        Real mLeftOff, mRightOff, mTopOff, mBottomOff;
167        // Camera axes in billboard space
168        Vector3 mCamX, mCamY;
169
170        /// The vertex index data for all billboards in this set (1 set only)
171        //unsigned short* mpIndexes;
172        IndexData* mIndexData;
173
174        /// Flag indicating whether each billboard should be culled separately (default: false)
175        bool mCullIndividual;
176
177        /// The type of billboard to render
178        BillboardType mBillboardType;
179
180        /// Common direction for billboards of type BBT_ORIENTED_COMMON
181        Vector3 mCommonDirection;
182
183        /// Internal method for culling individual billboards
184        inline bool billboardVisible(Camera* cam, const Billboard& bill);
185
186        // Number of visible billboards (will be == getNumBillboards if mCullIndividual == false)
187        unsigned short mNumVisibleBillboards;
188
189        /// Internal method for increasing pool size
190        virtual void increasePool(unsigned int size);
191
192
193        //-----------------------------------------------------------------------
194        // The internal methods which follow are here to allow maximum flexibility as to
195        //  when various components of the calculation are done. Depending on whether the
196        //  billboards are of fixed size and whether they are point or oriented type will
197        //  determine how much calculation has to be done per-billboard. NOT a one-size fits all approach.
198        //-----------------------------------------------------------------------
199        /** Internal method for generating billboard corners.
200        @remarks
201            Optional parameter pBill is only present for type BBT_ORIENTED_SELF
202        */
203        virtual void genBillboardAxes(Camera* cam, Vector3* pX, Vector3 *pY, const Billboard* pBill = 0);
204
205        /** Internal method, generates parametric offsets based on origin.
206        */
207        void getParametricOffsets(Real& left, Real& right, Real& top, Real& bottom);
208
209        /** Internal method for generating vertex data.
210        @param offsets Array of 4 Vector3 offsets
211        @param bb Referenceto billboard
212        */
213        void genVertices(const Vector3* const offsets, const Billboard& pBillboard);
214
215        /** Internal method generates vertex offsets.
216        @remarks
217            Takes in parametric offsets as generated from getParametericOffsets, width and height values
218            and billboard x and y axes as generated from genBillboardAxes.
219            Fills output array of 4 vectors with vector offsets
220            from origin for left-top, right-top, left-bottom, right-bottom corners.
221        */
222        void genVertOffsets(Real inleft, Real inright, Real intop, Real inbottom,
223            Real width, Real height,
224            const Vector3& x, const Vector3& y, Vector3* pDestVec);
225
226        /// Shared class-level name for Movable type
227        static String msMovableType;
228
229    private:
230        /// Flag indicating whether the HW buffers have been created.
231        bool mBuffersCreated;
232        /// The number of billboard in the pool.
233        unsigned int mPoolSize;
234        /// Is external billboard data in use?
235        bool mExternalData;
236
237        /** Internal method creates vertex and index buffers.
238        */
239        void _createBuffers(void);
240
241    public:
242
243        /** Usual constructor - this is called by the SceneManager.
244            @param
245                name The name to give the billboard set (must be unique)
246            @param
247                poolSize The initial size of the billboard pool. Estimate of the number of billboards
248                which will be required, and pass it using this parameter. The set will
249                preallocate this number to avoid memory fragmentation. The default behaviour
250                once this pool has run out is to double it.
251            @param
252                externalDataSource If true, the source of data for drawing the
253                billboards will not be the internal billboard list, but external
254                data. When driving thebillboard from external data, you must call
255                _notifyCurrentCamera to reorient the billboards, setPoolSize to set
256                the maximum billboards you want to use, beginBillboards to
257                start the update, and injectBillboard per billboard,
258                followed by endBillboards.
259            @see
260                BillboardSet::setAutoextend
261        */
262        BillboardSet( const String& name, unsigned int poolSize = 20,
263            bool externalDataSource = false);
264
265        virtual ~BillboardSet();
266
267        /** Creates a new billboard and adds it to this set.
268            @remarks
269                Behaviour once the billboard pool has been exhausted depends on the
270                BillboardSet::setAutoextendPool option.
271            @param
272                position The position of the new billboard realtive to the certer of the set
273            @param
274                colour Optional base colour of the billboard.
275            @returns
276                On success, a pointer to a newly created Billboard is
277                returned.
278            @par
279                On failiure (i.e. no more space and can't autoextend),
280                <b>NULL</b> is returned.
281            @see
282                BillboardSet::setAutoextend
283        */
284        Billboard* createBillboard(
285            const Vector3& position,
286            const ColourValue& colour = ColourValue::White );
287
288        /** Creates a new billboard and adds it to this set.
289            @remarks
290                Behaviour once the billboard pool has been exhausted depends on the
291                BillboardSet::setAutoextendPool option.
292            @param
293                x
294            @param
295                y
296            @param
297                z The position of the new billboard realtive to the certer of the set
298            @param
299                colour Optional base colour of the billboard.
300            @returns
301                On success, a pointer to a newly created Billboard is
302                returned.
303            @par
304                On failiure (i.e. no more space and can't autoextend),
305                <b>NULL</b> is returned.
306            @see
307                BillboardSet::setAutoextend
308        */
309        Billboard* createBillboard(
310            Real x, Real y, Real z,
311            const ColourValue& colour = ColourValue::White );
312
313        /** Returns the number of active billboards which currently make up this set.
314        */
315        virtual int getNumBillboards(void) const;
316
317        /** Tells the set whether to allow automatic extension of the pool of billboards.
318            @remarks
319                A BillboardSet stores a pool of pre-constructed billboards which are used as needed when
320                a new billboard is requested. This allows applications to create / remove billboards efficiently
321                without incurring construction / destruction costs (a must for sets with lots of billboards like
322                particle effects). This method allows you to configure the behaviour when a new billboard is requested
323                but the billboard pool has been exhausted.
324            @par
325                The default behaviour is to allow the pool to extend (typically this allocates double the current
326                pool of billboards when the pool is expended), equivalent to calling this method with
327                autoExtend = true. If you set the parameter to false however, any attempt to create a new billboard
328                when the pool has expired will simply fail silently, returning a null pointer.
329            @param autoextend true to double the pool every time it runs out, false to fail silently.
330        */
331        virtual void setAutoextend(bool autoextend);
332
333        /** Returns true if the billboard pool automatically extends.
334            @see
335                BillboardSet::setAutoextend
336        */
337        virtual bool getAutoextend(void) const;
338
339        /** Adjusts the size of the pool of billboards available in this set.
340            @remarks
341                See the BillboardSet::setAutoextend method for full details of the billboard pool. This method adjusts
342                the preallocated size of the pool. If you try to reduce the size of the pool, the set has the option
343                of ignoring you if too many billboards are already in use. Bear in mind that calling this method will
344                incur significant construction / destruction calls so should be avoided in time-critical code. The same
345                goes for auto-extension, try to avoid it by estimating the pool size correctly up-front.
346            @param
347                size The new size for the pool.
348        */
349        virtual void setPoolSize(unsigned int size);
350
351        /** Returns the current size of the billboard pool.
352            @returns
353                The current size of the billboard pool.
354            @see
355                BillboardSet::setAutoextend
356        */
357        virtual unsigned int getPoolSize(void) const;
358
359
360        /** Empties this set of all billboards.
361        */
362        virtual void clear();
363
364        /** Returns a pointer to the billboard at the supplied index.
365            @note
366                This method requires linear time since the billboard list is a linked list.
367            @param
368                index The index of the billboard that is requested.
369            @returns
370                On success, a valid pointer to the requested billboard is
371                returned.
372            @par
373                On failiure, <b>NULL</b> is returned.
374        */
375        virtual Billboard* getBillboard(unsigned int index) const;
376
377        /** Removes the billboard at the supplied index.
378            @note
379                This method requires linear time since the billboard list is a linked list.
380        */
381        virtual void removeBillboard(unsigned int index);
382
383        /** Removes a billboard from the set.
384            @note
385                This version is more efficient than removing by index.
386        */
387        virtual void removeBillboard(Billboard* pBill);
388
389        /** Sets the point which acts as the origin point for all billboards in this set.
390            @remarks
391                This setting controls the fine tuning of where a billboard appears in relation to it's
392                position. It could be that a billboard's position represents it's center (e.g. for fireballs),
393                it could mean the center of the bottom edge (e.g. a tree which is positioned on the ground),
394                the top-left corner (e.g. a cursor).
395            @par
396                The default setting is BBO_CENTER.
397            @param
398                origin A member of the BillboardOrigin enum specifying the origin for all the billboards in this set.
399        */
400        virtual void setBillboardOrigin(BillboardOrigin origin);
401
402        /** Gets the point which acts as the origin point for all billboards in this set.
403            @returns
404                A member of the BillboardOrigin enum specifying the origin for all the billboards in this set.
405        */
406        virtual BillboardOrigin getBillboardOrigin(void) const;
407
408        /** Sets the default dimensions of the billboards in this set.
409            @remarks
410                All billboards in a set are created with these default dimensions. The set will render most efficiently if
411                all the billboards in the set are the default size. It is possible to alter the size of individual
412                billboards at the expense of extra calculation. See the Billboard class for more info.
413            @param width
414                The new default width for the billboards in this set.
415            @param height
416                The new default height for the billboards in this set.
417        */
418        virtual void setDefaultDimensions(Real width, Real height);
419
420        /** See setDefaultDimensions - this sets 1 component individually. */
421        virtual void setDefaultWidth(Real width);
422        /** See setDefaultDimensions - this gets 1 component individually. */
423        virtual Real getDefaultWidth(void) const;
424        /** See setDefaultDimensions - this sets 1 component individually. */
425        virtual void setDefaultHeight(Real height);
426        /** See setDefaultDimensions - this gets 1 component individually. */
427        virtual Real getDefaultHeight(void) const;
428
429        /** Sets the name of the material to be used for this billboard set.
430            @param
431                name The new name of the material to use for this set.
432        */
433        virtual void setMaterialName(const String& name);
434
435        /** Sets the name of the material to be used for this billboard set.
436            @returns The name of the material that is used for this set.
437        */
438        virtual const String& getMaterialName(void) const;
439
440        /** Overridden from MovableObject
441            @see
442                MovableObject
443        */
444        virtual void _notifyCurrentCamera(Camera* cam);
445
446        /** Begin injection of billboard data; applicable when
447            constructing the BillboardSet for external data use.
448        */
449        void beginBillboards(void);
450        /** Define a billboard. */
451        void injectBillboard(const Billboard& bb);
452        /** Finish defining billboards. */
453        void endBillboards(void);
454                /** Set the bounds of the BillboardSet.
455                @remarks
456                        You may need to call this if you're injecting billboards manually,
457                        and you're relying on the BillboardSet to determine culling.
458                */
459                void setBounds(const AxisAlignedBox& box, Real radius);
460
461
462        /** Overridden from MovableObject
463            @see
464                MovableObject
465        */
466        virtual const AxisAlignedBox& getBoundingBox(void) const;
467
468        /** Overridden from MovableObject
469            @see
470                MovableObject
471        */
472        virtual Real getBoundingRadius(void) const;
473        /** Overridden from MovableObject
474            @see
475                MovableObject
476        */
477        virtual void _updateRenderQueue(RenderQueue* queue);
478
479        /** Overridden from MovableObject
480            @see
481                MovableObject
482        */
483        virtual const MaterialPtr& getMaterial(void) const;
484
485        /** Overridden from MovableObject
486            @see
487                MovableObject
488        */
489        virtual void getRenderOperation(RenderOperation& op);
490
491        /** Overridden from MovableObject
492            @see
493                MovableObject
494        */
495        virtual void getWorldTransforms(Matrix4* xform) const;
496
497        /** @copydoc Renderable::getWorldOrientation */
498        const Quaternion& getWorldOrientation(void) const;
499        /** @copydoc Renderable::getWorldPosition */
500        const Vector3& getWorldPosition(void) const;
501        /** Internal callback used by Billboards to notify their parent that they have been resized.
502        */
503        virtual void _notifyBillboardResized(void);
504
505        /** Notifies the billboardset that texture coordinates will be modified
506            for this set. */
507        virtual void _notifyBillboardTextureCoordsModified(void) {
508            mFixedTextureCoords = false; }
509
510        /** Returns whether or not billbards in this are tested individually for culling. */
511        virtual bool getCullIndividually(void) const;
512        /** Sets whether culling tests billboards in this individually as well as in a group.
513        @remarks
514            Billboard sets are always culled as a whole group, based on a bounding box which
515            encloses all billboards in the set. For fairly localised sets, this is enough. However, you
516            can optionally tell the set to also cull individual billboards in the set, i.e. to test
517            each individual billboard before rendering. The default is not to do this.
518        @par
519            This is useful when you have a large, fairly distributed set of billboards, like maybe
520            trees on a landscape. You probably still want to group them into more than one
521            set (maybe one set per section of landscape), which will be culled coarsely, but you also
522            want to cull the billboards individually because they are spread out. Whilst you could have
523            lots of single-tree sets which are culled separately, this would be inefficient to render
524            because each tree would be issued as it's own rendering operation.
525        @par
526            By calling this method with a parameter of true, you can have large billboard sets which
527            are spaced out and so get the benefit of batch rendering and coarse culling, but also have
528            fine-grained culling so unnecessary rendering is avoided.
529        @param cullIndividual If true, each billboard is tested before being sent to the pipeline as well
530            as the whole set having to pass the coarse group bounding test.
531        */
532        virtual void setCullIndividually(bool cullIndividual);
533
534        /** Sets the type of billboard to render.
535        @remarks
536            The default sort of billboard (BBT_POINT), always has both x and y axes parallel to
537            the camera's local axes. This is fine for 'point' style billboards (e.g. flares,
538            smoke, anything which is symmetrical about a central point) but does not look good for
539            billboards which have an orientation (e.g. an elongated raindrop). In this case, the
540            oriented billboards are more suitable (BBT_ORIENTED_COMMON or BBT_ORIENTED_SELF) since they retain an independant Y axis
541            and only the X axis is generated, perpendicular to both the local Y and the camera Z.
542        @param bbt The type of billboard to render
543        */
544        virtual void setBillboardType(BillboardType bbt);
545
546        /** Returns the billboard type in use. */
547        virtual BillboardType getBillboardType(void) const;
548
549        /** Use this to specify the common direction given to billboards of type BBT_ORIENTED_COMMON.
550        @remarks
551            Use BBT_ORIENTED_COMMON when you want oriented billboards but you know they are always going to
552            be oriented the same way (e.g. rain in calm weather). It is faster for the system to calculate
553            the billboard vertices if they have a common direction.
554        @param vec The direction for all billboards.
555        */
556        virtual void setCommonDirection(const Vector3& vec);
557
558        /** Gets the common direction for all billboards (BBT_ORIENTED_COMMON) */
559        virtual const Vector3& getCommonDirection(void) const;
560
561        /** Overridden from MovableObject */
562        virtual const String& getName(void) const;
563
564        /** Overridden from MovableObject */
565        virtual const String& getMovableType(void) const;
566
567        /** Overridden, see Renderable */
568        Real getSquaredViewDepth(const Camera* cam) const;
569
570        /** Update the bounds of the billboardset */
571        virtual void _updateBounds(void);
572        /** @copydoc Renderable::getLights */
573        const LightList& getLights(void) const;
574
575        /** Sets whether billboards should be treated as being in world space.
576        @remarks
577            This is most useful when you are driving the billboard set from
578            an external data source.
579        */
580        virtual void setBillboardsInWorldSpace(bool ws) { mWorldSpace = ws; }
581
582    };
583
584}
585
586
587#endif
Note: See TracBrowser for help on using the repository browser.