File indexing completed on 2024-04-21 14:43:24

0001 /*
0002  * box2ddistancejoint.cpp
0003  * Copyright (c) 2011 Joonas Erkinheimo <joonas.erkinheimo@nokia.com>
0004  *
0005  * This file is part of the Box2D QML plugin.
0006  *
0007  * This software is provided 'as-is', without any express or implied warranty.
0008  * In no event will the authors be held liable for any damages arising from
0009  * the use of this software.
0010  *
0011  * Permission is granted to anyone to use this software for any purpose,
0012  * including commercial applications, and to alter it and redistribute it
0013  * freely, subject to the following restrictions:
0014  *
0015  * 1. The origin of this software must not be misrepresented; you must not
0016  *    claim that you wrote the original software. If you use this software in
0017  *    a product, an acknowledgment in the product documentation would be
0018  *    appreciated but is not required.
0019  *
0020  * 2. Altered source versions must be plainly marked as such, and must not be
0021  *    misrepresented as being the original software.
0022  *
0023  * 3. This notice may not be removed or altered from any source distribution.
0024  */
0025 
0026 #include "box2ddistancejoint.h"
0027 
0028 #include "box2dworld.h"
0029 #include "box2dbody.h"
0030 
0031 Box2DDistanceJoint::Box2DDistanceJoint(QObject *parent)
0032     : Box2DJoint(DistanceJoint, parent)
0033     , m_length(1.0f)
0034     , m_frequencyHz(0.0f)
0035     , m_dampingRatio(0.0f)
0036     , m_defaultLocalAnchorA(true)
0037     , m_defaultLocalAnchorB(true)
0038     , m_defaultLength(true)
0039 {
0040 }
0041 
0042 void Box2DDistanceJoint::setLocalAnchorA(const QPointF &localAnchorA)
0043 {
0044     m_defaultLocalAnchorA = false;
0045 
0046     if (m_localAnchorA == localAnchorA)
0047         return;
0048 
0049     m_localAnchorA = localAnchorA;
0050     emit localAnchorAChanged();
0051 }
0052 
0053 void Box2DDistanceJoint::setLocalAnchorB(const QPointF &localAnchorB)
0054 {
0055     m_defaultLocalAnchorB = false;
0056 
0057     if (m_localAnchorB == localAnchorB)
0058         return;
0059 
0060     m_localAnchorB = localAnchorB;
0061     emit localAnchorBChanged();
0062 }
0063 
0064 void Box2DDistanceJoint::setLength(float length)
0065 {
0066     if (m_length == length)
0067         return;
0068 
0069     m_length = length;
0070     m_defaultLength = false;
0071     if (distanceJoint())
0072         distanceJoint()->SetLength(world()->toMeters(length));
0073     emit lengthChanged();
0074 }
0075 
0076 void Box2DDistanceJoint::setFrequencyHz(float frequencyHz)
0077 {
0078     if (m_frequencyHz == frequencyHz)
0079         return;
0080 
0081     m_frequencyHz = frequencyHz;
0082     if (distanceJoint())
0083         distanceJoint()->SetFrequency(frequencyHz);
0084     emit frequencyHzChanged();
0085 }
0086 
0087 void Box2DDistanceJoint::setDampingRatio(float dampingRatio)
0088 {
0089     if (m_dampingRatio == dampingRatio)
0090         return;
0091 
0092     m_dampingRatio = dampingRatio;
0093     if (distanceJoint())
0094         distanceJoint()->SetDampingRatio(dampingRatio);
0095     emit dampingRatioChanged();
0096 }
0097 
0098 b2Joint *Box2DDistanceJoint::createJoint()
0099 {
0100     b2DistanceJointDef jointDef;
0101     initializeJointDef(jointDef);
0102 
0103     // Default to bodyA center
0104     if (m_defaultLocalAnchorA)
0105         jointDef.localAnchorA = jointDef.bodyA->GetLocalCenter();
0106     else
0107         jointDef.localAnchorA = world()->toMeters(m_localAnchorA);
0108 
0109     // Default to bodyB center
0110     if (m_defaultLocalAnchorB)
0111         jointDef.localAnchorB = jointDef.bodyB->GetLocalCenter();
0112     else
0113         jointDef.localAnchorB = world()->toMeters(m_localAnchorB);
0114 
0115     // Default to length between anchors
0116     if (m_defaultLength) {
0117         b2Vec2 a = jointDef.bodyA->GetWorldPoint(jointDef.localAnchorA);
0118         b2Vec2 b = jointDef.bodyB->GetWorldPoint(jointDef.localAnchorB);
0119         jointDef.length = (b - a).Length();
0120     } else {
0121         jointDef.length = world()->toMeters(m_length);
0122     }
0123 
0124     jointDef.frequencyHz = m_frequencyHz;
0125     jointDef.dampingRatio = m_dampingRatio;
0126 
0127     return world()->world().CreateJoint(&jointDef);
0128 }
0129 
0130 QPointF Box2DDistanceJoint::getReactionForce(float32 inv_dt) const
0131 {
0132     if (distanceJoint())
0133         return invertY(distanceJoint()->GetReactionForce(inv_dt));
0134     return QPointF();
0135 }
0136 
0137 float Box2DDistanceJoint::getReactionTorque(float32 inv_dt) const
0138 {
0139     if (distanceJoint())
0140         return distanceJoint()->GetReactionTorque(inv_dt);
0141     return 0.0f;
0142 }