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