/* orxonox - the future of 3D-vertical-scrollers Copyright (C) 2004 orx This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2, or (at your option) any later version. ### File Specific: main-programmer: Patrick Boenzli */ #define DEBUG_SPECIAL_MODULE DEBUG_MODULE_IMPORTER #include "md3_animation_cfg.h" #include "md3_animation.h" #include "tokenizer.h" #include "helper_functions.h" #include "debug.h" #include #include using namespace std; namespace md3 { /** * create an empty MD3AnimationCfg object */ MD3AnimationCfg::MD3AnimationCfg() { } /** * create a new MD3 Anumation object and initialize it with the data on the given line * @param line: the line to read from */ MD3AnimationCfg::MD3AnimationCfg(std::string filename) { this->loadConfig(filename); } /** * deconstructor */ MD3AnimationCfg::~MD3AnimationCfg() {} /** * loads the configuration file */ void MD3AnimationCfg::loadConfig(std::string filename) { // BufferedReader bin=new BufferedReader(new InputStreamReader(in)); int i = 0; //!< last read animation, animation order is hard coded! int torsoOffset = -1; //!< torso offset int firstTorsoFrame = -1; //!< first of the TORSO animation frames bool inHeader = true; //!< are we still in the header of the .cfg file? FILE* pFile; char* cLine; size_t len = 0; ssize_t read = 0; PRINTF(0)("opening file: %s\n", filename.c_str()); pFile = fopen(filename.c_str(), "r"); if( !pFile) { PRINTF(1)("Error: file could not be opened: %s\n", filename.c_str()); return; } // parse file while( (read = getline(&cLine, &len, pFile)) != -1) { /*( !this->dataStream.eof()) {*/ std::string line(cLine); // PRINTF(0)("size = %i, line = |%s|\n", read, line.c_str()); //ignore empty lines and comments if( line.length() > 2 && line.find("//") != 0) { // find the gender section if( inHeader && line.find("sex") == 0) { //parse line: sex [m | f | ...] std::vector tokens; Tokenizer::tokenize(line, tokens, " \t\n\r\f/"); std::string sexStr = tokens.back(); // probably error in the file format if( sexStr.length() != 1) { this->sex = '?'; PRINTF(2)("no section \"sex\" in the config file %s found\n", filename.c_str()); } else { this->sex = sexStr[0]; } PRINTF(0)("sex of the md3 model: %c\n", this->sex); } else if( inHeader && line.find("headoffset") == 0) { // parse line: headoffset X Y Z std::vector tokens; Tokenizer::tokenize(line, tokens, " \t\n\r\f/"); float z = atof(tokens.back().c_str()); tokens.pop_back(); float y = atof(tokens.back().c_str()); tokens.pop_back(); float x = atof(tokens.back().c_str()); tokens.pop_back(); this->headOffset = Vector(x, y, z); PRINTF(0)("got head offset: %f, %f, %f\n", x, y, z); } else if( inHeader && line.find("footsteps") == 0) { //parse line: footsteps [normal | mech | ...] std::vector tokens; Tokenizer::tokenize(line, tokens, " \t\n\r\f/"); this->footsteps = tokens.back(); //check if value is ok if (!(nocaseCmp(this->footsteps, "default") || nocaseCmp(this->footsteps, "normal") || nocaseCmp(this->footsteps, "boot") || nocaseCmp(this->footsteps, "flesh") || nocaseCmp(this->footsteps, "mech") || nocaseCmp(this->footsteps, "energy")) ) { this->footsteps="illegal footsteps value (" + this->footsteps + ")"; } PRINTF(0)("got footsteps: %s\n", this->footsteps.c_str()); } else { // assume it's an animation line inHeader = false; MD3Animation* animation = new MD3Animation(); this->loadAnimation(animation, line); if( i < 25) { animation->name = MD3Animation::animationList[i].animationName; animation->type = MD3Animation::animationList[i++].animationType; } // workaround for strange numbering in animation.cfg: skip TORSO frames // for LEGS animation lines... if( animation->type == LEGS) { //when first LEGS animation is found, calc # of TORSO frames if( torsoOffset == -1) torsoOffset = animation->first - firstTorsoFrame; animation->first -= torsoOffset; animation->offset = torsoOffset; } else if( animation->type == TORSO) if( firstTorsoFrame == -1) firstTorsoFrame = animation->first; this->putAnimation(animation); } } } } /** * loading the animation data itself */ void MD3AnimationCfg::loadAnimation(MD3Animation* anim, std::string line) { // parse the line: // first frame, num frames, looping frames, frames per second (fps) std::vector tokens; Tokenizer::tokenize(line, tokens, " \t\n\r\f/"); anim->fps = atoi(tokens.back().c_str()); tokens.pop_back(); anim->numLoopFrames = atoi(tokens.back().c_str()); tokens.pop_back(); anim->numFrames = atoi(tokens.back().c_str()); tokens.pop_back(); anim->first = atoi(tokens.back().c_str()); tokens.pop_back(); //some adjustements: if( anim->fps == 0) anim->fps = 33; PRINTF(0)("Animation: first frame: %i, num frames: %i, num loops: %i, fps: %i\n", anim->first, anim->numFrames, anim->numLoopFrames, anim->fps); } /** * Look up the animation data for the animation with the specified name. * * @param name Name of the animation. * @return The animation data associated with the name or null if no data was found. */ MD3Animation* MD3AnimationCfg::getAnimation(std::string name) { return this->animations[name]; } /** * Add the specified animation to the list of known animations. */ void MD3AnimationCfg::putAnimation(MD3Animation* anim) { this->animations[anim->name] = anim; } }