void ObjectMotionState::handleHardAndEasyChanges(uint32_t flags, PhysicsEngine* engine) { if (flags & EntityItem::DIRTY_SHAPE) { // make sure the new shape is valid ShapeInfo shapeInfo; computeObjectShapeInfo(shapeInfo); btCollisionShape* newShape = getShapeManager()->getShape(shapeInfo); if (!newShape) { qCDebug(physics) << "Warning: failed to generate new shape!"; // failed to generate new shape! --> keep old shape and remove shape-change flag flags &= ~EntityItem::DIRTY_SHAPE; // TODO: force this object out of PhysicsEngine rather than just use the old shape if ((flags & HARD_DIRTY_PHYSICS_FLAGS) == 0) { // no HARD flags remain, so do any EASY changes if (flags & EASY_DIRTY_PHYSICS_FLAGS) { handleEasyChanges(flags); } return; } } getShapeManager()->releaseShape(_shape); _shape = newShape; _body->setCollisionShape(_shape); if (flags & EASY_DIRTY_PHYSICS_FLAGS) { handleEasyChanges(flags); } } else { if (flags & EASY_DIRTY_PHYSICS_FLAGS) { handleEasyChanges(flags); } } engine->reinsertObject(this); }
void DetailedMotionState::setShape(const btCollisionShape* shape) { if (_shape != shape) { if (_shape) { getShapeManager()->releaseShape(_shape); } _shape = shape; if (_body) { assert(_shape); _body->setCollisionShape(const_cast<btCollisionShape*>(_shape)); } } else if (shape) { // we need to release unused reference to shape getShapeManager()->releaseShape(shape); } }
void ObjectMotionState::handleHardAndEasyChanges(uint32_t flags, PhysicsEngine* engine) { if (flags & EntityItem::DIRTY_SHAPE) { // make sure the new shape is valid btCollisionShape* newShape = computeNewShape(); if (!newShape) { qCDebug(physics) << "Warning: failed to generate new shape!"; // failed to generate new shape! --> keep old shape and remove shape-change flag flags &= ~EntityItem::DIRTY_SHAPE; // TODO: force this object out of PhysicsEngine rather than just use the old shape if ((flags & HARD_DIRTY_PHYSICS_FLAGS) == 0) { // no HARD flags remain, so do any EASY changes if (flags & EASY_DIRTY_PHYSICS_FLAGS) { handleEasyChanges(flags, engine); } return; } } getShapeManager()->releaseShape(_shape); if (_shape != newShape) { _shape = newShape; _body->setCollisionShape(_shape); } else { // huh... the shape didn't actually change, so we clear the DIRTY_SHAPE flag flags &= ~EntityItem::DIRTY_SHAPE; } } if (flags & EASY_DIRTY_PHYSICS_FLAGS) { handleEasyChanges(flags, engine); } // it is possible that there are no HARD flags at this point (if DIRTY_SHAPE was removed) // so we check again befoe we reinsert: if (flags & HARD_DIRTY_PHYSICS_FLAGS) { engine->reinsertObject(this); } }
// virtual and protected btCollisionShape* EntityMotionState::computeNewShape() { if (_entity) { ShapeInfo shapeInfo; assert(entityTreeIsLocked()); _entity->computeShapeInfo(shapeInfo); return getShapeManager()->getShape(shapeInfo); } return nullptr; }
// virtual and protected const btCollisionShape* AvatarMotionState::computeNewShape() { ShapeInfo shapeInfo; _avatar->computeShapeInfo(shapeInfo); return getShapeManager()->getShape(shapeInfo); }