Main Page   Namespace List   Class Hierarchy   Compound List   File List   Namespace Members   Compound Members   File Members  

spring.cxx

Go to the documentation of this file.
00001 //  $Id: spring.cxx,v 1.13 2003/01/11 19:07:48 grumbel Exp $
00002 //
00003 //  Construo - A wire-frame construction game
00004 //  Copyright (C) 2002 Ingo Ruhnke <[email protected]>
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 "colors.hxx"
00021 #include "construo_error.hxx"
00022 #include "particle_factory.hxx"
00023 #include "spring.hxx"
00024 
00025 Spring::Spring (Particle* f, Particle* s, float l)
00026 {
00027   particles.first  = f;
00028   particles.second = s;
00029   destroyed        = false;
00030   length           = l;
00031 
00032   stiffness   = 50.0f;
00033   damping     = .1f;
00034   max_stretch = 0.15f;
00035 
00036   f->spring_links += 1;
00037   s->spring_links += 1;
00038 }
00039 
00040 Spring::Spring (Particle* f, Particle* s) 
00041 {
00042   particles.first  = f;
00043   particles.second = s;
00044   destroyed        = false;
00045   length           = fabs((f->pos - s->pos).norm ());
00046 
00047   stiffness   = 50.0f;
00048   damping     = .1f;
00049   max_stretch = 0.15f;
00050 
00051   f->spring_links += 1;
00052   s->spring_links += 1;
00053 
00054   assert (length != 0);
00055 }
00056 
00057 Spring::Spring (World* world, lisp_object_t* cursor)
00058   : destroyed (false)
00059 {
00060   cursor = lisp_cdr(cursor); // Skip the identifer
00061 
00062   int first_id = -1;
00063   int second_id = -1;
00064   length = -1;
00065 
00066   stiffness   = 50.0f;
00067   damping     = .1f;
00068   max_stretch = 0.15f;
00069 
00070   LispReader reader(cursor);
00071   reader.read_int ("first", &first_id);
00072   reader.read_int ("second", &second_id);
00073   reader.read_float ("length", &length);
00074   reader.read_float ("stiffness",   &stiffness);
00075   reader.read_float ("damping",     &damping);
00076   reader.read_float ("maxstretch", &max_stretch);
00077 
00078   particles.first  = world->get_particle_mgr()->lookup_particle (first_id);
00079   particles.second = world->get_particle_mgr()->lookup_particle (second_id);
00080 
00081   if (particles.first == 0 || particles.second == 0)
00082     {
00083       throw ConstruoError ("Spring: Pair lookup failed");
00084     }
00085 
00086   particles.first->spring_links  += 1;
00087   particles.second->spring_links += 1;
00088 
00089   if (length == -1)
00090     {
00091       //std::cout << "Spring: length missing in data file, recalculating" << std::endl;     
00092       length = fabs((particles.first->pos - particles.second->pos).norm ());
00093     }
00094 }
00095 
00096 Spring::~Spring ()
00097 {
00098   particles.first->spring_links -= 1;
00099   particles.second->spring_links -= 1;
00100 }
00101 
00102 void
00103 Spring::update (float delta)
00104 {
00105   Vector2d dist = particles.first->pos - particles.second->pos;
00106 
00107   // Calculate the stretchness of the spring, 0.0 if unstretch, else
00108   // <> 0
00109   float stretch = (dist.norm () - length);
00110   
00111   //std::cout << "Stretch: " << stretch << std::endl;
00112   if (fabs(stretch/length) > max_stretch && 
00113       length > 10.0f) // atomar spring
00114     { // If the spring is streched above limits, let it get destroyed
00115       destroyed = true;
00116     }
00117   else
00118     {
00119       stretch *= stiffness;
00120       float dterm = (dist.dot(particles.first->velocity - particles.second->velocity) * damping)/dist.norm ();
00121 
00122       dist.normalize ();
00123       Vector2d force = dist * (stretch + dterm);
00124       
00125       /*std::cout << "DTerm: " << dterm << " HTerm: " << stretch 
00126                 << " Force: " << force
00127                 << std::endl;*/
00128 
00129       particles.first->add_force (-force);
00130       particles.second->add_force (force);
00131     }
00132 }
00133 
00134 void
00135 Spring::draw (ZoomGraphicContext* gc)
00136 {
00137   Vector2d dist = particles.first->pos - particles.second->pos;
00138   float stretch = fabs(dist.norm ()/length - 1.0f) * 10.0f;
00139   
00140   float color = fabs((stretch/max_stretch));
00141   
00142   if (particles.first->pos.y  < 598.5f
00143       || 
00144       particles.second->pos.y < 598.5f)
00145     {
00146       gc->GraphicContext::draw_line (particles.first->pos,
00147                                      particles.second->pos,
00148                                      Color(color, 1.0f - color, 0.0f),
00149                                      2);
00150     }
00151 }
00152 
00153 void
00154 Spring::draw_highlight (ZoomGraphicContext* gc)
00155 {
00156   gc->GraphicContext::draw_line (particles.first->pos, particles.second->pos,
00157                                  Colors::highlight, 4);
00158 }
00159 
00160 
00161 lisp_object_t* 
00162 Spring::serialize()
00163 {
00164   LispWriter obj ("spring");
00165   obj.write_int ("first", particles.first->get_id());
00166   obj.write_int ("second", particles.second->get_id());
00167   obj.write_float ("length", length);
00168   obj.write_float ("stiffness",   stiffness);
00169   obj.write_float ("damping",     damping);
00170   obj.write_float ("maxstretch", max_stretch);
00171 
00172   return obj.create_lisp ();
00173 }
00174 
00175 void
00176 Spring::recalc_length ()
00177 {
00178   length = fabs((particles.first->pos - particles.second->pos).norm ());
00179 }
00180 
00181 /* EOF */

Generated on Thu Jul 24 10:24:31 2003 for Construo by doxygen1.3-rc3