2
* Copyright (c) 2011 Erin Catto http://box2d.org
4
* This software is provided 'as-is', without any express or implied
5
* warranty. In no event will the authors be held liable for any damages
6
* arising from the use of this software.
7
* Permission is granted to anyone to use this software for any purpose,
8
* including commercial applications, and to alter it and redistribute it
9
* freely, subject to the following restrictions:
10
* 1. The origin of this software must not be misrepresented; you must not
11
* claim that you wrote the original software. If you use this software
12
* in a product, an acknowledgment in the product documentation would be
13
* appreciated but is not required.
14
* 2. Altered source versions must be plainly marked as such, and must not be
15
* misrepresented as being the original software.
16
* 3. This notice may not be removed or altered from any source distribution.
19
#include <Box2D/Rope/b2Rope.h>
20
#include <Box2D/Common/b2Draw.h>
46
void b2Rope::Initialize(const b2RopeDef* def)
48
b2Assert(def->count >= 3);
50
m_ps = (b2Vec2*)b2Alloc(m_count * sizeof(b2Vec2));
51
m_p0s = (b2Vec2*)b2Alloc(m_count * sizeof(b2Vec2));
52
m_vs = (b2Vec2*)b2Alloc(m_count * sizeof(b2Vec2));
53
m_ims = (float32*)b2Alloc(m_count * sizeof(float32));
55
for (int32 i = 0; i < m_count; ++i)
57
m_ps[i] = def->vertices[i];
58
m_p0s[i] = def->vertices[i];
61
float32 m = def->masses[i];
72
int32 count2 = m_count - 1;
73
int32 count3 = m_count - 2;
74
m_Ls = (float32*)b2Alloc(count2 * sizeof(float32));
75
m_as = (float32*)b2Alloc(count3 * sizeof(float32));
77
for (int32 i = 0; i < count2; ++i)
80
b2Vec2 p2 = m_ps[i+1];
81
m_Ls[i] = b2Distance(p1, p2);
84
for (int32 i = 0; i < count3; ++i)
87
b2Vec2 p2 = m_ps[i + 1];
88
b2Vec2 p3 = m_ps[i + 2];
93
float32 a = b2Cross(d1, d2);
94
float32 b = b2Dot(d1, d2);
96
m_as[i] = b2Atan2(a, b);
99
m_gravity = def->gravity;
100
m_damping = def->damping;
105
void b2Rope::Step(float32 h, int32 iterations)
112
float32 d = expf(- h * m_damping);
114
for (int32 i = 0; i < m_count; ++i)
119
m_vs[i] += h * m_gravity;
122
m_ps[i] += h * m_vs[i];
126
for (int32 i = 0; i < iterations; ++i)
133
float32 inv_h = 1.0f / h;
134
for (int32 i = 0; i < m_count; ++i)
136
m_vs[i] = inv_h * (m_ps[i] - m_p0s[i]);
140
void b2Rope::SolveC2()
142
int32 count2 = m_count - 1;
144
for (int32 i = 0; i < count2; ++i)
147
b2Vec2 p2 = m_ps[i + 1];
150
float32 L = d.Normalize();
152
float32 im1 = m_ims[i];
153
float32 im2 = m_ims[i + 1];
155
if (im1 + im2 == 0.0f)
160
float32 s1 = im1 / (im1 + im2);
161
float32 s2 = im2 / (im1 + im2);
163
p1 -= m_k2 * s1 * (m_Ls[i] - L) * d;
164
p2 += m_k2 * s2 * (m_Ls[i] - L) * d;
171
void b2Rope::SetAngle(float32 angle)
173
int32 count3 = m_count - 2;
174
for (int32 i = 0; i < count3; ++i)
180
void b2Rope::SolveC3()
182
int32 count3 = m_count - 2;
184
for (int32 i = 0; i < count3; ++i)
187
b2Vec2 p2 = m_ps[i + 1];
188
b2Vec2 p3 = m_ps[i + 2];
190
float32 m1 = m_ims[i];
191
float32 m2 = m_ims[i + 1];
192
float32 m3 = m_ims[i + 2];
197
float32 L1sqr = d1.LengthSquared();
198
float32 L2sqr = d2.LengthSquared();
200
if (L1sqr * L2sqr == 0.0f)
205
float32 a = b2Cross(d1, d2);
206
float32 b = b2Dot(d1, d2);
208
float32 angle = b2Atan2(a, b);
210
b2Vec2 Jd1 = (-1.0f / L1sqr) * d1.Skew();
211
b2Vec2 Jd2 = (1.0f / L2sqr) * d2.Skew();
214
b2Vec2 J2 = Jd1 - Jd2;
217
float32 mass = m1 * b2Dot(J1, J1) + m2 * b2Dot(J2, J2) + m3 * b2Dot(J3, J3);
225
float32 C = angle - m_as[i];
235
angle += 2.0f * b2_pi;
239
float32 impulse = - m_k3 * mass * C;
241
p1 += (m1 * impulse) * J1;
242
p2 += (m2 * impulse) * J2;
243
p3 += (m3 * impulse) * J3;
251
void b2Rope::Draw(b2Draw* draw) const
253
b2Color c(0.4f, 0.5f, 0.7f);
255
for (int32 i = 0; i < m_count - 1; ++i)
257
draw->DrawSegment(m_ps[i], m_ps[i+1], c);