1 // $Id: spring.cxx,v 1.15 2003/07/27 18:46:11 grumbel Exp $
3 // Construo - A wire-frame construction game
4 // Copyright (C) 2002 Ingo Ruhnke <grumbel@gmx.de>
6 // This program is free software; you can redistribute it and/or
7 // modify it under the terms of the GNU General Public License
8 // as published by the Free Software Foundation; either version 2
9 // of the License, or (at your option) any later version.
11 // This program is distributed in the hope that it will be useful,
12 // but WITHOUT ANY WARRANTY; without even the implied warranty of
13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 // GNU General Public License for more details.
16 // You should have received a copy of the GNU General Public License
17 // along with this program; if not, write to the Free Software
18 // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
21 #include "construo_error.hxx"
22 #include "particle_factory.hxx"
25 Spring::Spring (Particle
* f
, Particle
* s
, float l
)
40 Spring::Spring (Particle
* f
, Particle
* s
)
45 length
= fabs((f
->pos
- s
->pos
).norm ());
57 Spring::Spring (World
* world
, lisp_object_t
* cursor
)
60 cursor
= lisp_cdr(cursor
); // Skip the identifer
70 LispReader
reader(cursor
);
71 reader
.read_int ("first", &first_id
);
72 reader
.read_int ("second", &second_id
);
73 reader
.read_float ("length", &length
);
74 reader
.read_float ("stiffness", &stiffness
);
75 reader
.read_float ("damping", &damping
);
76 reader
.read_float ("maxstretch", &max_stretch
);
78 particles
.first
= world
->get_particle_mgr()->lookup_particle (first_id
);
79 particles
.second
= world
->get_particle_mgr()->lookup_particle (second_id
);
81 if (particles
.first
== 0 || particles
.second
== 0)
83 throw ConstruoError ("Spring: Pair lookup failed");
86 particles
.first
->spring_links
+= 1;
87 particles
.second
->spring_links
+= 1;
91 //std::cout << "Spring: length missing in data file, recalculating" << std::endl;
92 length
= fabs((particles
.first
->pos
- particles
.second
->pos
).norm ());
98 particles
.first
->spring_links
-= 1;
99 particles
.second
->spring_links
-= 1;
103 Spring::update (float delta
)
105 Vector2d dist
= particles
.first
->pos
- particles
.second
->pos
;
107 // Calculate the stretchness of the spring, 0.0 if unstretch, else
109 float stretch
= (dist
.norm () - length
);
111 //std::cout << "Stretch: " << stretch << std::endl;
112 if (fabs(stretch
/length
) > max_stretch
&&
113 length
> 10.0f
) // atomar spring
114 { // If the spring is streched above limits, let it get destroyed
119 stretch
*= stiffness
;
120 float dterm
= (dist
.dot(particles
.first
->velocity
- particles
.second
->velocity
) * damping
)/dist
.norm ();
123 Vector2d force
= dist
* (stretch
+ dterm
);
125 /*std::cout << "DTerm: " << dterm << " HTerm: " << stretch
126 << " Force: " << force
129 particles
.first
->add_force (-force
);
130 particles
.second
->add_force (force
);
135 Spring::draw (ZoomGraphicContext
* gc
)
137 Vector2d dist
= particles
.first
->pos
- particles
.second
->pos
;
138 float stretch
= fabs(dist
.norm ()/length
- 1.0f
) * 10.0f
;
140 float color
= fabs((stretch
/max_stretch
));
142 if (particles
.first
->pos
.y
< 598.5f
144 particles
.second
->pos
.y
< 598.5f
)
146 gc
->GraphicContext::draw_line(particles
.first
->pos
,
147 particles
.second
->pos
,
148 Color(color
, 1.0f
- color
, 0.0f
),
154 Spring::draw_highlight (ZoomGraphicContext
* gc
)
156 gc
->GraphicContext::draw_line (particles
.first
->pos
, particles
.second
->pos
,
157 Colors::highlight
, 4);
164 LispWriter
obj ("spring");
165 obj
.write_int ("first", particles
.first
->get_id());
166 obj
.write_int ("second", particles
.second
->get_id());
167 obj
.write_float ("length", length
);
168 obj
.write_float ("stiffness", stiffness
);
169 obj
.write_float ("damping", damping
);
170 obj
.write_float ("maxstretch", max_stretch
);
172 return obj
.create_lisp ();
176 Spring::recalc_length ()
178 length
= fabs((particles
.first
->pos
- particles
.second
->pos
).norm ());