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 __RibbonTrail_H__
30 #define __RibbonTrail_H__
31 
32 #include "OgrePrerequisites.h"
33 
34 #include "OgreBillboardChain.h"
35 #include "OgreNode.h"
36 #include "OgreControllerManager.h"
37 #include "OgreHeaderPrefix.h"
38 
39 namespace Ogre {
40 
41     /** \addtogroup Core
42     *  @{
43     */
44     /** \addtogroup Effects
45     *  @{
46     */
47     /** Subclass of BillboardChain which automatically leaves a trail behind
48         one or more Node instances.
49     @remarks
50         An instance of this class will watch one or more Node instances, and
51         automatically generate a trail behind them as they move. Because this
52         class can monitor multiple modes, it generates its own geometry in
53         world space and thus, even though it has to be attached to a SceneNode
54         to be visible, changing the position of the scene node it is attached to
55         makes no difference to the geometry rendered.
56     @par
57         The 'head' element grows smoothly in size until it reaches the required size,
58         then a new element is added. If the segment is full, the tail element
59         shrinks by the same proportion as the head grows before disappearing.
60     @par
61         Elements can be faded out on a time basis, either by altering their colour
62         or altering their alpha. The width can also alter over time.
63     @par
64         'v' texture coordinates are fixed at 0.0 if used, meaning that you can
65         use a 1D texture to 'smear' a colour pattern along the ribbon if you wish.
66         The 'u' coordinates are by default (0.0, 1.0), but you can alter this
67         using setOtherTexCoordRange if you wish.
68     */
69     class _OgreExport RibbonTrail : public BillboardChain, public Node::Listener
70     {
71     public:
72         /** Constructor (don't use directly, use factory)
73         @param name The name to give this object
74         @param maxElements The maximum number of elements per chain
75         @param numberOfChains The number of separate chain segments contained in this object,
76             ie the maximum number of nodes that can have trails attached
77         @param useTextureCoords If true, use texture coordinates from the chain elements
78         @param useVertexColours If true, use vertex colours from the chain elements (must
79             be true if you intend to use fading)
80         */
81         RibbonTrail(const String& name, size_t maxElements = 20, size_t numberOfChains = 1,
82             bool useTextureCoords = true, bool useVertexColours = true);
83         /// destructor
84         virtual ~RibbonTrail();
85 
86         typedef std::vector<Node*> NodeList;
87         typedef ConstVectorIterator<NodeList> NodeIterator;
88 
89         /** Add a node to be tracked.
90         @param n The node that will be tracked.
91         */
92         virtual void addNode(Node* n);
93         /** Remove tracking on a given node. */
94         virtual void removeNode(const Node* n);
95         /** Get an iterator over the nodes which are being tracked. */
96         virtual NodeIterator getNodeIterator(void) const;
97         /** Get the chain index for a given Node being tracked. */
98         virtual size_t getChainIndexForNode(const Node* n);
99 
100         /** Set the length of the trail.
101         @remarks
102             This sets the length of the trail, in world units. It also sets how
103             far apart each segment will be, ie length / max_elements.
104         @param len The length of the trail in world units
105         */
106         virtual void setTrailLength(Real len);
107         /** Get the length of the trail. */
getTrailLength(void)108         virtual Real getTrailLength(void) const { return mTrailLength; }
109 
110         /** @copydoc BillboardChain::setMaxChainElements */
111         void setMaxChainElements(size_t maxElements);
112         /** @copydoc BillboardChain::setNumberOfChains */
113         void setNumberOfChains(size_t numChains);
114         /** @copydoc BillboardChain::clearChain */
115         void clearChain(size_t chainIndex);
116 
117         /** Set the starting ribbon colour for a given segment.
118         @param chainIndex The index of the chain
119         @param col The initial colour
120         @note
121             Only used if this instance is using vertex colours.
122         */
123         virtual void setInitialColour(size_t chainIndex, const ColourValue& col);
124         /** Set the starting ribbon colour.
125         @param chainIndex The index of the chain
126         @param r,b,g,a The initial colour
127         @note
128             Only used if this instance is using vertex colours.
129         */
130         virtual void setInitialColour(size_t chainIndex, float r, float g, float b, float a = 1.0);
131         /** Get the starting ribbon colour. */
132         virtual const ColourValue& getInitialColour(size_t chainIndex) const;
133 
134         /** Enables / disables fading the trail using colour.
135         @param chainIndex The index of the chain
136         @param valuePerSecond The amount to subtract from colour each second
137         */
138         virtual void setColourChange(size_t chainIndex, const ColourValue& valuePerSecond);
139 
140         /** Set the starting ribbon width in world units.
141         @param chainIndex The index of the chain
142         @param width The initial width of the ribbon
143         */
144         virtual void setInitialWidth(size_t chainIndex, Real width);
145         /** Get the starting ribbon width in world units. */
146         virtual Real getInitialWidth(size_t chainIndex) const;
147 
148         /** Set the change in ribbon width per second.
149         @param chainIndex The index of the chain
150         @param widthDeltaPerSecond The amount the width will reduce by per second
151         */
152         virtual void setWidthChange(size_t chainIndex, Real widthDeltaPerSecond);
153         /** Get the change in ribbon width per second. */
154         virtual Real getWidthChange(size_t chainIndex) const;
155 
156         /** Enables / disables fading the trail using colour.
157         @param chainIndex The index of the chain
158         @param r,g,b,a The amount to subtract from each colour channel per second
159         */
160         virtual void setColourChange(size_t chainIndex, float r, float g, float b, float a);
161 
162         /** Get the per-second fading amount */
163         virtual const ColourValue& getColourChange(size_t chainIndex) const;
164 
165         /// @see Node::Listener::nodeUpdated
166         void nodeUpdated(const Node* node);
167         /// @see Node::Listener::nodeDestroyed
168         void nodeDestroyed(const Node* node);
169 
170         /// Perform any fading / width delta required; internal method
171         virtual void _timeUpdate(Real time);
172 
173         /** Overridden from MovableObject */
174         const String& getMovableType(void) const;
175 
176     protected:
177         /// List of nodes being trailed
178         NodeList mNodeList;
179         /// Mapping of nodes to chain segments
180         typedef std::vector<size_t> IndexVector;
181         /// Ordered like mNodeList, contains chain index
182         IndexVector mNodeToChainSegment;
183         // chains not in use
184         IndexVector mFreeChains;
185 
186         // fast lookup node->chain index
187         // we use positional map too because that can be useful
188         typedef std::map<const Node*, size_t> NodeToChainSegmentMap;
189         NodeToChainSegmentMap mNodeToSegMap;
190 
191         /// Total length of trail in world units
192         Real mTrailLength;
193         /// length of each element
194         Real mElemLength;
195         /// Squared length of each element
196         Real mSquaredElemLength;
197         typedef std::vector<ColourValue> ColourValueList;
198         typedef std::vector<Real> RealList;
199         /// Initial colour of the ribbon
200         ColourValueList mInitialColour;
201         /// fade amount per second
202         ColourValueList mDeltaColour;
203         /// Initial width of the ribbon
204         RealList mInitialWidth;
205         /// Delta width of the ribbon
206         RealList mDeltaWidth;
207         /// controller used to hook up frame time to fader
208         Controller<Real>* mFadeController;
209         /// controller value for hooking up frame time to fader
210         ControllerValueRealPtr mTimeControllerValue;
211 
212         /// Manage updates to the time controller
213         virtual void manageController(void);
214         /// Node has changed position, update
215         virtual void updateTrail(size_t index, const Node* node);
216         /// Reset the tracked chain to initial state
217         virtual void resetTrail(size_t index, const Node* node);
218         /// Reset all tracked chains to initial state
219         virtual void resetAllTrails(void);
220 
221     };
222 
223 
224     /** Factory object for creating RibbonTrail instances */
225     class _OgreExport RibbonTrailFactory : public MovableObjectFactory
226     {
227     protected:
228         MovableObject* createInstanceImpl( const String& name, const NameValuePairList* params);
229     public:
RibbonTrailFactory()230         RibbonTrailFactory() {}
~RibbonTrailFactory()231         ~RibbonTrailFactory() {}
232 
233         static String FACTORY_TYPE_NAME;
234 
235         const String& getType(void) const;
236         void destroyInstance( MovableObject* obj);
237 
238     };
239     /** @} */
240     /** @} */
241 
242 }
243 
244 #include "OgreHeaderSuffix.h"
245 
246 #endif
247