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 "math.hxx"
00022 #include "lisp_reader.hxx"
00023 #include "string_utils.hxx"
00024 #include "particle.hxx"
00025
00026 using namespace StringUtils;
00027
00028 Particle::Particle (int i, const Vector2d& arg_pos, const Vector2d& arg_velocity, float m, bool f)
00029 : id (i),
00030 pos (arg_pos),
00031 velocity (arg_velocity),
00032 mass (m),
00033 fixed (f),
00034 totale_force (0,0),
00035 spring_links (0)
00036 {
00037 }
00038
00039 Particle::Particle (const Particle& p)
00040 : id (p.id),
00041 pos (p.pos),
00042 velocity (p.velocity),
00043 mass (p.mass),
00044 fixed (p.fixed),
00045 totale_force (0,0),
00046 spring_links (0)
00047 {
00048 }
00049
00050 lisp_object_t*
00051 Particle::serialize()
00052 {
00053 LispWriter obj ("particle");
00054 obj.write_int ("id", id);
00055 obj.write_vector ("pos", pos);
00056 obj.write_vector ("velocity", velocity);
00057 obj.write_boolean ("fixed", fixed);
00058 obj.write_float ("mass", mass);
00059 return obj.create_lisp ();
00060 }
00061
00062 void
00063 Particle::draw_highlight (ZoomGraphicContext* gc)
00064 {
00065 gc->get_parent_gc()->draw_fill_circle (gc->world_to_screen(pos),
00066 Math::round(Math::max(6.0f, get_mass() + 3)),
00067 Colors::highlight);
00068 }
00069
00070 void
00071 Particle::draw_infos (ZoomGraphicContext* gc)
00072 {
00073 Vector2d p = gc->world_to_screen(pos);
00074 draw_velocity_vector (gc);
00075 gc->get_parent_gc()->draw_string (p + Vector2d(20.0f, 5.0f),
00076 "Particle: " + to_string (pos));
00077 gc->get_parent_gc()->draw_string (p + Vector2d(20.0f, 25.0f),
00078 "Fixed: " + to_string (fixed));
00079 gc->get_parent_gc()->draw_string (p + Vector2d(20.0f, 45.0f),
00080 "Mass : " + to_string (get_mass()));
00081 gc->get_parent_gc()->draw_string (p + Vector2d(20.0f, 70.0f),
00082 "Links : " + to_string (spring_links));
00083 }
00084
00085 void
00086 Particle::draw (ZoomGraphicContext* gc)
00087 {
00088 if (pos.y < 598.5f)
00089 {
00090 if (fixed)
00091 {
00092 gc->get_parent_gc()->draw_fill_circle (gc->world_to_screen(pos),
00093 4,
00094 Color(0.6f, 0.6f, 0.6f));
00095 }
00096 else
00097 {
00098 gc->get_parent_gc()->draw_fill_circle (gc->world_to_screen(pos),
00099 Math::round(Math::max(3.0f, get_mass())),
00100 Color(1.0f, 0.0f, 0.0f));
00101 }
00102 }
00103 }
00104
00105 void
00106 Particle::draw_velocity_vector (ZoomGraphicContext* gc)
00107 {
00108 gc->draw_line (int (pos.x), int (pos.y),
00109 int (pos.x + velocity.x), int (pos.y + velocity.y),
00110 Color (0.0f, 0.0f, 1.0f));
00111 }
00112
00113 void
00114 Particle::update (float delta)
00115 {
00116 const float max_velocity = 1000.0f;
00117
00118 if (fixed) return;
00119
00120 velocity += totale_force * delta * (1.0f/mass);
00121
00122
00123 if (0)
00124 velocity -= (velocity * (1.0f/mass) * delta) * 0.001f;
00125
00126
00127
00128 pos += velocity * delta;
00129
00130 float collision_damp = 0.2;
00131
00132 #if 0 // FIXME: Replace this with a generic shape collision handling thing
00133
00134 if (pos.x < 0) {
00135 velocity.x = fabs(velocity.x);
00136 pos.x = 0;
00137 velocity *= collision_damp;
00138 } else if (pos.x > 799) {
00139 velocity.x = -fabs(velocity.x);
00140 pos.x = 799;
00141 velocity *= collision_damp;
00142 }
00143
00144
00145 if (pos.y < 0) {
00146 velocity.y = fabs(velocity.y);
00147 pos.y = 0;
00148 velocity *= collision_damp;
00149 } else
00150 #endif
00151
00152 if (pos.y > 599) {
00153 velocity.y = -fabs(velocity.y);
00154 pos.y = 599;
00155 velocity *= collision_damp;
00156 }
00157
00158
00159
00160
00161
00162
00163
00164 clear_force ();
00165
00166
00167 if (velocity.norm () > max_velocity)
00168 {
00169 velocity.normalize();
00170 velocity *= max_velocity;
00171 }
00172 }
00173
00174
00175