1 #include <osgAnimation/Animation>
2 #include <osgDB/ObjectWrapper>
3 #include <osgDB/InputStream>
4 #include <osgDB/OutputStream>
5 
6 // reading channel helpers
7 
readChannel(osgDB::InputStream & is,osgAnimation::Channel * ch)8 static void readChannel( osgDB::InputStream& is, osgAnimation::Channel* ch )
9 {
10     std::string name, targetName;
11     is >> is.PROPERTY("Name"); is.readWrappedString(name);
12     is >> is.PROPERTY("TargetName"); is.readWrappedString(targetName);
13     ch->setName( name );
14     ch->setTargetName( targetName );
15 }
16 #include<osg/io_utils>
17 template <typename ContainerType, typename ValueType>
readContainer(osgDB::InputStream & is,ContainerType * container)18 static void readContainer( osgDB::InputStream& is, ContainerType* container )
19 {
20     typedef typename ContainerType::KeyType KeyType;
21     bool hasContainer = false;
22     is >> is.PROPERTY("KeyFrameContainer") >> hasContainer;
23     if ( hasContainer )
24     {
25         unsigned int size = 0;
26         size = is.readSize(); is >> is.BEGIN_BRACKET;
27         for ( unsigned int i=0; i<size; ++i )
28         {
29             double time = 0.0f;
30             ValueType value;
31             is >> time >> value;
32             container->push_back( KeyType(time, value) );
33         }
34         is >> is.END_BRACKET;
35     }
36 }
37 
38 template <typename ContainerType, typename ValueType, typename InternalValueType>
readContainer2(osgDB::InputStream & is,ContainerType * container)39 static void readContainer2( osgDB::InputStream& is, ContainerType* container )
40 {
41     typedef typename ContainerType::KeyType KeyType;
42     bool hasContainer = false;
43     is >> is.PROPERTY("KeyFrameContainer") >> hasContainer;
44     if ( hasContainer )
45     {
46         unsigned int size = 0;
47         size = is.readSize(); is >> is.BEGIN_BRACKET;
48         for ( unsigned int i=0; i<size; ++i )
49         {
50             double time = 0.0f;
51             InternalValueType pos, ptIn, ptOut;
52             is >> time >> pos >> ptIn >> ptOut;
53             container->push_back( KeyType(time, ValueType(pos, ptIn, ptOut)) );
54         }
55         is >> is.END_BRACKET;
56     }
57 }
58 
59 #define READ_CHANNEL_FUNC( NAME, CHANNEL, CONTAINER, VALUE ) \
60     if ( type==#NAME ) { \
61         CHANNEL* ch = new CHANNEL; \
62         readChannel( is, ch ); \
63         readContainer<CONTAINER, VALUE>( is, ch->getOrCreateSampler()->getOrCreateKeyframeContainer() ); \
64         is >> is.END_BRACKET; \
65         if ( ch ) ani.addChannel( ch ); \
66         continue; \
67     }
68 
69 #define READ_CHANNEL_FUNC2( NAME, CHANNEL, CONTAINER, VALUE, INVALUE ) \
70     if ( type==#NAME ) { \
71         CHANNEL* ch = new CHANNEL; \
72         readChannel( is, ch ); \
73         readContainer2<CONTAINER, VALUE, INVALUE>( is, ch->getOrCreateSampler()->getOrCreateKeyframeContainer() ); \
74         is >> is.END_BRACKET; \
75         if ( ch ) ani.addChannel( ch ); \
76         continue; \
77     }
78 
79 // writing channel helpers
80 
writeChannel(osgDB::OutputStream & os,osgAnimation::Channel * ch)81 static void writeChannel( osgDB::OutputStream& os, osgAnimation::Channel* ch )
82 {
83     os << os.PROPERTY("Name"); os.writeWrappedString(ch->getName()); os << std::endl;
84     os << os.PROPERTY("TargetName");os.writeWrappedString(ch->getTargetName()); os << std::endl;
85 }
86 
87 template <typename ContainerType>
writeContainer(osgDB::OutputStream & os,ContainerType * container)88 static void writeContainer( osgDB::OutputStream& os, ContainerType* container )
89 {
90     os << os.PROPERTY("KeyFrameContainer") << (container!=NULL);
91     if ( container!=NULL )
92     {
93         os.writeSize(container->size()); os << os.BEGIN_BRACKET << std::endl;
94         for ( unsigned int i=0; i<container->size(); ++i )
95         {
96             os << (*container)[i].getTime() << (*container)[i].getValue() << std::endl;
97         }
98         os << os.END_BRACKET;
99     }
100     os << std::endl;
101 }
102 
103 template <typename ContainerType>
writeContainer2(osgDB::OutputStream & os,ContainerType * container)104 static void writeContainer2( osgDB::OutputStream& os, ContainerType* container )
105 {
106     typedef typename ContainerType::KeyType KeyType;
107     os << os.PROPERTY("KeyFrameContainer") << (container!=NULL);
108     if ( container!=NULL )
109     {
110         os.writeSize(container->size()); os << os.BEGIN_BRACKET << std::endl;
111         for ( unsigned int i=0; i<container->size(); ++i )
112         {
113             const KeyType& keyframe = (*container)[i];
114             os << keyframe.getTime() << keyframe.getValue().getPosition()
115                << keyframe.getValue().getControlPointIn()
116                << keyframe.getValue().getControlPointOut() << std::endl;
117         }
118         os << os.END_BRACKET;
119     }
120     os << std::endl;
121 }
122 
123 #define WRITE_CHANNEL_FUNC( NAME, CHANNEL, CONTAINER ) \
124     CHANNEL* ch_##NAME = dynamic_cast<CHANNEL*>(ch); \
125     if ( ch_##NAME ) { \
126         os << os.PROPERTY("Type") << std::string(#NAME) << os.BEGIN_BRACKET << std::endl; \
127         writeChannel( os, ch_##NAME ); \
128         writeContainer<CONTAINER>( os, ch_##NAME ->getSamplerTyped()->getKeyframeContainerTyped() ); \
129         os << os.END_BRACKET << std::endl; \
130         continue; \
131     }
132 
133 #define WRITE_CHANNEL_FUNC2( NAME, CHANNEL, CONTAINER ) \
134     CHANNEL* ch_##NAME = dynamic_cast<CHANNEL*>(ch); \
135     if ( ch_##NAME ) { \
136         os << os.PROPERTY("Type") << #NAME << os.BEGIN_BRACKET << std::endl; \
137         writeChannel( os, ch_##NAME ); \
138         writeContainer2<CONTAINER>( os, ch_##NAME ->getSamplerTyped()->getKeyframeContainerTyped() ); \
139         os << os.END_BRACKET << std::endl; \
140         continue; \
141     }
142 
143 // _channels
144 
checkChannels(const osgAnimation::Animation & ani)145 static bool checkChannels( const osgAnimation::Animation& ani )
146 {
147     return ani.getChannels().size()>0;
148 }
149 
readChannels(osgDB::InputStream & is,osgAnimation::Animation & ani)150 static bool readChannels( osgDB::InputStream& is, osgAnimation::Animation& ani )
151 {
152     unsigned int size = is.readSize(); is >> is.BEGIN_BRACKET;
153     for ( unsigned int i=0; i<size; ++i )
154     {
155         std::string type;
156         is >> is.PROPERTY("Type") >> type >> is.BEGIN_BRACKET;
157 
158         READ_CHANNEL_FUNC( DoubleStepChannel, osgAnimation::DoubleStepChannel, osgAnimation::DoubleKeyframeContainer, double );
159         READ_CHANNEL_FUNC( FloatStepChannel, osgAnimation::FloatStepChannel, osgAnimation::FloatKeyframeContainer, float );
160         READ_CHANNEL_FUNC( Vec2StepChannel, osgAnimation::Vec2StepChannel, osgAnimation::Vec2KeyframeContainer, osg::Vec2 );
161         READ_CHANNEL_FUNC( Vec3StepChannel, osgAnimation::Vec3StepChannel, osgAnimation::Vec3KeyframeContainer, osg::Vec3 );
162         READ_CHANNEL_FUNC( Vec4StepChannel, osgAnimation::Vec4StepChannel, osgAnimation::Vec4KeyframeContainer, osg::Vec4 );
163         READ_CHANNEL_FUNC( QuatStepChannel, osgAnimation::QuatStepChannel, osgAnimation::QuatKeyframeContainer, osg::Quat );
164         READ_CHANNEL_FUNC( DoubleLinearChannel, osgAnimation::DoubleLinearChannel, osgAnimation::DoubleKeyframeContainer, double );
165         READ_CHANNEL_FUNC( FloatLinearChannel, osgAnimation::FloatLinearChannel, osgAnimation::FloatKeyframeContainer, float );
166         READ_CHANNEL_FUNC( Vec2LinearChannel, osgAnimation::Vec2LinearChannel, osgAnimation::Vec2KeyframeContainer, osg::Vec2 );
167         READ_CHANNEL_FUNC( Vec3LinearChannel, osgAnimation::Vec3LinearChannel, osgAnimation::Vec3KeyframeContainer, osg::Vec3 );
168         READ_CHANNEL_FUNC( Vec4LinearChannel, osgAnimation::Vec4LinearChannel, osgAnimation::Vec4KeyframeContainer, osg::Vec4 );
169         READ_CHANNEL_FUNC( QuatSphericalLinearChannel, osgAnimation::QuatSphericalLinearChannel,
170                                                        osgAnimation::QuatKeyframeContainer, osg::Quat );
171         READ_CHANNEL_FUNC( MatrixLinearChannel, osgAnimation::MatrixLinearChannel,
172                                                 osgAnimation::MatrixKeyframeContainer, osg::Matrix );
173         READ_CHANNEL_FUNC2( FloatCubicBezierChannel, osgAnimation::FloatCubicBezierChannel,
174                                                      osgAnimation::FloatCubicBezierKeyframeContainer,
175                                                      osgAnimation::FloatCubicBezier, float );
176         READ_CHANNEL_FUNC2( DoubleCubicBezierChannel, osgAnimation::DoubleCubicBezierChannel,
177                                                       osgAnimation::DoubleCubicBezierKeyframeContainer,
178                                                       osgAnimation::DoubleCubicBezier, double );
179         READ_CHANNEL_FUNC2( Vec2CubicBezierChannel, osgAnimation::Vec2CubicBezierChannel,
180                                                     osgAnimation::Vec2CubicBezierKeyframeContainer,
181                                                     osgAnimation::Vec2CubicBezier, osg::Vec2 );
182         READ_CHANNEL_FUNC2( Vec3CubicBezierChannel, osgAnimation::Vec3CubicBezierChannel,
183                                                     osgAnimation::Vec3CubicBezierKeyframeContainer,
184                                                     osgAnimation::Vec3CubicBezier, osg::Vec3 );
185         READ_CHANNEL_FUNC2( Vec4CubicBezierChannel, osgAnimation::Vec4CubicBezierChannel,
186                                                     osgAnimation::Vec4CubicBezierKeyframeContainer,
187                                                     osgAnimation::Vec4CubicBezier, osg::Vec4 );
188         is.advanceToCurrentEndBracket();
189     }
190     is >> is.END_BRACKET;
191     return true;
192 }
193 
writeChannels(osgDB::OutputStream & os,const osgAnimation::Animation & ani)194 static bool writeChannels( osgDB::OutputStream& os, const osgAnimation::Animation& ani )
195 {
196     const osgAnimation::ChannelList& channels = ani.getChannels();
197     os.writeSize(channels.size()); os << os.BEGIN_BRACKET << std::endl;
198     for ( osgAnimation::ChannelList::const_iterator itr=channels.begin();
199           itr!=channels.end(); ++itr )
200     {
201         osgAnimation::Channel* ch = itr->get();
202         WRITE_CHANNEL_FUNC( DoubleStepChannel, osgAnimation::DoubleStepChannel, osgAnimation::DoubleKeyframeContainer );
203         WRITE_CHANNEL_FUNC( FloatStepChannel, osgAnimation::FloatStepChannel, osgAnimation::FloatKeyframeContainer );
204         WRITE_CHANNEL_FUNC( Vec2StepChannel, osgAnimation::Vec2StepChannel, osgAnimation::Vec2KeyframeContainer );
205         WRITE_CHANNEL_FUNC( Vec3StepChannel, osgAnimation::Vec3StepChannel, osgAnimation::Vec3KeyframeContainer );
206         WRITE_CHANNEL_FUNC( Vec4StepChannel, osgAnimation::Vec4StepChannel, osgAnimation::Vec4KeyframeContainer );
207         WRITE_CHANNEL_FUNC( QuatStepChannel, osgAnimation::QuatStepChannel, osgAnimation::QuatKeyframeContainer );
208         WRITE_CHANNEL_FUNC( DoubleLinearChannel, osgAnimation::DoubleLinearChannel, osgAnimation::DoubleKeyframeContainer );
209         WRITE_CHANNEL_FUNC( FloatLinearChannel, osgAnimation::FloatLinearChannel, osgAnimation::FloatKeyframeContainer );
210         WRITE_CHANNEL_FUNC( Vec2LinearChannel, osgAnimation::Vec2LinearChannel, osgAnimation::Vec2KeyframeContainer );
211         WRITE_CHANNEL_FUNC( Vec3LinearChannel, osgAnimation::Vec3LinearChannel, osgAnimation::Vec3KeyframeContainer );
212         WRITE_CHANNEL_FUNC( Vec4LinearChannel, osgAnimation::Vec4LinearChannel, osgAnimation::Vec4KeyframeContainer );
213         WRITE_CHANNEL_FUNC( QuatSphericalLinearChannel, osgAnimation::QuatSphericalLinearChannel,
214                                                          osgAnimation::QuatKeyframeContainer );
215         WRITE_CHANNEL_FUNC( MatrixLinearChannel, osgAnimation::MatrixLinearChannel,
216                                                  osgAnimation::MatrixKeyframeContainer );
217         WRITE_CHANNEL_FUNC2( FloatCubicBezierChannel, osgAnimation::FloatCubicBezierChannel,
218                                                       osgAnimation::FloatCubicBezierKeyframeContainer );
219         WRITE_CHANNEL_FUNC2( DoubleCubicBezierChannel, osgAnimation::DoubleCubicBezierChannel,
220                                                        osgAnimation::DoubleCubicBezierKeyframeContainer );
221         WRITE_CHANNEL_FUNC2( Vec2CubicBezierChannel, osgAnimation::Vec2CubicBezierChannel,
222                                                      osgAnimation::Vec2CubicBezierKeyframeContainer );
223         WRITE_CHANNEL_FUNC2( Vec3CubicBezierChannel, osgAnimation::Vec3CubicBezierChannel,
224                                                      osgAnimation::Vec3CubicBezierKeyframeContainer );
225         WRITE_CHANNEL_FUNC2( Vec4CubicBezierChannel, osgAnimation::Vec4CubicBezierChannel,
226                                                      osgAnimation::Vec4CubicBezierKeyframeContainer );
227 
228         os << os.PROPERTY("Type") << std::string("UnknownChannel") << os.BEGIN_BRACKET << std::endl;
229         os << os.END_BRACKET << std::endl;
230     }
231     os << os.END_BRACKET << std::endl;
232     return true;
233 }
234 
235 REGISTER_OBJECT_WRAPPER( osgAnimation_Animation,
236                          new osgAnimation::Animation,
237                          osgAnimation::Animation,
238                          "osg::Object osgAnimation::Animation" )
239 {
240     ADD_DOUBLE_SERIALIZER( Duration, 0.0f );  // _duration
241     ADD_FLOAT_SERIALIZER( Weight, 0.0f );  // _weight
242     ADD_DOUBLE_SERIALIZER( StartTime, 0.0f );  // _startTime
243 
244     BEGIN_ENUM_SERIALIZER( PlayMode, LOOP );
245         ADD_ENUM_VALUE( ONCE );
246         ADD_ENUM_VALUE( STAY );
247         ADD_ENUM_VALUE( LOOP );
248         ADD_ENUM_VALUE( PPONG );
249     END_ENUM_SERIALIZER();  // _playmode
250 
251     ADD_USER_SERIALIZER( Channels );  // _channels
252 }
253