00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
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);
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
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
00108
00109 float stretch = (dist.norm () - length);
00110
00111
00112 if (fabs(stretch/length) > max_stretch &&
00113 length > 10.0f)
00114 {
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
00126
00127
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