|
31 | 31 | #include "parts/box2DRobot.h" |
32 | 32 | #include "parts/box2DItem.h" |
33 | 33 |
|
34 | | -//#define BOX2D_DEBUG_PATH |
35 | | - |
36 | | -#ifdef BOX2D_DEBUG_PATH |
37 | | -QGraphicsPathItem *debugPathBox2D = nullptr; |
38 | | -#endif |
39 | | - |
40 | | - |
41 | 34 | using namespace twoDModel::model::physics; |
42 | 35 | using namespace parts; |
43 | 36 | using namespace mathUtils; |
@@ -236,103 +229,112 @@ void Box2DPhysicsEngine::recalculateParameters(qreal timeInterval) |
236 | 229 | const int positionIterations = 6; |
237 | 230 |
|
238 | 231 | model::RobotModel * const robot = mRobots.first(); |
239 | | - if (mBox2DRobots[robot]) { |
240 | | - b2Body *rBody = mBox2DRobots[robot]->getBody(); |
241 | | - float secondsInterval = timeInterval / 1000.0f; |
| 232 | + if (!mBox2DRobots[robot]) { |
| 233 | + return; |
| 234 | + } |
| 235 | + |
| 236 | + b2Body *rBody = mBox2DRobots[robot]->getBody(); |
| 237 | + float secondsInterval = timeInterval / 1000.0f; |
| 238 | + |
| 239 | + if (mBox2DRobots[robot]->isStopping()){ |
| 240 | + mBox2DRobots[robot]->stop(); |
| 241 | + } else { |
| 242 | + // sAdpt is the speed adaptation coefficient for physics engines |
| 243 | + const int sAdpt = 10; |
| 244 | + const qreal speed1 = pxToM(wheelLinearSpeed(*robot, robot->leftWheel())) / secondsInterval * sAdpt; |
| 245 | + const qreal speed2 = pxToM(wheelLinearSpeed(*robot, robot->rightWheel())) / secondsInterval * sAdpt; |
242 | 246 |
|
243 | | - if (mBox2DRobots[robot]->isStopping()){ |
| 247 | + if (qAbs(speed1) + qAbs(speed2) < b2_epsilon) { |
244 | 248 | mBox2DRobots[robot]->stop(); |
245 | | - } else { |
246 | | - // sAdpt is the speed adaptation coefficient for physics engines |
247 | | - const int sAdpt = 10; |
248 | | - const qreal speed1 = pxToM(wheelLinearSpeed(*robot, robot->leftWheel())) / secondsInterval * sAdpt; |
249 | | - const qreal speed2 = pxToM(wheelLinearSpeed(*robot, robot->rightWheel())) / secondsInterval * sAdpt; |
250 | | - |
251 | | - if (qAbs(speed1) + qAbs(speed2) < b2_epsilon) { |
252 | | - mBox2DRobots[robot]->stop(); |
253 | | - mLeftWheels[robot]->stop(); |
254 | | - mRightWheels[robot]->stop(); |
255 | | - } |
256 | | - else { |
257 | | - mLeftWheels[robot]->keepConstantSpeed(speed1); |
258 | | - mRightWheels[robot]->keepConstantSpeed(speed2); |
259 | | - } |
| 249 | + mLeftWheels[robot]->stop(); |
| 250 | + mRightWheels[robot]->stop(); |
| 251 | + } |
| 252 | + else { |
| 253 | + mLeftWheels[robot]->keepConstantSpeed(speed1); |
| 254 | + mRightWheels[robot]->keepConstantSpeed(speed2); |
260 | 255 | } |
| 256 | + } |
261 | 257 |
|
262 | | - mPrevPosition = rBody->GetPosition(); |
263 | | - mPrevAngle = rBody->GetAngle(); |
| 258 | + mPrevPosition = rBody->GetPosition(); |
| 259 | + mPrevAngle = rBody->GetAngle(); |
264 | 260 |
|
265 | | - mWorld->Step(secondsInterval, velocityIterations, positionIterations); |
| 261 | + mWorld->Step(secondsInterval, velocityIterations, positionIterations); |
266 | 262 |
|
267 | | -#ifdef BOX2D_DEBUG_PATH |
268 | | - delete debugPathBox2D; |
269 | | - QPainterPath path; |
| 263 | + static volatile auto sThisFlagHelpsToAvoidClangError = true; |
| 264 | + if ("If you want debug BOX2D, fix this expression to be false" && sThisFlagHelpsToAvoidClangError) { |
| 265 | + return; |
| 266 | + } |
270 | 267 |
|
271 | | - for(QGraphicsItem *item : mBox2DDynamicItems.keys()) { |
272 | | - if (auto solidItem = dynamic_cast<items::SolidItem *>(item)) { |
273 | | - QPolygonF localCollidingPolygon = solidItem->collidingPolygon(); |
274 | | - qreal lsceneAngle = angleToScene(mBox2DDynamicItems[item]->getRotation()); |
275 | | - QMatrix m; |
276 | | - m.rotate(lsceneAngle); |
| 268 | + QPainterPath path; |
277 | 269 |
|
278 | | - QPointF firstP = localCollidingPolygon.at(0); |
279 | | - localCollidingPolygon.translate(-firstP.x(), -firstP.y()); |
| 270 | + for(QGraphicsItem *item : mBox2DDynamicItems.keys()) { |
| 271 | + if (auto solidItem = dynamic_cast<items::SolidItem *>(item)) { |
| 272 | + QPolygonF localCollidingPolygon = solidItem->collidingPolygon(); |
| 273 | + qreal lsceneAngle = angleToScene(mBox2DDynamicItems[item]->getRotation()); |
| 274 | + QMatrix m; |
| 275 | + m.rotate(lsceneAngle); |
280 | 276 |
|
281 | | - QPainterPath lpath; |
282 | | - lpath.addPolygon(localCollidingPolygon); |
283 | | - QPainterPath lpathTR = m.map(lpath); |
284 | | - lpathTR.translate(firstP.x(), firstP.y()); |
| 277 | + QPointF firstP = localCollidingPolygon.at(0); |
| 278 | + localCollidingPolygon.translate(-firstP.x(), -firstP.y()); |
285 | 279 |
|
286 | | - path.addPath(lpathTR); |
287 | | - } |
| 280 | + QPainterPath lpath; |
| 281 | + lpath.addPolygon(localCollidingPolygon); |
| 282 | + QPainterPath lpathTR = m.map(lpath); |
| 283 | + lpathTR.translate(firstP.x(), firstP.y()); |
| 284 | + |
| 285 | + path.addPath(lpathTR); |
288 | 286 | } |
| 287 | + } |
289 | 288 |
|
290 | | - qreal angleRobot= angleToScene(mBox2DRobots[robot]->getBody()->GetAngle()); |
291 | | - QPointF posRobot = positionToScene(mBox2DRobots[robot]->getBody()->GetPosition()); |
292 | | - QGraphicsRectItem *rect1 = new QGraphicsRectItem(-25, -25, 60, 50); |
293 | | - QGraphicsRectItem *rect2 = new QGraphicsRectItem(-10, -6, 20, 10); |
294 | | - QGraphicsRectItem *rect3 = new QGraphicsRectItem(-10, -6, 20, 10); |
295 | | - |
296 | | - rect1->setTransformOriginPoint(0, 0); |
297 | | - rect1->setRotation(angleRobot); |
298 | | - rect1->setPos(posRobot); |
299 | | - rect2->setTransformOriginPoint(0, 0); |
300 | | - rect2->setRotation(angleToScene(mBox2DRobots[robot]->getWheelAt(0)->getBody()->GetAngle())); |
301 | | - rect2->setPos(positionToScene(mBox2DRobots[robot]->getWheelAt(0)->getBody()->GetPosition())); |
302 | | - rect3->setTransformOriginPoint(0, 0); |
303 | | - rect3->setRotation(angleToScene(mBox2DRobots[robot]->getWheelAt(1)->getBody()->GetAngle())); |
304 | | - rect3->setPos(positionToScene(mBox2DRobots[robot]->getWheelAt(1)->getBody()->GetPosition())); |
305 | | - mScene->addItem(rect1); |
306 | | - mScene->addItem(rect2); |
307 | | - mScene->addItem(rect3); |
308 | | - QTimer::singleShot(20, [=](){ |
309 | | - delete rect1; |
310 | | - delete rect2; |
311 | | - delete rect3; |
312 | | - }); |
| 289 | + qreal angleRobot= angleToScene(mBox2DRobots[robot]->getBody()->GetAngle()); |
| 290 | + QPointF posRobot = positionToScene(mBox2DRobots[robot]->getBody()->GetPosition()); |
| 291 | + QGraphicsRectItem *rect1 = new QGraphicsRectItem(-25, -25, 60, 50); |
| 292 | + QGraphicsRectItem *rect2 = new QGraphicsRectItem(-10, -6, 20, 10); |
| 293 | + QGraphicsRectItem *rect3 = new QGraphicsRectItem(-10, -6, 20, 10); |
| 294 | + |
| 295 | + rect1->setTransformOriginPoint(0, 0); |
| 296 | + rect1->setRotation(angleRobot); |
| 297 | + rect1->setPos(posRobot); |
| 298 | + rect2->setTransformOriginPoint(0, 0); |
| 299 | + rect2->setRotation(angleToScene(mBox2DRobots[robot]->getWheelAt(0)->getBody()->GetAngle())); |
| 300 | + rect2->setPos(positionToScene(mBox2DRobots[robot]->getWheelAt(0)->getBody()->GetPosition())); |
| 301 | + rect3->setTransformOriginPoint(0, 0); |
| 302 | + rect3->setRotation(angleToScene(mBox2DRobots[robot]->getWheelAt(1)->getBody()->GetAngle())); |
| 303 | + rect3->setPos(positionToScene(mBox2DRobots[robot]->getWheelAt(1)->getBody()->GetPosition())); |
| 304 | + mScene->addItem(rect1); |
| 305 | + mScene->addItem(rect2); |
| 306 | + mScene->addItem(rect3); |
| 307 | + QTimer::singleShot(20, [this, rect1, rect2, rect3](){ |
| 308 | + for (auto &&rect: {rect1, rect2, rect3}) { |
| 309 | + mScene->removeItem(rect); |
| 310 | + delete rect; |
| 311 | + } |
| 312 | + }); |
313 | 313 |
|
314 | 314 |
|
315 | 315 | // uncomment it for watching mutual position of robot and wheels (polygon form) |
316 | 316 | // path.addPolygon(mBox2DRobots[robot]->getDebuggingPolygon()); |
317 | 317 | // path.addPolygon(mBox2DRobots[robot]->getWheelAt(0)->mDebuggingDrawPolygon); |
318 | 318 | // path.addPolygon(mBox2DRobots[robot]->getWheelAt(1)->mDebuggingDrawPolygon); |
319 | 319 |
|
320 | | - const QMap<const view::SensorItem *, Box2DItem *> sensors = mBox2DRobots[robot]->getSensors(); |
321 | | - for (Box2DItem * sensor : sensors.values()) { |
322 | | - const b2Vec2 position = sensor->getBody()->GetPosition(); |
323 | | - QPointF scenePos = positionToScene(position); |
324 | | - path.addEllipse(scenePos, 10, 10); |
325 | | - } |
326 | | - |
327 | | - debugPathBox2D = new QGraphicsPathItem(path); |
328 | | - debugPathBox2D->setBrush(Qt::blue); |
329 | | - debugPathBox2D->setPen(QPen(QColor(Qt::red))); |
330 | | - debugPathBox2D->setZValue(101); |
331 | | - mScene->addItem(debugPathBox2D); |
332 | | - mScene->update(); |
| 320 | + const QMap<const view::SensorItem *, Box2DItem *> sensors = mBox2DRobots[robot]->getSensors(); |
| 321 | + for (Box2DItem * sensor : sensors.values()) { |
| 322 | + const b2Vec2 position = sensor->getBody()->GetPosition(); |
| 323 | + QPointF scenePos = positionToScene(position); |
| 324 | + path.addEllipse(scenePos, 10, 10); |
| 325 | + } |
333 | 326 |
|
334 | | -#endif |
| 327 | + static QGraphicsPathItem *debugPathBox2D = nullptr; |
| 328 | + if (debugPathBox2D) { |
| 329 | + mScene->removeItem(debugPathBox2D); |
| 330 | + delete debugPathBox2D; |
335 | 331 | } |
| 332 | + debugPathBox2D = new QGraphicsPathItem(path); |
| 333 | + debugPathBox2D->setBrush(Qt::blue); |
| 334 | + debugPathBox2D->setPen(QPen(QColor(Qt::red))); |
| 335 | + debugPathBox2D->setZValue(101); |
| 336 | + mScene->addItem(debugPathBox2D); |
| 337 | + mScene->update(); |
336 | 338 | } |
337 | 339 |
|
338 | 340 | void Box2DPhysicsEngine::wakeUp() |
@@ -411,9 +413,7 @@ void Box2DPhysicsEngine::onItemDragged(graphicsUtils::AbstractItem *item) |
411 | 413 | Box2DItem *box2dItem = new Box2DItem(this, wallItem, pos, angleToBox2D(item->rotation())); |
412 | 414 | mBox2DResizableItems[item] = box2dItem; |
413 | 415 | return; |
414 | | - } |
415 | | - |
416 | | - if (auto solidItem = dynamic_cast<items::SolidItem *>(item)) { |
| 416 | + } else if (auto solidItem = dynamic_cast<items::SolidItem *>(item)) { |
417 | 417 | QPolygonF collidingPolygon = solidItem->collidingPolygon(); |
418 | 418 | if (itemTracked(item)) { |
419 | 419 | if (solidItem->bodyType() == items::SolidItem::DYNAMIC) { |
@@ -444,14 +444,9 @@ void Box2DPhysicsEngine::onItemDragged(graphicsUtils::AbstractItem *item) |
444 | 444 |
|
445 | 445 | void Box2DPhysicsEngine::itemRemoved(QGraphicsItem * const item) |
446 | 446 | { |
447 | | - if (mBox2DResizableItems.contains(item)) { |
448 | | - delete mBox2DResizableItems[item]; |
449 | | - mBox2DResizableItems.remove(item); |
450 | | - } |
451 | | - |
452 | | - if (mBox2DDynamicItems.contains(item)) { |
453 | | - mBox2DDynamicItems.remove(item); |
454 | | - } |
| 447 | + delete mBox2DResizableItems.value(item); |
| 448 | + mBox2DResizableItems.remove(item); |
| 449 | + mBox2DDynamicItems.remove(item); |
455 | 450 | } |
456 | 451 |
|
457 | 452 | b2World &Box2DPhysicsEngine::box2DWorld() |
|
0 commit comments