File indexing completed on 2024-04-14 14:08:25

0001 /*
0002  * box2dweldjoint.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 "box2dweldjoint.h"
0027 
0028 #include "box2dworld.h"
0029 #include "box2dbody.h"
0030 
0031 Box2DWeldJoint::Box2DWeldJoint(QObject *parent)
0032     : Box2DJoint(WeldJoint, parent)
0033     , m_referenceAngle(0.0f)
0034     , m_frequencyHz(0.0f)
0035     , m_dampingRatio(0.0f)
0036     , m_defaultLocalAnchorA(true)
0037     , m_defaultLocalAnchorB(true)
0038     , m_defaultReferenceAngle(true)
0039 {
0040 }
0041 
0042 void Box2DWeldJoint::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 Box2DWeldJoint::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 Box2DWeldJoint::setReferenceAngle(float referenceAngle)
0065 {
0066     m_defaultReferenceAngle = false;
0067 
0068     if (m_referenceAngle == referenceAngle)
0069         return;
0070 
0071     m_referenceAngle = referenceAngle;
0072     emit referenceAngleChanged();
0073 }
0074 
0075 void Box2DWeldJoint::setFrequencyHz(float frequencyHz)
0076 {
0077     if (m_frequencyHz == frequencyHz)
0078         return;
0079 
0080     m_frequencyHz = frequencyHz;
0081     if (weldJoint())
0082         weldJoint()->SetFrequency(frequencyHz);
0083     emit frequencyHzChanged();
0084 }
0085 
0086 void Box2DWeldJoint::setDampingRatio(float dampingRatio)
0087 {
0088     if (m_dampingRatio == dampingRatio)
0089         return;
0090 
0091     m_dampingRatio = dampingRatio;
0092     if (weldJoint())
0093         weldJoint()->SetDampingRatio(dampingRatio);
0094     emit dampingRatioChanged();
0095 }
0096 
0097 b2Joint *Box2DWeldJoint::createJoint()
0098 {
0099     b2WeldJointDef jointDef;
0100     initializeJointDef(jointDef);
0101 
0102     // Default localAnchorA to bodyA center
0103     if (m_defaultLocalAnchorA)
0104         jointDef.localAnchorA = jointDef.bodyA->GetLocalCenter();
0105     else
0106         jointDef.localAnchorA = world()->toMeters(m_localAnchorA);
0107 
0108     // Default localAnchorB to the same world position as localAnchorA
0109     if (m_defaultLocalAnchorB) {
0110         b2Vec2 anchorA = jointDef.bodyA->GetWorldPoint(jointDef.localAnchorA);
0111         jointDef.localAnchorB = jointDef.bodyB->GetLocalPoint(anchorA);
0112     } else {
0113         jointDef.localAnchorB = world()->toMeters(m_localAnchorB);
0114     }
0115 
0116     if (m_defaultReferenceAngle) {
0117         float32 angleA = jointDef.bodyA->GetAngle();
0118         float32 angleB = jointDef.bodyB->GetAngle();
0119         jointDef.referenceAngle = angleB - angleA;
0120     } else {
0121         jointDef.referenceAngle = toRadians(m_referenceAngle);
0122     }
0123 
0124     jointDef.frequencyHz = m_frequencyHz;
0125     jointDef.dampingRatio = m_dampingRatio;
0126 
0127     return world()->world().CreateJoint(&jointDef);
0128 }