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 }