File indexing completed on 2024-04-14 14:08:24
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 "box2dprismaticjoint.h" 0027 0028 #include "box2dworld.h" 0029 0030 Box2DPrismaticJoint::Box2DPrismaticJoint(QObject *parent) 0031 : Box2DJoint(PrismaticJoint, parent) 0032 , m_localAxisA(1.0, 0.0) 0033 , m_referenceAngle(0.0f) 0034 , m_enableLimit(false) 0035 , m_lowerTranslation(0.0f) 0036 , m_upperTranslation(0.0f) 0037 , m_enableMotor(false) 0038 , m_maxMotorForce(0.0f) 0039 , m_motorSpeed(0.0f) 0040 , m_defaultLocalAnchorA(true) 0041 , m_defaultLocalAnchorB(true) 0042 , m_defaultReferenceAngle(true) 0043 { 0044 } 0045 0046 void Box2DPrismaticJoint::setLocalAnchorA(const QPointF &localAnchorA) 0047 { 0048 m_defaultLocalAnchorA = false; 0049 0050 if (m_localAnchorA == localAnchorA) 0051 return; 0052 0053 m_localAnchorA = localAnchorA; 0054 emit localAnchorAChanged(); 0055 } 0056 0057 void Box2DPrismaticJoint::setLocalAnchorB(const QPointF &localAnchorB) 0058 { 0059 m_defaultLocalAnchorB = false; 0060 0061 if (m_localAnchorB == localAnchorB) 0062 return; 0063 0064 m_localAnchorB = localAnchorB; 0065 emit localAnchorBChanged(); 0066 } 0067 0068 void Box2DPrismaticJoint::setLocalAxisA(const QPointF &localAxisA) 0069 { 0070 if (m_localAxisA == localAxisA) 0071 return; 0072 0073 m_localAxisA = localAxisA; 0074 emit localAxisAChanged(); 0075 } 0076 0077 void Box2DPrismaticJoint::setLowerTranslation(float lowerTranslation) 0078 { 0079 if (m_lowerTranslation == lowerTranslation) 0080 return; 0081 0082 m_lowerTranslation = lowerTranslation; 0083 if (prismaticJoint()) { 0084 prismaticJoint()->SetLimits(world()->toMeters(lowerTranslation), 0085 prismaticJoint()->GetUpperLimit()); 0086 } 0087 emit lowerTranslationChanged(); 0088 } 0089 0090 void Box2DPrismaticJoint::setUpperTranslation(float upperTranslation) 0091 { 0092 if (m_upperTranslation == upperTranslation) 0093 return; 0094 0095 m_upperTranslation = upperTranslation; 0096 if (prismaticJoint()) { 0097 prismaticJoint()->SetLimits(prismaticJoint()->GetLowerLimit(), 0098 world()->toMeters(upperTranslation)); 0099 } 0100 emit upperTranslationChanged(); 0101 } 0102 0103 void Box2DPrismaticJoint::setMaxMotorForce(float maxMotorForce) 0104 { 0105 if (m_maxMotorForce == maxMotorForce) 0106 return; 0107 0108 m_maxMotorForce = maxMotorForce; 0109 if (prismaticJoint()) 0110 prismaticJoint()->SetMaxMotorForce(maxMotorForce); 0111 emit maxMotorForceChanged(); 0112 } 0113 0114 void Box2DPrismaticJoint::setMotorSpeed(float motorSpeed) 0115 { 0116 if (m_motorSpeed == motorSpeed) 0117 return; 0118 0119 m_motorSpeed = motorSpeed; 0120 if (prismaticJoint()) 0121 prismaticJoint()->SetMotorSpeed(toRadians(motorSpeed)); 0122 emit motorSpeedChanged(); 0123 } 0124 0125 void Box2DPrismaticJoint::setEnableLimit(bool enableLimit) 0126 { 0127 if (m_enableLimit == enableLimit) 0128 return; 0129 0130 m_enableLimit = enableLimit; 0131 if (prismaticJoint()) 0132 prismaticJoint()->EnableLimit(enableLimit); 0133 emit enableLimitChanged(); 0134 } 0135 0136 void Box2DPrismaticJoint::setEnableMotor(bool enableMotor) 0137 { 0138 if (m_enableMotor == enableMotor) 0139 return; 0140 0141 m_enableMotor = enableMotor; 0142 if (prismaticJoint()) 0143 prismaticJoint()->EnableMotor(enableMotor); 0144 emit enableMotorChanged(); 0145 } 0146 0147 void Box2DPrismaticJoint::setReferenceAngle(float referenceAngle) 0148 { 0149 m_defaultReferenceAngle = false; 0150 0151 if (m_referenceAngle == referenceAngle) 0152 return; 0153 0154 m_referenceAngle = referenceAngle; 0155 emit referenceAngleChanged(); 0156 } 0157 0158 b2Joint *Box2DPrismaticJoint::createJoint() 0159 { 0160 b2PrismaticJointDef jointDef; 0161 initializeJointDef(jointDef); 0162 0163 // Default localAnchorA to bodyA center 0164 if (m_defaultLocalAnchorA) 0165 jointDef.localAnchorA = jointDef.bodyA->GetLocalCenter(); 0166 else 0167 jointDef.localAnchorA = world()->toMeters(m_localAnchorA); 0168 0169 // Default localAnchorB to the same world position as localAnchorA 0170 if (m_defaultLocalAnchorB) { 0171 b2Vec2 anchorA = jointDef.bodyA->GetWorldPoint(jointDef.localAnchorA); 0172 jointDef.localAnchorB = jointDef.bodyB->GetLocalPoint(anchorA); 0173 } else { 0174 jointDef.localAnchorB = world()->toMeters(m_localAnchorB); 0175 } 0176 0177 jointDef.localAxisA = invertY(m_localAxisA); 0178 0179 if (m_defaultReferenceAngle) { 0180 float32 angleA = jointDef.bodyA->GetAngle(); 0181 float32 angleB = jointDef.bodyB->GetAngle(); 0182 jointDef.referenceAngle = angleB - angleA; 0183 } else { 0184 jointDef.referenceAngle = toRadians(m_referenceAngle); 0185 } 0186 0187 jointDef.enableLimit = m_enableLimit; 0188 jointDef.lowerTranslation = world()->toMeters(m_lowerTranslation); 0189 jointDef.upperTranslation = world()->toMeters(m_upperTranslation); 0190 jointDef.enableMotor = m_enableMotor; 0191 jointDef.maxMotorForce = m_maxMotorForce; 0192 jointDef.motorSpeed = toRadians(m_motorSpeed); 0193 0194 return world()->world().CreateJoint(&jointDef); 0195 } 0196 0197 float Box2DPrismaticJoint::getJointTranslation() const 0198 { 0199 if (prismaticJoint()) 0200 return world()->toPixels(prismaticJoint()->GetJointTranslation()); 0201 return 0.0f; 0202 } 0203 0204 float Box2DPrismaticJoint::getJointSpeed() const 0205 { 0206 if (prismaticJoint()) 0207 return prismaticJoint()->GetJointSpeed(); 0208 return 0.0f; 0209 }