File indexing completed on 2024-04-14 14:08:24
0001 /* 0002 * box2drevolutejoint.cpp 0003 * Copyright (c) 2011 Joonas Erkinheimo <joonas.erkinheimo@nokia.com> 0004 * Copyright (c) 2011 Markus Kivioja <markus.kivioja@digia.com> 0005 * 0006 * This file is part of the Box2D QML plugin. 0007 * 0008 * This software is provided 'as-is', without any express or implied warranty. 0009 * In no event will the authors be held liable for any damages arising from 0010 * the use of this software. 0011 * 0012 * Permission is granted to anyone to use this software for any purpose, 0013 * including commercial applications, and to alter it and redistribute it 0014 * freely, subject to the following restrictions: 0015 * 0016 * 1. The origin of this software must not be misrepresented; you must not 0017 * claim that you wrote the original software. If you use this software in 0018 * a product, an acknowledgment in the product documentation would be 0019 * appreciated but is not required. 0020 * 0021 * 2. Altered source versions must be plainly marked as such, and must not be 0022 * misrepresented as being the original software. 0023 * 0024 * 3. This notice may not be removed or altered from any source distribution. 0025 */ 0026 0027 #include "box2drevolutejoint.h" 0028 0029 #include "box2dworld.h" 0030 #include "box2dbody.h" 0031 0032 Box2DRevoluteJoint::Box2DRevoluteJoint(QObject *parent) 0033 : Box2DJoint(RevoluteJoint, parent) 0034 , m_referenceAngle(0.0f) 0035 , m_enableLimit(false) 0036 , m_lowerAngle(0.0f) 0037 , m_upperAngle(0.0f) 0038 , m_enableMotor(false) 0039 , m_motorSpeed(0.0f) 0040 , m_maxMotorTorque(0.0f) 0041 , m_defaultLocalAnchorA(true) 0042 , m_defaultLocalAnchorB(true) 0043 , m_defaultReferenceAngle(true) 0044 { 0045 } 0046 0047 void Box2DRevoluteJoint::setLocalAnchorA(const QPointF &localAnchorA) 0048 { 0049 m_defaultLocalAnchorA = false; 0050 0051 if (m_localAnchorA == localAnchorA) 0052 return; 0053 0054 m_localAnchorA = localAnchorA; 0055 emit localAnchorAChanged(); 0056 } 0057 0058 void Box2DRevoluteJoint::setLocalAnchorB(const QPointF &localAnchorB) 0059 { 0060 m_defaultLocalAnchorB = false; 0061 0062 if (m_localAnchorB == localAnchorB) 0063 return; 0064 0065 m_localAnchorB = localAnchorB; 0066 emit localAnchorBChanged(); 0067 } 0068 0069 void Box2DRevoluteJoint::setReferenceAngle(float referenceAngle) 0070 { 0071 m_defaultReferenceAngle = false; 0072 0073 if (m_referenceAngle == referenceAngle) 0074 return; 0075 0076 m_referenceAngle = referenceAngle; 0077 emit referenceAngleChanged(); 0078 } 0079 0080 void Box2DRevoluteJoint::setEnableLimit(bool enableLimit) 0081 { 0082 if (m_enableLimit == enableLimit) 0083 return; 0084 0085 m_enableLimit = enableLimit; 0086 if (revoluteJoint()) 0087 revoluteJoint()->EnableLimit(enableLimit); 0088 emit enableLimitChanged(); 0089 } 0090 0091 void Box2DRevoluteJoint::setLowerAngle(float lowerAngle) 0092 { 0093 if (m_lowerAngle == lowerAngle) 0094 return; 0095 0096 m_lowerAngle = lowerAngle; 0097 if (revoluteJoint()) 0098 revoluteJoint()->SetLimits(toRadians(lowerAngle), 0099 m_upperAngle); 0100 emit lowerAngleChanged(); 0101 } 0102 0103 void Box2DRevoluteJoint::setUpperAngle(float upperAngle) 0104 { 0105 if (m_upperAngle == upperAngle) 0106 return; 0107 0108 m_upperAngle = upperAngle; 0109 if (revoluteJoint()) 0110 revoluteJoint()->SetLimits(m_lowerAngle, 0111 toRadians(upperAngle)); 0112 emit upperAngleChanged(); 0113 } 0114 0115 void Box2DRevoluteJoint::setEnableMotor(bool enableMotor) 0116 { 0117 if (m_enableMotor == enableMotor) 0118 return; 0119 0120 m_enableMotor = enableMotor; 0121 if (revoluteJoint()) 0122 revoluteJoint()->EnableMotor(enableMotor); 0123 emit enableMotorChanged(); 0124 } 0125 0126 void Box2DRevoluteJoint::setMotorSpeed(float motorSpeed) 0127 { 0128 if (m_motorSpeed == motorSpeed) 0129 return; 0130 0131 m_motorSpeed = motorSpeed; 0132 if (revoluteJoint()) 0133 revoluteJoint()->SetMotorSpeed(toRadians(motorSpeed)); 0134 emit motorSpeedChanged(); 0135 } 0136 0137 void Box2DRevoluteJoint::setMaxMotorTorque(float maxMotorTorque) 0138 { 0139 if (m_maxMotorTorque == maxMotorTorque) 0140 return; 0141 0142 m_maxMotorTorque = maxMotorTorque; 0143 if (revoluteJoint()) 0144 revoluteJoint()->SetMaxMotorTorque(maxMotorTorque); 0145 emit maxMotorTorqueChanged(); 0146 } 0147 0148 b2Joint *Box2DRevoluteJoint::createJoint() 0149 { 0150 b2RevoluteJointDef jointDef; 0151 initializeJointDef(jointDef); 0152 0153 // Default localAnchorA to bodyA center 0154 if (m_defaultLocalAnchorA) 0155 jointDef.localAnchorA = jointDef.bodyA->GetLocalCenter(); 0156 else 0157 jointDef.localAnchorA = world()->toMeters(m_localAnchorA); 0158 0159 // Default localAnchorB to the same world position as localAnchorA 0160 if (m_defaultLocalAnchorB) { 0161 b2Vec2 anchorA = jointDef.bodyA->GetWorldPoint(jointDef.localAnchorA); 0162 jointDef.localAnchorB = jointDef.bodyB->GetLocalPoint(anchorA); 0163 } else { 0164 jointDef.localAnchorB = world()->toMeters(m_localAnchorB); 0165 } 0166 0167 if (m_defaultReferenceAngle) { 0168 float32 angleA = jointDef.bodyA->GetAngle(); 0169 float32 angleB = jointDef.bodyB->GetAngle(); 0170 jointDef.referenceAngle = angleB - angleA; 0171 } else { 0172 jointDef.referenceAngle = toRadians(m_referenceAngle); 0173 } 0174 0175 jointDef.enableLimit = m_enableLimit; 0176 jointDef.lowerAngle = toRadians(m_lowerAngle); 0177 jointDef.upperAngle = toRadians(m_upperAngle); 0178 jointDef.enableMotor = m_enableMotor; 0179 jointDef.motorSpeed = toRadians(m_motorSpeed); 0180 jointDef.maxMotorTorque = m_maxMotorTorque; 0181 0182 return world()->world().CreateJoint(&jointDef); 0183 } 0184 0185 float Box2DRevoluteJoint::getJointAngle() const 0186 { 0187 if (revoluteJoint()) 0188 return toDegrees(revoluteJoint()->GetJointAngle()); 0189 return 0.0; 0190 } 0191 0192 float Box2DRevoluteJoint::getJointSpeed() const 0193 { 0194 if (revoluteJoint()) 0195 return revoluteJoint()->GetJointSpeed(); 0196 return 0.0; 0197 }