Back to index

supertuxkart  0.5+dfsg1
loader.cpp
Go to the documentation of this file.
00001 //  $Id: loader.cpp 1610 2008-03-01 03:18:53Z hikerstk $
00002 //
00003 //  SuperTuxKart - a fun racing game with go-kart
00004 //  Copyright (C) 2004 Steve Baker <sjbaker1@airmail.net>
00005 //            (C) 2008 Steve Baker, Joerg Henrichs
00006 //
00007 //  This program is free software; you can redistribute it and/or
00008 //  modify it under the terms of the GNU General Public License
00009 //  as published by the Free Software Foundation; either version 2
00010 //  of the License, or (at your option) any later version.
00011 //
00012 //  This program is distributed in the hope that it will be useful,
00013 //  but WITHOUT ANY WARRANTY; without even the implied warranty of
00014 //  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00015 //  GNU General Public License for more details.
00016 //
00017 //  You should have received a copy of the GNU General Public License
00018 //  along with this program; if not, write to the Free Software
00019 //  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
00020 
00021 
00022 #include <stdexcept>
00023 #include <sstream>
00024 #include <sys/stat.h>
00025 #include <string>
00026 #ifdef WIN32
00027 #  include <io.h>
00028 #  include <stdio.h>
00029 #  ifndef __CYGWIN__
00030 #    define S_ISDIR(mode)  (((mode) & S_IFMT) == S_IFDIR)
00031      //   Some portabilty defines
00032 #  endif
00033 #endif
00034 
00035 #include "loader.hpp"
00036 #include "moving_physics.hpp"
00037 #include "moving_texture.hpp"
00038 #include "material_manager.hpp"
00039 #include "file_manager.hpp"
00040 #include "material.hpp"
00041 
00042 Loader* loader = 0;
00043 
00044 Loader::Loader()
00045 {
00046     m_current_callback_type = CB_COLLECTABLE;
00047 }  // Loader
00048 
00049 //-----------------------------------------------------------------------------
00050 Loader::~Loader()
00051 {
00052 }   // ~Loader
00053 
00054 //-----------------------------------------------------------------------------
00055 void Loader::makeModelPath(char* path, const char* FNAME) const
00056 {
00057     if(m_is_full_path)
00058     {
00059         strcpy(path, FNAME);
00060         return;
00061     }
00062     
00063     std::string p=file_manager->getModelFile(FNAME);
00064     strcpy(path, p.c_str());
00065     return;
00066 }   // makeModelPath
00067 
00068 //-----------------------------------------------------------------------------
00085 ssgEntity *Loader::load(const std::string& filename, CallbackType t,
00086                         bool optimise, bool is_full_path)
00087 {
00088     m_current_callback_type   = t;
00089     m_is_full_path            = is_full_path;
00090     ssgEntity *obj            = optimise ? ssgLoad  (filename.c_str(), this) 
00091                                          : ssgLoadAC(filename.c_str(), this);
00092     preProcessObj(obj, false);
00093     return obj;
00094 }   // load
00095 
00096 //-----------------------------------------------------------------------------
00097 void Loader::preProcessObj ( ssgEntity *n, bool mirror )
00098 {
00099     if ( n == NULL ) return ;
00100 
00101     n -> dirtyBSphere () ;
00102 
00103     if ( n -> isAKindOf ( ssgTypeLeaf() ) )
00104     {
00105         if ( mirror )
00106             for ( int i = 0 ; i < ((ssgLeaf *)n) -> getNumVertices () ; i++ )
00107                 ((ssgLeaf *)n) -> getVertex ( i ) [ 0 ] *= -1.0f ;
00108 
00109         material_manager->getMaterial((ssgLeaf *) n ) -> applyToLeaf ( (ssgLeaf *) n ) ;
00110         return ;
00111     }
00112 
00113     if ( mirror && n -> isAKindOf ( ssgTypeTransform () ) )
00114     {
00115         sgMat4 xform ;
00116 
00117         ((ssgTransform *)n) -> getTransform ( xform ) ;
00118         xform [ 0 ][ 0 ] *= -1.0f ;
00119         xform [ 1 ][ 0 ] *= -1.0f ;
00120         xform [ 2 ][ 0 ] *= -1.0f ;
00121         xform [ 3 ][ 0 ] *= -1.0f ;
00122         ((ssgTransform *)n) -> setTransform ( xform ) ;
00123     }
00124 
00125     ssgBranch *b = (ssgBranch *) n ;
00126 
00127     for ( int i = 0 ; i < b -> getNumKids () ; i++ )
00128         preProcessObj ( b -> getKid ( i ), mirror ) ;
00129 }
00130 
00131 //-----------------------------------------------------------------------------
00132 ssgBranch *Loader::animInit (char *data ) const
00133 {
00134     while ( ! isdigit ( *data ) && *data != '\0' )
00135         data++ ;
00136 
00137     const int   START_LIM =        strtol(data, &data, 0 );
00138     const int   END_LIM   =        strtol(data, &data, 0 );
00139     const float TIME_LIM  = (float)strtod(data, &data    );
00140 
00141     while ( *data <= ' ' && *data != '\0' )
00142         data++ ;
00143 
00144     char mode = toupper ( *data ) ;
00145 
00146     ssgTimedSelector *br = new ssgTimedSelector;
00147 
00148     br->setLimits  (START_LIM+1, END_LIM+1 ) ;
00149     br->setDuration(TIME_LIM ) ;
00150     br->setMode    ((mode=='O') ?  SSG_ANIM_ONESHOT
00151                     :  (mode=='S') ?  SSG_ANIM_SWING
00152                     : SSG_ANIM_SHUTTLE ) ;
00153     br->control    (SSG_ANIM_START ) ;
00154 
00155     return br;
00156 }   // animInit
00157 
00158 
00159 //-----------------------------------------------------------------------------
00166 ssgBranch *Loader::createBranch(char *data) const
00167 {
00168 
00169     if ( data == NULL || data[0] != '@' ) return NULL;
00170 
00171     data++ ;   /* Skip the '@' */
00172 
00173     if ( strncmp("billboard", data, strlen("billboard") ) == 0 )
00174         return  new ssgCutout();
00175 
00176     if ( strncmp("DONT_DELETE", data, strlen("DONT_DELETE") ) == 0 )
00177     {
00178         printf("DONT\n");
00179         ssgBranch *br = new ssgTransform();
00180         br->setUserData(new ssgBase());
00181         return br;
00182     }
00183 
00184     if ( strncmp("invisible", data, strlen("invisible") ) == 0 )
00185         return new ssgInvisible();
00186 
00187     if ( strncmp ( "switch", data, strlen ( "switch" ) ) == 0 )
00188     {
00189         ssgSelector *sel = new ssgSelector();
00190         sel->select(0);
00191         return sel;
00192     }
00193 
00194     if ( strncmp ( "animate", data, strlen ( "animate" ) ) == 0 )
00195         return animInit(data);
00196 
00197 
00198     if ( strncmp ( "autodcs", data, strlen ( "autodcs" ) ) == 0 )
00199     {
00200         ssgTransform *br = new ssgTransform();
00201         Callback     *c  = new MovingTexture(data, br);
00202         br->setUserData(new ssgBase());
00203         callback_manager->addCallback(c, m_current_callback_type);
00204         return br;
00205     }
00206 
00207     if ( strncmp ( "autotex", data, strlen ( "autotex" ) ) == 0 )
00208     {
00209         ssgTexTrans *br = new ssgTexTrans();
00210         Callback    *c  = new MovingTexture(data, br);
00211         callback_manager->addCallback(c, m_current_callback_type);
00212         return br;
00213     }
00214     if(strncmp("physics", data, strlen("physics")) == 0)
00215     {
00216         MovingPhysics *mp = new MovingPhysics(std::string(data));
00217         callback_manager->addCallback(mp, m_current_callback_type);
00218         return mp;
00219     }
00220     fprintf(stderr, "Warning: Ignoring userdata '%s'\n", data);
00221     return NULL ;
00222 }   // createBranch
00223