/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__ |