File indexing completed on 2024-04-14 14:08:24
0001 /* 0002 * box2djoint.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 "box2djoint.h" 0027 #include "box2dworld.h" 0028 #include "box2dbody.h" 0029 0030 #include <QDebug> 0031 0032 Box2DJoint::Box2DJoint(JointType jointType, QObject *parent) : 0033 QObject(parent), 0034 mJointType(jointType), 0035 mCollideConnected(false), 0036 mComponentComplete(false), 0037 mInitializePending(false), 0038 mBodyA(0), 0039 mBodyB(0), 0040 mWorld(0), 0041 mJoint(0) 0042 { 0043 } 0044 0045 Box2DJoint::~Box2DJoint() 0046 { 0047 if (mJoint) 0048 mWorld->world().DestroyJoint(mJoint); 0049 } 0050 0051 void Box2DJoint::setCollideConnected(bool collideConnected) 0052 { 0053 if (mCollideConnected == collideConnected) 0054 return; 0055 0056 mCollideConnected = collideConnected; 0057 0058 emit collideConnectedChanged(); 0059 } 0060 0061 void Box2DJoint::setBodyA(Box2DBody *bodyA) 0062 { 0063 if (mBodyA == bodyA) 0064 return; 0065 0066 mBodyA = bodyA; 0067 0068 if (!bodyA || bodyA->body()) 0069 initialize(); 0070 else 0071 connect(bodyA, SIGNAL(bodyCreated()), this, SLOT(bodyACreated())); 0072 0073 emit bodyAChanged(); 0074 } 0075 0076 void Box2DJoint::setBodyB(Box2DBody *bodyB) 0077 { 0078 if (mBodyB == bodyB) 0079 return; 0080 0081 mBodyB = bodyB; 0082 0083 if (!bodyB || bodyB->body()) 0084 initialize(); 0085 else 0086 connect(bodyB, SIGNAL(bodyCreated()), this, SLOT(bodyBCreated())); 0087 0088 emit bodyBChanged(); 0089 } 0090 0091 void Box2DJoint::initialize() 0092 { 0093 // Delay initialization until the component is complete 0094 if (!mComponentComplete) { 0095 mInitializePending = true; 0096 return; 0097 } 0098 mInitializePending = false; 0099 0100 // Destroy any previously created joint 0101 if (mJoint) { 0102 mWorld->world().DestroyJoint(mJoint); 0103 mJoint = 0; 0104 mWorld = 0; 0105 } 0106 0107 if (!mBodyA || !mBodyB) 0108 return; 0109 if (!mBodyA->body() || !mBodyB->body()) 0110 return; 0111 0112 if (mBodyA->world() != mBodyB->world()) { 0113 qWarning() << "Joint: bodyA and bodyB are not from the same world"; 0114 return; 0115 } 0116 0117 if (mBodyA == mBodyB) { 0118 qWarning() << "Joint: bodyA and bodyB cannot be the same body"; 0119 return; 0120 } 0121 0122 mWorld = mBodyA->world(); 0123 mJoint = createJoint(); 0124 if (mJoint) 0125 emit created(); 0126 } 0127 0128 void Box2DJoint::componentComplete() 0129 { 0130 mComponentComplete = true; 0131 if (mInitializePending) 0132 initialize(); 0133 } 0134 0135 void Box2DJoint::initializeJointDef(b2JointDef &def) 0136 { 0137 def.userData = this; 0138 def.bodyA = bodyA()->body(); 0139 def.bodyB = bodyB()->body(); 0140 def.collideConnected = mCollideConnected; 0141 } 0142 0143 void Box2DJoint::bodyACreated() 0144 { 0145 disconnect(mBodyA, SIGNAL(bodyCreated()), this, SLOT(bodyACreated())); 0146 initialize(); 0147 } 0148 0149 void Box2DJoint::bodyBCreated() 0150 { 0151 disconnect(mBodyB, SIGNAL(bodyCreated()), this, SLOT(bodyBCreated())); 0152 initialize(); 0153 }