Back to index

supertuxkart  0.5+dfsg1
moving_texture.cpp
Go to the documentation of this file.
00001 //  $Id: moving_texture.cpp 796 2006-09-27 07:06:34Z hiker $
00002 //
00003 //  SuperTuxKart - a fun racing game with go-kart
00004 //  Copyright (C) 2006 Joerg Henrichs
00005 //
00006 //  This program is free software; you can redistribute it and/or
00007 //  modify it under the terms of the GNU General Public License
00008 //  as published by the Free Software Foundation; either version 2
00009 //  of the License, or (at your option) any later version.
00010 //
00011 //  This program is distributed in the hope that it will be useful,
00012 //  but WITHOUT ANY WARRANTY; without even the implied warranty of
00013 //  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00014 //  GNU General Public License for more details.
00015 //
00016 //  You should have received a copy of the GNU General Public License
00017 //  along with this program; if not, write to the Free Software
00018 //  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
00019 
00020 #include "constants.hpp"
00021 #include "moving_texture.hpp"
00022 #include "string_utils.hpp"
00023 #include "world.hpp"
00024 #include "translation.hpp"
00025 
00026 MovingTexture::MovingTexture(char *data, ssgBranch *branch)
00027 {
00028     m_branch = branch;
00029     branch->setUserData(new ssgBase());
00030     branch->setName("MovingTexture");
00031 
00032     m_branch->ref();
00033     m_phase  = 0.0f;
00034     m_mode   = MODE_FORWARD;
00035     m_cycle  = 30.0f;
00036     sgSetCoord(&m_now,   0, 0, 0, 0, 0, 0 ) ;
00037     sgSetCoord(&m_delta, 0, 0, 0, 0, 0, 0 ) ;
00038     parseData(data);
00039 
00040 
00041 }   // MovingTexture
00042 
00043 //-----------------------------------------------------------------------------
00044 MovingTexture::~MovingTexture()
00045 {
00046     ssgDeRefDelete(m_branch);
00047 
00048 }   // ~MovingTexture
00049 
00050 //-----------------------------------------------------------------------------
00051 void MovingTexture::parseData(char *data)
00052 {
00053     char *s = data;
00054 
00055     // convert to uppercase
00056     while(*s!='\0')
00057     {
00058         if( *s>='a' && *s<='z' ) *s = *s - 'a' + 'A' ;
00059         s++;
00060     }
00061     s = data;
00062 
00063     while ( s != NULL && *s != '\0' )
00064     {
00065         while ( *s > ' '                ) s++ ;     /* Skip previous token */
00066         while ( *s <= ' ' && *s != '\0' ) s++ ;     /* Skip spaces         */
00067 
00068         if ( *s == '\0' ) break ;
00069 
00070         float f ;
00071 
00072         if ( sscanf ( s,  "H=%f", & f ) == 1 ) m_delta.hpr[0] = f ; else
00073         if ( sscanf ( s,  "P=%f", & f ) == 1 ) m_delta.hpr[1] = f ; else
00074         if ( sscanf ( s,  "R=%f", & f ) == 1 ) m_delta.hpr[2] = f ; else
00075         if ( sscanf ( s,  "X=%f", & f ) == 1 ) m_delta.xyz[0] = f ; else
00076         if ( sscanf ( s,  "Y=%f", & f ) == 1 ) m_delta.xyz[1] = f ; else
00077         if ( sscanf ( s,  "Z=%f", & f ) == 1 ) m_delta.xyz[2] = f ; else
00078         if ( sscanf ( s,  "C=%f", & f ) == 1 ) m_cycle        = f ; else
00079         if ( sscanf ( s,  "M=%f", & f ) == 1 ) m_mode         = (int) f ; else
00080         if ( sscanf ( s,  "O=%f", & f ) == 1 ) m_phase        = f ; else
00081             fprintf ( stderr, "Unrecognised @autodcs string: '%s'\n", data );
00082     }   // while s!=NULL&&s!='\0'
00083 }   // parseData
00084 
00085 //-----------------------------------------------------------------------------
00086 void MovingTexture::update(float dt)
00087 {
00088     sgCoord add;
00089 
00090 
00091     float timer = world->getTime() + m_phase ;
00092 
00093     if ( m_cycle != 0.0 && m_mode != MODE_FORWARD )
00094     {
00095         if ( m_mode == MODE_SHUTTLE )
00096         {
00097             const float CTIMER = fmod ( timer, m_cycle ) ;
00098 
00099             if ( CTIMER > m_cycle / 2.0f )
00100                 timer = m_cycle - CTIMER ;
00101             else
00102                 timer = CTIMER ;
00103         }
00104         else
00105         {
00106             if ( m_mode == MODE_SINESHUTTLE )
00107                 timer = sin ( timer * 2.0f * M_PI / m_cycle ) * m_cycle / 2.0f ;
00108             else
00109                 timer = fmod ( timer, m_cycle ) ;
00110         }
00111     }   // m_mode!=MODE_FORWARD
00112 
00113     sgCopyCoord(&add, &m_delta  );
00114     sgScaleVec3(add.xyz, dt);
00115     sgScaleVec3(add.hpr, dt);
00116 
00117     sgAddVec3(m_now.xyz, add.xyz);
00118     sgAddVec3(m_now.hpr, add.hpr);
00119 
00120     /*
00121       To avoid roundoff problems with very large values
00122       accumulated after long runs all rotations
00123       can be modulo-360 degrees.
00124     */
00125 
00126     m_now.hpr[0] = fmod ( m_now.hpr[0], 360.0f);
00127     m_now.hpr[1] = fmod ( m_now.hpr[1], 360.0f);
00128     m_now.hpr[2] = fmod ( m_now.hpr[2], 360.0f);
00129 
00130     if ( m_branch->isAKindOf(ssgTypeTexTrans()) )
00131     {
00132         m_now.xyz[0] = fmod( m_now.xyz[0], 1.0f);
00133         m_now.xyz[1] = fmod( m_now.xyz[1], 1.0f);
00134         m_now.xyz[2] = fmod( m_now.xyz[2], 1.0f);
00135     }
00136     ((ssgBaseTransform *) m_branch) -> setTransform(&m_now);
00137 }   // update
00138 
00139