1 /*
2 * box2dropejoint.cpp
3 * Copyright (c) 2011 Joonas Erkinheimo <joonas.erkinheimo@nokia.com>
4 * Copyright (c) 2011 Markus Kivioja <markus.kivioja@digia.com>
5 *
6 * This file is part of the Box2D QML plugin.
7 *
8 * This software is provided 'as-is', without any express or implied warranty.
9 * In no event will the authors be held liable for any damages arising from
10 * the use of this software.
11 *
12 * Permission is granted to anyone to use this software for any purpose,
13 * including commercial applications, and to alter it and redistribute it
14 * freely, subject to the following restrictions:
15 *
16 * 1. The origin of this software must not be misrepresented; you must not
17 * claim that you wrote the original software. If you use this software in
18 * a product, an acknowledgment in the product documentation would be
19 * appreciated but is not required.
20 *
21 * 2. Altered source versions must be plainly marked as such, and must not be
22 * misrepresented as being the original software.
23 *
24 * 3. This notice may not be removed or altered from any source distribution.
25 */
26
27 #include "box2dropejoint.h"
28
29 #include "box2dworld.h"
30
Box2DRopeJoint(QObject * parent)31 Box2DRopeJoint::Box2DRopeJoint(QObject *parent)
32 : Box2DJoint(RopeJoint, parent)
33 , m_maxLength(0.0f)
34 , m_defaultLocalAnchorA(true)
35 , m_defaultLocalAnchorB(true)
36 {
37 }
38
setLocalAnchorA(const QPointF & localAnchorA)39 void Box2DRopeJoint::setLocalAnchorA(const QPointF &localAnchorA)
40 {
41 m_defaultLocalAnchorA = false;
42
43 if (m_localAnchorA == localAnchorA)
44 return;
45
46 m_localAnchorA = localAnchorA;
47 emit localAnchorAChanged();
48 }
49
setLocalAnchorB(const QPointF & localAnchorB)50 void Box2DRopeJoint::setLocalAnchorB(const QPointF &localAnchorB)
51 {
52 m_defaultLocalAnchorB = false;
53
54 if (m_localAnchorB == localAnchorB)
55 return;
56
57 m_localAnchorB = localAnchorB;
58 emit localAnchorBChanged();
59 }
60
setMaxLength(float maxLength)61 void Box2DRopeJoint::setMaxLength(float maxLength)
62 {
63 if (m_maxLength == maxLength)
64 return;
65
66 m_maxLength = maxLength;
67 if (ropeJoint()) {
68 const float maxLengthMeters = world()->toMeters(maxLength);
69 if (maxLengthMeters < b2_linearSlop)
70 qWarning() << "RopeJoint: maxLength too small";
71
72 ropeJoint()->SetMaxLength(maxLengthMeters);
73 }
74 emit maxLengthChanged();
75 }
76
createJoint()77 b2Joint *Box2DRopeJoint::createJoint()
78 {
79 b2RopeJointDef jointDef;
80 initializeJointDef(jointDef);
81
82 // Default localAnchorA to bodyA center
83 if (m_defaultLocalAnchorA)
84 jointDef.localAnchorA = jointDef.bodyA->GetLocalCenter();
85 else
86 jointDef.localAnchorA = world()->toMeters(m_localAnchorA);
87
88 // Default localAnchorB to bodyB center
89 if (m_defaultLocalAnchorB)
90 jointDef.localAnchorB = jointDef.bodyB->GetLocalCenter();
91 else
92 jointDef.localAnchorB = world()->toMeters(m_localAnchorB);
93
94 jointDef.maxLength = world()->toMeters(m_maxLength);
95
96 if (jointDef.maxLength < b2_linearSlop)
97 qWarning() << "RopeJoint: maxLength too small";
98
99 return world()->world().CreateJoint(&jointDef);
100 }
101
getReactionForce(float32 inv_dt) const102 QPointF Box2DRopeJoint::getReactionForce(float32 inv_dt) const
103 {
104 if (ropeJoint())
105 return invertY(ropeJoint()->GetReactionForce(inv_dt));
106 return QPointF();
107 }
108
getReactionTorque(float32 inv_dt) const109 float Box2DRopeJoint::getReactionTorque(float32 inv_dt) const
110 {
111 if (ropeJoint())
112 return ropeJoint()->GetReactionTorque(inv_dt);
113 return 0.0f;
114 }
115