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

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 "box2dwheeljoint.h"
0028 
0029 #include "box2dworld.h"
0030 #include "box2dbody.h"
0031 
0032 Box2DWheelJoint::Box2DWheelJoint(QObject *parent)
0033     : Box2DJoint(WheelJoint, parent)
0034     , m_enableMotor(false)
0035     , m_maxMotorTorque(0.0f)
0036     , m_motorSpeed(0.0f)
0037     , m_frequencyHz(2.0f)
0038     , m_dampingRatio(0.7f)
0039     , m_defaultLocalAnchorA(true)
0040     , m_defaultLocalAnchorB(true)
0041     , m_defaultLocalAxisA(true)
0042 {
0043 }
0044 
0045 void Box2DWheelJoint::setLocalAnchorA(const QPointF &localAnchorA)
0046 {
0047     m_defaultLocalAnchorA = false;
0048 
0049     if (m_localAnchorA == localAnchorA)
0050         return;
0051 
0052     m_localAnchorA = localAnchorA;
0053     emit localAnchorAChanged();
0054 }
0055 
0056 void Box2DWheelJoint::setLocalAnchorB(const QPointF &localAnchorB)
0057 {
0058     m_defaultLocalAnchorB = false;
0059 
0060     if (m_localAnchorB == localAnchorB)
0061         return;
0062 
0063     m_localAnchorB = localAnchorB;
0064     emit localAnchorBChanged();
0065 }
0066 
0067 void Box2DWheelJoint::setLocalAxisA(const QPointF &localAxisA)
0068 {
0069     m_defaultLocalAxisA = false;
0070 
0071     if (m_localAxisA == localAxisA)
0072         return;
0073 
0074     m_localAxisA = localAxisA;
0075     emit localAxisAChanged();
0076 }
0077 
0078 void Box2DWheelJoint::setEnableMotor(bool enableMotor)
0079 {
0080     if (m_enableMotor == enableMotor)
0081         return;
0082 
0083     m_enableMotor = enableMotor;
0084     if (wheelJoint())
0085         wheelJoint()->EnableMotor(enableMotor);
0086     emit enableMotorChanged();
0087 }
0088 
0089 void Box2DWheelJoint::setMaxMotorTorque(float maxMotorTorque)
0090 {
0091     if (m_maxMotorTorque == maxMotorTorque)
0092         return;
0093 
0094     m_maxMotorTorque = maxMotorTorque;
0095     if (wheelJoint())
0096         wheelJoint()->SetMaxMotorTorque(maxMotorTorque);
0097     emit maxMotorTorqueChanged();
0098 }
0099 
0100 void Box2DWheelJoint::setMotorSpeed(float motorSpeed)
0101 {
0102     if (m_motorSpeed == motorSpeed)
0103         return;
0104 
0105     m_motorSpeed = motorSpeed;
0106     if (wheelJoint())
0107         wheelJoint()->SetMotorSpeed(toRadians(motorSpeed));
0108     emit motorSpeedChanged();
0109 }
0110 
0111 void Box2DWheelJoint::setFrequencyHz(float frequencyHz)
0112 {
0113     if (m_frequencyHz == frequencyHz)
0114         return;
0115 
0116     m_frequencyHz = frequencyHz;
0117     if (wheelJoint())
0118         wheelJoint()->SetSpringFrequencyHz(frequencyHz);
0119     emit frequencyHzChanged();
0120 }
0121 
0122 void Box2DWheelJoint::setDampingRatio(float dampingRatio)
0123 {
0124     if (m_dampingRatio == dampingRatio)
0125         return;
0126 
0127     m_dampingRatio = dampingRatio;
0128     if (wheelJoint())
0129         wheelJoint()->SetSpringDampingRatio(dampingRatio);
0130     emit dampingRatioChanged();
0131 }
0132 
0133 b2Joint *Box2DWheelJoint::createJoint()
0134 {
0135     b2WheelJointDef jointDef;
0136     initializeJointDef(jointDef);
0137 
0138     // Default localAnchorA to bodyA center
0139     if (m_defaultLocalAnchorA)
0140         jointDef.localAnchorA = jointDef.bodyA->GetLocalCenter();
0141     else
0142         jointDef.localAnchorA = world()->toMeters(m_localAnchorA);
0143 
0144     // Default localAnchorB to the same world position as localAnchorA
0145     if (m_defaultLocalAnchorB) {
0146         b2Vec2 anchorA = jointDef.bodyA->GetWorldPoint(jointDef.localAnchorA);
0147         jointDef.localAnchorB = jointDef.bodyB->GetLocalPoint(anchorA);
0148     } else {
0149         jointDef.localAnchorB = world()->toMeters(m_localAnchorB);
0150     }
0151 
0152     if (!m_defaultLocalAxisA) {
0153         jointDef.localAxisA = invertY(m_localAxisA);
0154         jointDef.localAxisA.Normalize();
0155     }
0156 
0157     jointDef.enableMotor = m_enableMotor;
0158     jointDef.maxMotorTorque = m_maxMotorTorque;
0159     jointDef.motorSpeed = toRadians(m_motorSpeed);
0160     jointDef.frequencyHz = m_frequencyHz;
0161     jointDef.dampingRatio = m_dampingRatio;
0162 
0163     return world()->world().CreateJoint(&jointDef);
0164 }
0165 
0166 float Box2DWheelJoint::getJointTranslation() const
0167 {
0168     if (wheelJoint())
0169         return world()->toPixels(wheelJoint()->GetJointTranslation());
0170     return 0;
0171 }
0172 
0173 float Box2DWheelJoint::getJointSpeed() const
0174 {
0175     if (wheelJoint())
0176         return wheelJoint()->GetJointSpeed();
0177     return 0;
0178 }
0179 
0180 QPointF Box2DWheelJoint::getReactionForce(float32 inv_dt) const
0181 {
0182     if (wheelJoint())
0183         return invertY(wheelJoint()->GetReactionForce(inv_dt));
0184     return QPointF();
0185 }
0186 
0187 float Box2DWheelJoint::getReactionTorque(float32 inv_dt) const
0188 {
0189     if (wheelJoint())
0190         return wheelJoint()->GetReactionTorque(inv_dt);
0191     return 0.0f;
0192 }