43 #ifdef GLS_ANIMATION_ENABLE_ZIP_LOADING
57 const std::string s_expectedVersion =
"1.0";
59 const char*
const s_animationCollectionTag =
"AnimationSequence";
60 const std::string s_animationPropertyTag =
"AnimationProperty";
62 const char*
const s_nameTag =
"name";
63 const char*
const s_typeTag =
"type";
65 const std::string s_floatTypeTag =
"float";
66 const std::string s_vec3fTypeTag =
"vec3f";
67 const std::string s_vec4fTypeTag =
"vec4f";
68 const std::string s_colorTypeTag =
"color";
69 const std::string s_stringTypeTag =
"string";
71 const char s_typeSeparator =
':';
73 const std::string s_keyTag =
"Key";
74 const char*
const s_timeTag =
"t";
75 const char*
const s_valueTag =
"v";
80 Value Destringify(
const std::string& str,
typename Detail::enable_if< !Detail::is_same< Value, std::string >::value >::type* = 0 )
82 std::istringstream iss( str );
90 Value Destringify(
const std::string& str,
typename Detail::enable_if< Detail::is_same< Value, std::string >::value >::type* = 0 )
97 typename GlsKeyframeCurve<Value>::PtrConst ParseKeyframes( tinyxml2::XMLElement*
const element,
const std::string& interpType,
const char*
const name )
105 typename GlsKeyframeCurve<Value>::Ptr curve(
new GlsKeyframeCurve<Value>( interpolator ) );
107 for( tinyxml2::XMLElement* elemChild = element->FirstChildElement(); elemChild != NULL; elemChild = elemChild->NextSiblingElement() )
109 if( s_keyTag == elemChild->Value() )
112 if(
const char* time = elemChild->Attribute( s_timeTag ) )
114 key = std::atof( time );
118 std::cerr <<
"LoadAnimationScript(): No key found for frame in '" << name <<
"'. Ignoring.\n";
122 std::string valueStr;
123 if(
const char* value = elemChild->Attribute( s_valueTag ) )
127 else if(
const char* text = elemChild->GetText() )
133 std::cerr <<
"LoadAnimationScript(): Key '" << key <<
"' did not have a value. Ignoring.\n";
137 curve->AddKeyframe( key, Destringify<Value>( valueStr ) );
144 GlsAnimation::Ptr LoadAnimation(
const std::vector<char>& file,
const std::string& name )
146 tinyxml2::XMLDocument doc;
147 if( doc.Parse( const_cast<char*>( &file[0] ), file.size()) != tinyxml2::XML_NO_ERROR )
149 std::cerr <<
"LoadAnimation(): Unable to parse script file " << name <<
". (Bad format?)\n";
153 tinyxml2::XMLNode* frames = doc.FirstChildElement( s_animationCollectionTag );
157 std::cerr <<
"LoadAnimation(): " << s_animationCollectionTag <<
" tag not found in " << name << std::endl;
162 tinyxml2::XMLElement* topElem = frames->ToElement();
163 DistiAssert( topElem );
164 const char* version = topElem->Attribute(
"version" );
165 if( !version || version != s_expectedVersion )
167 std::cerr <<
"LoadAnimation(): Unknown version number (found=" << (version ? version :
"no version")
168 <<
", expected=" << s_expectedVersion <<
")\n";
174 for( tinyxml2::XMLElement* child = frames->FirstChildElement(); child != NULL; child = child->NextSiblingElement())
176 const char* childValue = child->Value();
177 if( childValue && s_animationPropertyTag == childValue )
179 const char* animationName = child->Attribute( s_nameTag );
180 const char* rawType = child->Attribute( s_typeTag );
181 if( !rawType || !animationName )
183 std::cerr <<
"LoadAnimation(): Name and/or type tags not set(Name=" << (animationName ? animationName :
"Not Set")
184 <<
", type=" << (rawType ? rawType :
"Not Set") <<
")\n";
187 std::string baseType = rawType;
188 const std::size_t sepPos = baseType.find( s_typeSeparator );
189 std::string interpType = sepPos != std::string::npos ? baseType.substr( sepPos + 1 ) : std::string();
190 if( !interpType.empty() )
192 baseType = baseType.substr( 0, sepPos );
195 if( s_floatTypeTag == baseType )
198 if( curve && curve->GetKeyframeCount() > 0 )
200 animationSeq->Add(
new GlsKeyframeAnimation( name, animationName, curve ) );
203 else if( s_vec3fTypeTag == baseType )
206 if( curve && curve->GetKeyframeCount() > 0 )
208 animationSeq->Add(
new GlsKeyframeAnimation( name, animationName, curve ) );
211 else if( s_vec4fTypeTag == baseType )
214 if( curve && curve->GetKeyframeCount() > 0 )
216 animationSeq->Add(
new GlsKeyframeAnimation( name, animationName, curve ) );
219 else if( s_colorTypeTag == baseType )
222 if( curve && curve->GetKeyframeCount() > 0 )
224 animationSeq->Add(
new GlsKeyframeAnimation( name, animationName, curve ) );
227 else if( s_stringTypeTag == baseType )
231 std::cerr <<
"LoadAnimation(): Forcing string to gated interpolation: " << name <<
" of type " << rawType << std::endl;
234 if( curve && curve->GetKeyframeCount() > 0 )
236 animationSeq->Add(
new GlsKeyframeAnimation( name, animationName, curve ) );
241 std::cerr <<
"LoadAnimation(): Unknown type tag found (type=" << baseType.c_str()
242 <<
", name=" << animationName <<
"). Ignoring.\n";
247 std::cerr <<
"LoadAnimation(): Unknown property tag found (property=" << (childValue ? childValue :
"N/A")
248 <<
", expected=" << s_animationPropertyTag <<
"). Ignoring.\n";
251 if( animationSeq->GetAnimationCount() == 0 )
253 std::cerr <<
"LoadAnimation(): No keys found in file " << name << std::endl;
260 #ifdef GLS_ANIMATION_ENABLE_ZIP_LOADING
261 std::vector< GlsAnimation::Ptr >
LoadAnimationZip(
const std::string& filename )
264 std::vector< GlsAnimation::Ptr > animations;
267 unzFile zipFile = unzOpen(filename.c_str());
269 if (unzGoToFirstFile(zipFile) != UNZ_OK)
271 std::cerr <<
"LoadAnimationZip(): Unable to open file " << filename << std::endl;
275 const unsigned int bufSize(4096);
276 std::vector<char> buf(bufSize);
277 unz_file_info file_info;
281 if( unzGetCurrentFileInfo(zipFile, &file_info, &buf[0], bufSize - 1, NULL,0, NULL,0) != UNZ_OK )
283 std::cerr <<
"LoadAnimationZip(): Error getting file info from file in " << filename << std::endl;
287 std::string zippedFilename = &buf[0];
289 std::string extension = zippedFilename.substr( zippedFilename.rfind(
'.') + 1 );
290 std::transform(extension.begin(), extension.end(), extension.begin(), ::tolower);
291 if (extension ==
"zip")
293 std::cerr <<
"LoadAnimationZip(): File '" << filename <<
"' contains a zip file. Nested zip files are not supported. Ignoring.\n";
297 const uLong size = file_info.uncompressed_size;
299 if( unzOpenCurrentFile(zipFile) != UNZ_OK )
301 std::cerr <<
"LoadAnimationZip(): Error opening file " << zippedFilename <<
" in file " << filename << std::endl;
305 std::vector<char> data(size);
307 if( unzReadCurrentFile(zipFile,&data[0],size) != static_cast<int>( size ) )
309 std::cerr <<
"LoadAnimationZip(): Error reading from file " << zippedFilename <<
" in file " << filename << std::endl;
315 animations.push_back( anim );
319 }
while(unzGoToNextFile(zipFile) == UNZ_OK);
329 std::ifstream readIn( filename.c_str(), std::ios_base::ate );
333 std::cerr <<
"LoadAnimationScript(): Unable to load script file " << filename << std::endl;
337 std::streampos size = readIn.tellg();
340 if( !readIn || size == static_cast<std::streampos>(-1) )
342 std::cerr <<
"LoadAnimationScript(): Error reading from file " << filename << std::endl;
346 std::vector<char> data( static_cast<unsigned int>( size ) );
347 readIn.read( &data[0], size );
349 return LoadAnimation( data, filename );
stdortr1::shared_ptr< const GlsKeyframeCurve > PtrConst
Alias for easier reading.
stdortr1::shared_ptr< GlsAnimationCollection > Ptr
Alias for easier reading.
GlsAnimation::Ptr LoadAnimationScript(const std::string &filename)
Loads an animation sequence from a script file.
stdortr1::shared_ptr< GlsAnimation > Ptr
Alias for easier reading.
const std::string g_gatedInterpTag
Gated interpolator tag.
stdortr1::shared_ptr< const GlsKeyframeInterpolator > PtrConst
Alias for easier reading.
The GL Studio animation classes.
std::vector< GlsAnimation::Ptr > LoadAnimationZip(const std::string &filename)
Loads a set of animation sequences from a zip file.