From 859ec6fcaa643af9cb5c70008f9aa32290eadfd9 Mon Sep 17 00:00:00 2001 From: hikerstk Date: Mon, 3 Mar 2008 03:48:04 +0000 Subject: [PATCH] Added loader. git-svn-id: svn+ssh://svn.code.sf.net/p/supertuxkart/code/trunk/supertuxkart@1620 178a84e3-b1eb-0310-8ba1-8eac791a3b58 --- src/loader.cpp | 223 +++++++++++++++++++++++++++++++++++++++++++++++++ src/loader.hpp | 62 ++++++++++++++ 2 files changed, 285 insertions(+) create mode 100644 src/loader.cpp create mode 100644 src/loader.hpp diff --git a/src/loader.cpp b/src/loader.cpp new file mode 100644 index 000000000..6c82cff81 --- /dev/null +++ b/src/loader.cpp @@ -0,0 +1,223 @@ +// $Id: loader.cpp 1610 2008-03-01 03:18:53Z hikerstk $ +// +// SuperTuxKart - a fun racing game with go-kart +// Copyright (C) 2004 Steve Baker +// (C) 2008 Steve Baker, Joerg Henrichs +// +// 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 +// of the License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + + +#include +#include +#include +#include +#ifdef WIN32 +# include +# include +# ifndef __CYGWIN__ +# define S_ISDIR(mode) (((mode) & S_IFMT) == S_IFDIR) + // Some portabilty defines +# endif +#endif + +#include "loader.hpp" +#include "moving_physics.hpp" +#include "moving_texture.hpp" +#include "material_manager.hpp" +#include "file_manager.hpp" +#include "material.hpp" + +Loader* loader = 0; + +Loader::Loader() +{ + m_current_callback_type = CB_COLLECTABLE; +} // Loader + +//----------------------------------------------------------------------------- +Loader::~Loader() +{ +} // ~Loader + +//----------------------------------------------------------------------------- +void Loader::makeModelPath(char* path, const char* FNAME) const +{ + if(m_is_full_path) + { + strcpy(path, FNAME); + return; + } + + std::string p=file_manager->getModelFile(FNAME); + strcpy(path, p.c_str()); + return; +} // makeModelPath + +//----------------------------------------------------------------------------- +/** Loads a .ac model + * + * Loads the .ac model 'filename'. Callbacks contained in this file + * are stored in the callback class t. If optimise is set to false, + * the file will not be flattened, which is necessary for the kart + * models - flattening them will remove the wheel nodes, withouth + * which the wheels do not rotate. + * + * \param filename File to load + * + * \param t Callback category for callbacks included in this + * file (see callback_manager.hpp) + * + * \param optimise Default is true. If set to false, the model will not + * be flattened. + */ +ssgEntity *Loader::load(const std::string& filename, CallbackType t, + bool optimise, bool is_full_path) +{ + m_current_callback_type = t; + m_is_full_path = is_full_path; + ssgEntity *obj = optimise ? ssgLoad (filename.c_str(), this) + : ssgLoadAC(filename.c_str(), this); + preProcessObj(obj, false); + return obj; +} // load + +//----------------------------------------------------------------------------- +void Loader::preProcessObj ( ssgEntity *n, bool mirror ) +{ + if ( n == NULL ) return ; + + n -> dirtyBSphere () ; + + if ( n -> isAKindOf ( ssgTypeLeaf() ) ) + { + if ( mirror ) + for ( int i = 0 ; i < ((ssgLeaf *)n) -> getNumVertices () ; i++ ) + ((ssgLeaf *)n) -> getVertex ( i ) [ 0 ] *= -1.0f ; + + material_manager->getMaterial((ssgLeaf *) n ) -> applyToLeaf ( (ssgLeaf *) n ) ; + return ; + } + + if ( mirror && n -> isAKindOf ( ssgTypeTransform () ) ) + { + sgMat4 xform ; + + ((ssgTransform *)n) -> getTransform ( xform ) ; + xform [ 0 ][ 0 ] *= -1.0f ; + xform [ 1 ][ 0 ] *= -1.0f ; + xform [ 2 ][ 0 ] *= -1.0f ; + xform [ 3 ][ 0 ] *= -1.0f ; + ((ssgTransform *)n) -> setTransform ( xform ) ; + } + + ssgBranch *b = (ssgBranch *) n ; + + for ( int i = 0 ; i < b -> getNumKids () ; i++ ) + preProcessObj ( b -> getKid ( i ), mirror ) ; +} + +//----------------------------------------------------------------------------- +ssgBranch *Loader::animInit (char *data ) const +{ + while ( ! isdigit ( *data ) && *data != '\0' ) + data++ ; + + const int START_LIM = strtol(data, &data, 0 ); + const int END_LIM = strtol(data, &data, 0 ); + const float TIME_LIM = (float)strtod(data, &data ); + + while ( *data <= ' ' && *data != '\0' ) + data++ ; + + char mode = toupper ( *data ) ; + + ssgTimedSelector *br = new ssgTimedSelector; + + br->setLimits (START_LIM+1, END_LIM+1 ) ; + br->setDuration(TIME_LIM ) ; + br->setMode ((mode=='O') ? SSG_ANIM_ONESHOT + : (mode=='S') ? SSG_ANIM_SWING + : SSG_ANIM_SHUTTLE ) ; + br->control (SSG_ANIM_START ) ; + + return br; +} // animInit + + +//----------------------------------------------------------------------------- +/** Handle userdata that is stored in the model files. Mostly the userdata + * indicates that a special branch is to be created (e.g. a ssgCutout instead + * of the standard branch). But some userdata indicate that callbacks need + * to be created, which are then handled by the callback manager. + */ + +ssgBranch *Loader::createBranch(char *data) const +{ + + if ( data == NULL || data[0] != '@' ) return NULL; + + data++ ; /* Skip the '@' */ + + if ( strncmp("billboard", data, strlen("billboard") ) == 0 ) + return new ssgCutout(); + + if ( strncmp("DONT_DELETE", data, strlen("DONT_DELETE") ) == 0 ) + { + printf("DONT\n"); + ssgBranch *br = new ssgTransform(); + br->setUserData(new ssgBase()); + return br; + } + + if ( strncmp("invisible", data, strlen("invisible") ) == 0 ) + return new ssgInvisible(); + + if ( strncmp ( "switch", data, strlen ( "switch" ) ) == 0 ) + { + ssgSelector *sel = new ssgSelector(); + sel->select(0); + return sel; + } + + if ( strncmp ( "animate", data, strlen ( "animate" ) ) == 0 ) + return animInit(data); + + + if ( strncmp ( "autodcs", data, strlen ( "autodcs" ) ) == 0 ) + { + ssgTransform *br = new ssgTransform(); + Callback *c = new MovingTexture(data, br); + br->setUserData(new ssgBase()); + callback_manager->addCallback(c, m_current_callback_type); + return br; + } + + if ( strncmp ( "autotex", data, strlen ( "autotex" ) ) == 0 ) + { + ssgTexTrans *br = new ssgTexTrans(); + Callback *c = new MovingTexture(data, br); + callback_manager->addCallback(c, m_current_callback_type); + return br; + } + if(strncmp("physics", data, strlen("physics")) == 0) + { + MovingPhysics *mp = new MovingPhysics(std::string(data)); + callback_manager->addCallback(mp, m_current_callback_type); + return mp; + } + fprintf(stderr, "Warning: Ignoring userdata '%s'\n", data); + return NULL ; +} // createBranch + diff --git a/src/loader.hpp b/src/loader.hpp new file mode 100644 index 000000000..555da2e20 --- /dev/null +++ b/src/loader.hpp @@ -0,0 +1,62 @@ +// $Id: loader.hpp 1610 2008-03-01 03:18:53Z hikerstk $ +// +// SuperTuxKart - a fun racing game with go-kart +// Copyright (C) 2004 Steve Baker +// +// 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 +// of the License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +#ifndef HEADER_LOADER_H +#define HEADER_LOADER_H + +#include +#include +#include +#include +#include "callback_manager.hpp" + +class Loader : public ssgLoaderOptions +{ +private: + bool m_is_full_path; + std::string m_root_dir; + std::vector m_texture_search_path, + m_model_search_path, + m_music_search_path; + bool findFile (std::string& full_path, + const std::string& fname, + const std::vector& search_path) const; +public: + Loader(); + ~Loader(); + + virtual void makeModelPath (char* path, const char* fname) const; + + ssgEntity *load(const std::string& filename, CallbackType t, bool optimise=true, + bool is_full_path=false); + void setCallbackType(CallbackType t) {m_current_callback_type=t;} +private: + CallbackType m_current_callback_type; + + void makePath (std::string& path, const std::string& dir, + const std::string& fname) const; + ssgBranch *createBranch (char *data) const; + void preProcessObj( ssgEntity *n, bool mirror ); + ssgBranch *animInit (char *data) const; +}; + +extern Loader* loader; + +#endif +