~ubuntu-branches/ubuntu/quantal/aqsis/quantal

« back to all changes in this revision

Viewing changes to libs/core/motion.h

  • Committer: Bazaar Package Importer
  • Author(s): Fabrice Coutadeur
  • Date: 2009-08-06 04:53:26 UTC
  • mfrom: (1.2.3 upstream)
  • Revision ID: james.westby@ubuntu.com-20090806045326-z6xeaaao62idxcc6
Tags: 1.6.0-0ubuntu1
* New upstream release
* debian/control:
  - changed name of lib package to libaqsis1 instead of aqsis-libsc2a
  - changed name of dev package to libaqsis-dev instead of aqsis-libs-dev
  - Added aqsis-data package
  - Revised summary text according to that specified by the RISpec (Pixar)
* Moved examples installation from aqsis.install to aqsis-data.install
* debian/rules: 
  - added content to binary-indep target
* debian/rules: added explicit name of mime file to force dh_installmime
  to generate postinst and prerm scripts

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
// Aqsis
 
2
// Copyright (C) 1997 - 2001, Paul C. Gregory
 
3
//
 
4
// Contact: pgregory@aqsis.org
 
5
//
 
6
// This library is free software; you can redistribute it and/or
 
7
// modify it under the terms of the GNU General Public
 
8
// License as published by the Free Software Foundation; either
 
9
// version 2 of the License, or (at your option) any later version.
 
10
//
 
11
// This library is distributed in the hope that it will be useful,
 
12
// but WITHOUT ANY WARRANTY; without even the implied warranty of
 
13
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 
14
// General Public License for more details.
 
15
//
 
16
// You should have received a copy of the GNU General Public
 
17
// License along with this library; if not, write to the Free Software
 
18
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 
19
 
 
20
 
 
21
/** \file
 
22
                \brief Declares the CqMotionSpec template class for handling any class capable of being motion blurred.
 
23
                \author Paul C. Gregory (pgregory@aqsis.org)
 
24
*/
 
25
 
 
26
//? Is .h included already?
 
27
#ifndef MOTION_H_INCLUDED
 
28
#define MOTION_H_INCLUDED 1
 
29
 
 
30
#include        <vector>
 
31
 
 
32
#include        <aqsis/aqsis.h>
 
33
 
 
34
#include        <aqsis/ri/ri.h>
 
35
 
 
36
namespace Aqsis {
 
37
 
 
38
 
 
39
//----------------------------------------------------------------------
 
40
/** \class CqMotionSpec
 
41
 * Abstract base class from which all classes supporting motion blur should derive.
 
42
 */
 
43
 
 
44
template <class T>
 
45
class CqMotionSpec
 
46
{
 
47
        public:
 
48
                /** Default constructor.
 
49
                 * \param a The default value for the motion object, used when expanding the timeslots.
 
50
                 */
 
51
                CqMotionSpec( const T& a )
 
52
                {
 
53
                        m_DefObject = a;
 
54
                        //AddTimeSlot(0.0f, a);
 
55
                }
 
56
                /** Copy constructor.
 
57
                 */
 
58
                CqMotionSpec( const CqMotionSpec<T>& From )
 
59
                {
 
60
                        *this = From;
 
61
                }
 
62
                virtual ~CqMotionSpec()
 
63
                {
 
64
                        //for(std::vector<T>::iterator i=m_aObjects.begin(); i<m_aObjects.end(); i++)
 
65
                        //      ClearMotionObject((*i));
 
66
                }
 
67
 
 
68
                /** Assignment operator.
 
69
                 */
 
70
                void    operator=( const CqMotionSpec<T>& From )
 
71
                {
 
72
                        m_aTimes.clear();
 
73
                        m_aObjects.clear();
 
74
                        for ( std::vector<TqFloat>::const_iterator t = From.m_aTimes.begin(); t<From.m_aTimes.end(); t++ )
 
75
                                m_aTimes.push_back( *t );
 
76
                        for( typename std::vector<T>::const_iterator o = From.m_aObjects.begin(); o<From.m_aObjects.end(); o++ )
 
77
                                m_aObjects.push_back( *o );
 
78
                        m_DefObject = From.m_DefObject;
 
79
                }
 
80
 
 
81
                /** Put the specified motion object at the specified time, create a new timeslot if none exists,
 
82
                 * else overwrite the existing value.
 
83
                 * \param time The frame time to place the new object at.
 
84
                 * \param Object The new object to put in the timeslot.
 
85
                 */
 
86
                void    AddTimeSlot( TqFloat time, const T& Object )
 
87
                {
 
88
                        TqInt iIndex;
 
89
                        if ( cTimes() == 0 )
 
90
                        {
 
91
                                m_aTimes.push_back( time );
 
92
                                m_aObjects.push_back( Object );
 
93
                                return ;
 
94
                        }
 
95
 
 
96
                        if ( TimeSlotExists( time, iIndex ) )
 
97
                        {
 
98
                                ClearMotionObject( m_aObjects[ iIndex ] );
 
99
                                m_aObjects[ iIndex ] = Object;
 
100
                        }
 
101
                        else
 
102
                        {
 
103
                                // Insert the timeslot at the proper place.
 
104
                                std::vector<TqFloat>::iterator itime = m_aTimes.begin();
 
105
                                typename std::vector<T>::iterator iobj = m_aObjects.begin();
 
106
                                while ( itime != m_aTimes.end() && *itime < time )
 
107
                                        itime++, iobj++;
 
108
                                m_aTimes.insert( itime, time );
 
109
                                m_aObjects.insert( iobj, Object );
 
110
                        }
 
111
                }
 
112
                /** Combine the specified motion object with any existing one at the specified time.
 
113
                 * Will create a new timeslot if none exists.
 
114
                 * \param time The time of the relevant timeslot.
 
115
                 * \param Object The new obejct to combine with any existing one.
 
116
                 */
 
117
                void    ConcatTimeSlot( TqFloat time, const T& Object )
 
118
                {
 
119
                        TqInt iIndex;
 
120
                        if ( TimeSlotExists( time, iIndex ) )
 
121
                                m_aObjects[ iIndex ] = ConcatMotionObjects( m_aObjects[ iIndex ], Object );
 
122
                        else
 
123
                        {
 
124
                                // Add a new slot a nd set it to the default value before concatenating the
 
125
                                // specified value.
 
126
                                AddTimeSlot( time, m_DefObject );
 
127
                                TimeSlotExists( time, iIndex );
 
128
                                m_aObjects[ iIndex ] = ConcatMotionObjects( m_aObjects[ iIndex ], Object );
 
129
                        }
 
130
                }
 
131
                /** Combine the specified motion object with all timeslots.
 
132
                 * \param Object The object to combine.
 
133
                 */
 
134
                void    ConcatAllTimeSlots( const T& Object )
 
135
                {
 
136
                        for ( typename std::vector<T>::iterator i = m_aObjects.begin(); i<m_aObjects.end(); i++ )
 
137
                                ( *i ) = ConcatMotionObjects( ( *i ), Object );
 
138
                }
 
139
                /** Get the frame time at the specified timeslot index.
 
140
                 * \param index The timeslot index/
 
141
                 * \return Float frame time.
 
142
                 */
 
143
                TqFloat Time( TqInt index )
 
144
                const
 
145
                {
 
146
                        if ( m_aTimes.size() == 0 )
 
147
                                return ( 0.0f );
 
148
                        else if ( index < 0 )
 
149
                                return ( m_aTimes[ 0 ] );
 
150
                        else if ( index < cTimes() )
 
151
                                return ( m_aTimes[ index ] );
 
152
                        else
 
153
                                return ( m_aTimes.back() );
 
154
                }
 
155
                /** Get the number of timeslots.
 
156
                 * \return Integer timeslot count.
 
157
                 */
 
158
                TqInt   cTimes() const
 
159
                {
 
160
                        return ( m_aTimes.size() );
 
161
                }
 
162
                /** Return whether this motion block is actually motion blurred or not.
 
163
                 * \return Boolean indicating motion blurred.
 
164
                 */
 
165
                bool    fMotionBlurred() const
 
166
                {
 
167
                        return ( cTimes() > 1 );
 
168
                }
 
169
                /** Get the index of the timeslot for the specified time, and if not exact, the fractional
 
170
                 * distance between it and the following timeslot 0-1.
 
171
                 * \param time Float frame time.
 
172
                 * \param iIndex Reference to the integer index to fill in.
 
173
                 * \param Fraction Reference to the float fraction to fill in.
 
174
                 * \return Boolean indicating the index is exact.
 
175
                 */
 
176
                bool    GetTimeSlot( TqFloat time, TqInt& iIndex, TqFloat& Fraction ) const
 
177
                {
 
178
                        assert( cTimes() > 0 );
 
179
 
 
180
                        if ( time >= m_aTimes.back() )
 
181
                        {
 
182
                                iIndex = m_aTimes.size() - 1;
 
183
                                return ( true );
 
184
                        }
 
185
                        else if ( time <= m_aTimes.front() )
 
186
                        {
 
187
                                iIndex = 0;
 
188
                                return ( true );
 
189
                        }
 
190
                        else
 
191
                        {
 
192
                                // Find the appropriate time span.
 
193
                                iIndex = 0;
 
194
                                while ( time >= m_aTimes[ iIndex + 1 ] )
 
195
                                        iIndex += 1;
 
196
                                Fraction = ( time - m_aTimes[ iIndex ] ) / ( m_aTimes[ iIndex + 1 ] - m_aTimes[ iIndex ] );
 
197
                                return ( m_aTimes[ iIndex ] == time );
 
198
                        }
 
199
                }
 
200
                /** Get the index of the timeslot for the specified time, if it exists.
 
201
                 * \param time Float frame time.
 
202
                 * \param iIndex Reference to the integer index to fill in.
 
203
                 * \return Boolean indicating the index exists.
 
204
                 */
 
205
                bool    TimeSlotExists( TqFloat time, TqInt& iIndex ) const
 
206
                {
 
207
                        //assert( cTimes() > 0 );
 
208
                        //assert(time>=0.0f);
 
209
 
 
210
                        // Find the appropriate time span.
 
211
                        iIndex = 0;
 
212
                        while ( iIndex < cTimes() && time != m_aTimes[ iIndex ] )
 
213
                                iIndex += 1;
 
214
                        return ( iIndex < cTimes() );
 
215
                }
 
216
                /** Get the motion object at the specified time using linearinterpolation as appropriate.
 
217
                 * \param time Float frame time.
 
218
                 * \return New object representing the motion object at the specified time.
 
219
                 */
 
220
                T       GetMotionObjectInterpolated( TqFloat time ) const
 
221
                {
 
222
                        TqInt iIndex;
 
223
                        TqFloat Fraction;
 
224
                        if ( GetTimeSlot( time, iIndex, Fraction ) )
 
225
                                return ( m_aObjects[ iIndex ] );
 
226
                        else
 
227
                                return ( LinearInterpolateMotionObjects( Fraction, m_aObjects[ iIndex ], m_aObjects[ iIndex + 1 ] ) );
 
228
                }
 
229
 
 
230
                /** Get the motion object at the specified time, will only work if the timeslot exists.
 
231
                 * \param time Float frame time.
 
232
                 * \return Reference to the object at the appropriate timeslot.
 
233
                 */
 
234
                const   T&      GetMotionObject( TqFloat time ) const
 
235
                {
 
236
                        TqInt iIndex;
 
237
                        TqFloat Fraction;
 
238
                        if ( GetTimeSlot( time, iIndex, Fraction ) )
 
239
                                return ( m_aObjects[ iIndex ] );
 
240
                        else
 
241
                        {
 
242
                                assert( false );
 
243
                                return ( m_DefObject );
 
244
                        }
 
245
                }
 
246
 
 
247
                const T& GetDefaultObject() const
 
248
                {
 
249
                        return(m_DefObject);
 
250
                }
 
251
 
 
252
                /** Get the motion object at the specified index.
 
253
                 * \param iIndex Index in the array of time slots.
 
254
                 * \return Reference to the object at the appropriate timeslot.
 
255
                 */
 
256
                const   T&      GetMotionObject( TqInt iIndex ) const
 
257
                {
 
258
                        assert( iIndex >= 0 && iIndex < cTimes() );
 
259
                        return ( m_aObjects[ iIndex ] );
 
260
                }
 
261
 
 
262
                /** Set the motion object to use as the default when expanding the timeslot list.
 
263
                 * \param a The new default motion object.
 
264
                 */
 
265
                void    SetDefaultObject( const T& a )
 
266
                {
 
267
                        m_DefObject = a;
 
268
                }
 
269
 
 
270
                /** Empty all keyframes
 
271
                 *
 
272
                 */
 
273
                void    Reset()
 
274
                {
 
275
                        m_aTimes.clear();
 
276
                        typename std::vector<T>::iterator i;
 
277
                        for(i=m_aObjects.begin(); i!=m_aObjects.end(); i++)
 
278
                                ClearMotionObject(*i);
 
279
                        m_aObjects.clear();
 
280
                }
 
281
 
 
282
                /** Pure virtual, overridden by deriving classes. Clear a motion object.
 
283
                 */
 
284
                virtual void    ClearMotionObject( T& A ) const = 0;
 
285
                /** Pure virtual, overridden by deriving classes. Combine motion obects.
 
286
                 */
 
287
                virtual T       ConcatMotionObjects( const T& A, const T& B ) const = 0;
 
288
                /** Pure virtual, overridden by deriving classes. Linear interpolate between motion objects.
 
289
                 */
 
290
                virtual T       LinearInterpolateMotionObjects( TqFloat Fraction, const T& A, const T& B ) const = 0;
 
291
 
 
292
        private:
 
293
                std::vector<TqFloat>    m_aTimes;               ///< Array of float timeslot times.
 
294
                std::vector<T>  m_aObjects;             ///< Array of motion objects for each timeslot.
 
295
                T       m_DefObject;    ///< Default motion object, used when expanding the list of timeslots.
 
296
}
 
297
;
 
298
 
 
299
 
 
300
//-----------------------------------------------------------------------
 
301
 
 
302
} // namespace Aqsis
 
303
 
 
304
#endif // MOTION_H_INCLUDED