This machine mirrors various open-source projects.
20 Gbit/s uplink.
If there are any issues or you want another project mirrored, please contact
mirror-service -=AT=- netcologne DOT de !
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 <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 "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 */