File indexing completed on 2024-03-24 15:14:08
0001 /* 0002 * box2dprismaticjoint.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 "box2dpulleyjoint.h" 0027 0028 #include "box2dworld.h" 0029 #include "box2dbody.h" 0030 0031 Box2DPulleyJoint::Box2DPulleyJoint(QObject *parent) 0032 : Box2DJoint(PulleyJoint, parent) 0033 , m_lengthA(0.0f) 0034 , m_lengthB(0.0f) 0035 , m_ratio(1.0f) 0036 , m_defaultLocalAnchorA(true) 0037 , m_defaultLocalAnchorB(true) 0038 , m_defaultLengthA(true) 0039 , m_defaultLengthB(true) 0040 { 0041 setCollideConnected(true); 0042 } 0043 0044 void Box2DPulleyJoint::setGroundAnchorA(const QPointF &groundAnchorA) 0045 { 0046 if (m_groundAnchorA == groundAnchorA) 0047 return; 0048 0049 m_groundAnchorA = groundAnchorA; 0050 emit groundAnchorAChanged(); 0051 } 0052 0053 void Box2DPulleyJoint::setGroundAnchorB(const QPointF &groundAnchorB) 0054 { 0055 if (m_groundAnchorB == groundAnchorB) 0056 return; 0057 0058 m_groundAnchorB = groundAnchorB; 0059 emit groundAnchorBChanged(); 0060 } 0061 0062 void Box2DPulleyJoint::setLocalAnchorA(const QPointF &localAnchorA) 0063 { 0064 m_defaultLocalAnchorA = false; 0065 0066 if (m_localAnchorA == localAnchorA) 0067 return; 0068 0069 m_localAnchorA = localAnchorA; 0070 emit localAnchorAChanged(); 0071 } 0072 0073 void Box2DPulleyJoint::setLocalAnchorB(const QPointF &localAnchorB) 0074 { 0075 m_defaultLocalAnchorB = false; 0076 0077 if (m_localAnchorB == localAnchorB) 0078 return; 0079 0080 m_localAnchorB = localAnchorB; 0081 emit localAnchorBChanged(); 0082 } 0083 0084 void Box2DPulleyJoint::setLengthA(float lengthA) 0085 { 0086 m_defaultLengthA = false; 0087 0088 if (m_lengthA == lengthA) 0089 return; 0090 0091 m_lengthA = lengthA; 0092 emit lengthAChanged(); 0093 } 0094 0095 void Box2DPulleyJoint::setLengthB(float lengthB) 0096 { 0097 m_defaultLengthB = false; 0098 0099 if (m_lengthB == lengthB) 0100 return; 0101 0102 m_lengthB = lengthB; 0103 emit lengthBChanged(); 0104 } 0105 0106 void Box2DPulleyJoint::setRatio(float ratio) 0107 { 0108 if (m_ratio == ratio) 0109 return; 0110 0111 m_ratio = ratio; 0112 emit ratioChanged(); 0113 } 0114 0115 b2Joint *Box2DPulleyJoint::createJoint() 0116 { 0117 b2PulleyJointDef jointDef; 0118 initializeJointDef(jointDef); 0119 0120 jointDef.groundAnchorA = world()->toMeters(m_groundAnchorA); 0121 jointDef.groundAnchorB = world()->toMeters(m_groundAnchorB); 0122 0123 // Default localAnchorA to bodyA center 0124 if (m_defaultLocalAnchorA) 0125 jointDef.localAnchorA = jointDef.bodyA->GetLocalCenter(); 0126 else 0127 jointDef.localAnchorA = world()->toMeters(m_localAnchorA); 0128 0129 // Default localAnchorB to bodyB center 0130 if (m_defaultLocalAnchorB) 0131 jointDef.localAnchorB = jointDef.bodyB->GetLocalCenter(); 0132 else 0133 jointDef.localAnchorB = world()->toMeters(m_localAnchorB); 0134 0135 if (m_defaultLengthA) { 0136 b2Vec2 anchorA = jointDef.bodyA->GetWorldPoint(jointDef.localAnchorA); 0137 jointDef.lengthA = (anchorA - jointDef.groundAnchorA).Length(); 0138 } else { 0139 jointDef.lengthA = world()->toMeters(m_lengthA); 0140 } 0141 0142 if (m_defaultLengthB) { 0143 b2Vec2 anchorB = jointDef.bodyB->GetWorldPoint(jointDef.localAnchorB); 0144 jointDef.lengthB = (anchorB - jointDef.groundAnchorB).Length(); 0145 } else { 0146 jointDef.lengthB = world()->toMeters(m_lengthB); 0147 } 0148 0149 if (qFuzzyIsNull(jointDef.lengthA) || qFuzzyIsNull(jointDef.lengthB)) { 0150 qWarning() << "PulleyJoint: the joint length cannot be zero"; 0151 return 0; 0152 } 0153 0154 jointDef.ratio = m_ratio; 0155 0156 return world()->world().CreateJoint(&jointDef); 0157 } 0158 0159 float Box2DPulleyJoint::getCurrentLengthA() const 0160 { 0161 if (pulleyJoint()) 0162 return world()->toPixels(pulleyJoint()->GetCurrentLengthA()); 0163 return lengthA(); 0164 } 0165 0166 float Box2DPulleyJoint::getCurrentLengthB() const 0167 { 0168 if (pulleyJoint()) 0169 return world()->toPixels(pulleyJoint()->GetCurrentLengthB()); 0170 return lengthB(); 0171 } 0172 0173 QPointF Box2DPulleyJoint::getReactionForce(float32 inv_dt) const 0174 { 0175 if (pulleyJoint()) 0176 return invertY(pulleyJoint()->GetReactionForce(inv_dt)); 0177 return QPointF(); 0178 } 0179 0180 float Box2DPulleyJoint::getReactionTorque(float32 inv_dt) const 0181 { 0182 if (pulleyJoint()) 0183 return pulleyJoint()->GetReactionTorque(inv_dt); 0184 return 0.0f; 0185 }