Back to index

supertuxkart  0.5+dfsg1
skid_mark.cpp
Go to the documentation of this file.
00001 //  $Id: skid_mark.cpp 2111 2008-05-31 07:04:30Z cosmosninja $
00002 //
00003 //  SuperTuxKart - a fun racing game with go-kart
00004 //  Copyright (C) 2004 Ingo Ruhnke <grumbel@gmx.de>
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 "scene.hpp"
00021 #include "skid_mark.hpp"
00022 
00023 float SkidMark::m_global_track_offset = 0.005f;
00024 
00025 SkidMark::SkidMark(float angle_sign)
00026 {
00027     m_skid_state = new ssgSimpleState();
00028     m_angle_sign = angle_sign;
00029     m_skid_state->ref();
00030     m_skid_state -> enable (GL_BLEND);
00031     //This is just for the skidmarks, so the ones drawn when the kart is in
00032     //reverse get drawn
00033     m_skid_state -> disable (GL_CULL_FACE);
00034     m_skid_marking = false;
00035 }   // SkidMark
00036 
00037 //-----------------------------------------------------------------------------
00038 SkidMark::~SkidMark()
00039 {
00040     if(!m_skid_marks.empty())
00041     {
00042         const unsigned int SIZE = (unsigned int)m_skid_marks.size() -1;
00043         for(unsigned int i = 0; i < SIZE; ++i)
00044         {
00045             ssgDeRefDelete(m_skid_marks[i]);
00046         }   // for
00047     }   // if !empty
00048     ssgDeRefDelete(m_skid_state);
00049 }   // ~SkidMark
00050 
00051 //-----------------------------------------------------------------------------
00052 void SkidMark::add(const sgCoord& coord, float angle, float length)
00053 {
00054     if(m_skid_marking)
00055     {
00056         const int CURRENT = (int)m_skid_marks.size() - 1;
00057         m_skid_marks[CURRENT]->add(coord, m_angle_sign*angle, length);
00058     }
00059     else
00060     {
00061         addBreak(coord, angle, length);
00062     }
00063 }   // add
00064 
00065 //-----------------------------------------------------------------------------
00066 void SkidMark::addBreak(const sgCoord& kart_coord, float angle, float length)
00067 {
00068     sgCoord coord(kart_coord);
00069     coord.xyz[0] += length * sgSin(coord.hpr[0] + m_angle_sign*angle);
00070     coord.xyz[1] += length* -sgCos(coord.hpr[0] + m_angle_sign*angle);
00071 
00072 
00073     const unsigned int CURRENT = (unsigned int)m_skid_marks.size() - 1;
00074     if(m_skid_marking)
00075         m_skid_marks[CURRENT]->addEnd(coord);
00076     else
00077     {
00078         m_global_track_offset += 0.005f;
00079         if(m_global_track_offset > 0.05f) m_global_track_offset = 0.01f;
00080 
00081         // Width of the skidmark
00082         const float WIDTH = 0.1f;
00083 
00084         sgVec3 pos;
00085         sgSetVec3(pos,
00086                   coord.xyz[0] + sgSin(coord.hpr[0]-90) * WIDTH,
00087                   coord.xyz[1] - sgCos(coord.hpr[0]-90) * WIDTH,
00088                   coord.xyz[2] + m_global_track_offset);
00089         ssgVertexArray* SkidMarkVertices = new ssgVertexArray;
00090         SkidMarkVertices->add(pos);
00091 
00092         sgSetVec3(pos,
00093                   coord.xyz[0] + sgSin(coord.hpr[0]+90) * WIDTH,
00094                   coord.xyz[1] - sgCos(coord.hpr[0]+90) * WIDTH,
00095                   coord.xyz[2] + m_global_track_offset);
00096         SkidMarkVertices->add(pos);
00097 
00098         sgVec3 norm;
00099         sgSetVec3(norm, 0, 0, 1);
00100 
00101         ssgNormalArray* SkidMarkNormals = new ssgNormalArray;
00102         SkidMarkNormals->add(norm);
00103         SkidMarkNormals->add(norm);
00104 
00105         sgVec4 color;
00106         sgSetVec4(color, 0, 0, 0, 1);
00107 
00108         ssgColourArray* SkidMarkColors = new ssgColourArray;
00109         SkidMarkColors->add(color);
00110         SkidMarkColors->add(color);
00111 
00112         SkidMarkPos* new_skid_mark = new SkidMarkPos( SkidMarkVertices,
00113                                    SkidMarkNormals,
00114                                    SkidMarkColors,
00115                                    m_global_track_offset);
00116         new_skid_mark->ref();
00117         scene->add(new_skid_mark);
00118         new_skid_mark-> setState (m_skid_state);
00119 
00120         m_skid_marks.push_back(new_skid_mark);
00121     }   // if m_skid_marking
00122 
00123     m_skid_marking = !m_skid_marking;
00124 }   // addBreak
00125 
00126 //-----------------------------------------------------------------------------
00127 bool SkidMark::wasSkidMarking() const
00128 {
00129     return m_skid_marking;
00130 }   // wasSkidMarking
00131 
00132 
00133 //=============================================================================
00134 SkidMark::SkidMarkPos::SkidMarkPos() : ssgVtxTable ( GL_QUAD_STRIP,
00135                 new ssgVertexArray,
00136                 new ssgNormalArray,
00137                 new ssgTexCoordArray,
00138                 new ssgColourArray )
00139 {}   // SkidMarkPos
00140 
00141 //-----------------------------------------------------------------------------
00142 SkidMark::SkidMarkPos::SkidMarkPos( ssgVertexArray* vertices,
00143                                     ssgNormalArray* normals,
00144                                     ssgColourArray* colors,
00145                                     float global_track_offset) :
00146         ssgVtxTable ( GL_QUAD_STRIP,
00147                       vertices,
00148                       normals,
00149                       new ssgTexCoordArray,
00150                       colors )
00151 {
00152     m_track_offset = global_track_offset;
00153 }   // SkidMarkPos
00154 
00155 //-----------------------------------------------------------------------------
00156 SkidMark::SkidMarkPos::~SkidMarkPos()
00157 {}   // ~SkidMarkPos
00158 
00159 //-----------------------------------------------------------------------------
00160 void SkidMark::SkidMarkPos::recalcBSphere()
00161 {
00162     bsphere . setRadius ( 1000.0f ) ;
00163     bsphere . setCenter ( 0, 0, 0 ) ;
00164 }   // recalcBSphere
00165 
00166 //-----------------------------------------------------------------------------
00167 void SkidMark::SkidMarkPos::add(const sgCoord& kart_coord, float angle, float length)
00168 {
00169     sgCoord coord(kart_coord);
00170 
00171     coord.xyz[0] += length *  sgSin(kart_coord.hpr[0] + angle);
00172     coord.xyz[1] += length * -sgCos(kart_coord.hpr[0] + angle);
00173 
00174 
00175     // Width of the skidmark
00176     const float WIDTH = 0.1f;
00177 
00178     static float a = 1.0f;
00179     sgVec3 pos;
00180     sgSetVec3(pos,
00181               coord.xyz[0] + sgSin(coord.hpr[0]+a*90) * WIDTH,
00182               coord.xyz[1] - sgCos(coord.hpr[0]+a*90) * WIDTH,
00183               coord.xyz[2] + m_track_offset);
00184     vertices->add(pos);
00185 
00186     sgSetVec3(pos,
00187               coord.xyz[0] + sgSin(coord.hpr[0]-a*90) * WIDTH,
00188               coord.xyz[1] - sgCos(coord.hpr[0]-a*90) * WIDTH,
00189               coord.xyz[2] + m_track_offset);
00190     vertices->add(pos);
00191     a = (a > 0.0f ? -1.0f : 1.0f);
00192 
00193     sgVec3 norm;
00194     sgSetVec3(norm, 0, 0, 1);
00195     normals->add(norm); normals->add(norm);
00196 
00197     sgVec4 color;
00198     sgSetVec4(color, 0.07f, 0.07f, 0.07f, 0.8f);
00199     colours->add(color); colours->add(color);
00200     this->dirtyBSphere();
00201 }   // add
00202 
00203 //-----------------------------------------------------------------------------
00204 void SkidMark::SkidMarkPos::addEnd(const sgCoord& coord)
00205 {
00206     // Width of the skidmark
00207     const float width = 0.1f;
00208 
00209     sgVec3 pos;
00210     sgSetVec3(pos,
00211               coord.xyz[0] + sgSin(coord.hpr[0]-90) * width,
00212               coord.xyz[1] - sgCos(coord.hpr[0]-90) * width,
00213               coord.xyz[2] + m_track_offset);
00214     vertices->add(pos);
00215 
00216     sgSetVec3(pos,
00217               coord.xyz[0] + sgSin(coord.hpr[0]+90) * width,
00218               coord.xyz[1] - sgCos(coord.hpr[0]+90) * width,
00219               coord.xyz[2] + m_track_offset);
00220     vertices->add(pos);
00221 
00222     sgVec3 norm;
00223     sgSetVec3(norm, 0, 0, 1);
00224     normals->add(norm); normals->add(norm);
00225 
00226     sgVec4 color;
00227     sgSetVec4(color, 0.15f, 0.15f, 0.15f, 0.0f);
00228     colours->add(color); colours->add(color);
00229     makeDList();
00230 }   // addEnd
00231 
00232 /* EOF */