QList<btRigidBody*> ObjectConstraintSlider::getRigidBodies() { QList<btRigidBody*> result; result += getRigidBody(); QUuid otherEntityID; withReadLock([&]{ otherEntityID = _otherID; }); if (!otherEntityID.isNull()) { result += getOtherRigidBody(otherEntityID); } return result; }
btTypedConstraint* ObjectConstraintBallSocket::getConstraint() { btPoint2PointConstraint* constraint { nullptr }; QUuid otherEntityID; glm::vec3 pivotInA; glm::vec3 pivotInB; withReadLock([&]{ constraint = static_cast<btPoint2PointConstraint*>(_constraint); pivotInA = _pivotInA; otherEntityID = _otherID; pivotInB = _pivotInB; }); if (constraint) { return constraint; } static QString repeatedBallSocketNoRigidBody = LogHandler::getInstance().addRepeatedMessageRegex( "ObjectConstraintBallSocket::getConstraint -- no rigidBody.*"); btRigidBody* rigidBodyA = getRigidBody(); if (!rigidBodyA) { qCDebug(physics) << "ObjectConstraintBallSocket::getConstraint -- no rigidBodyA"; return nullptr; } if (!otherEntityID.isNull()) { // This constraint is between two entities... find the other rigid body. btRigidBody* rigidBodyB = getOtherRigidBody(otherEntityID); if (!rigidBodyB) { qCDebug(physics) << "ObjectConstraintBallSocket::getConstraint -- no rigidBodyB"; return nullptr; } constraint = new btPoint2PointConstraint(*rigidBodyA, *rigidBodyB, glmToBullet(pivotInA), glmToBullet(pivotInB)); } else { // This constraint is between an entity and the world-frame. constraint = new btPoint2PointConstraint(*rigidBodyA, glmToBullet(pivotInA)); } withWriteLock([&]{ _constraint = constraint; }); // if we don't wake up rigidBodyA, we may not send the dynamicData property over the network forceBodyNonStatic(); activateBody(); updateBallSocket(); return constraint; }
btTypedConstraint* ObjectConstraintSlider::getConstraint() { btSliderConstraint* constraint { nullptr }; QUuid otherEntityID; glm::vec3 pointInA; glm::vec3 axisInA; glm::vec3 pointInB; glm::vec3 axisInB; withReadLock([&]{ constraint = static_cast<btSliderConstraint*>(_constraint); pointInA = _pointInA; axisInA = _axisInA; otherEntityID = _otherID; pointInB = _pointInB; axisInB = _axisInB; }); if (constraint) { return constraint; } static int repeatMessageID = LogHandler::getInstance().newRepeatedMessageID(); btRigidBody* rigidBodyA = getRigidBody(); if (!rigidBodyA) { HIFI_FCDEBUG_ID(physics(), repeatMessageID, "ObjectConstraintSlider::getConstraint -- no rigidBodyA"); return nullptr; } if (glm::length(axisInA) < FLT_EPSILON) { qCWarning(physics) << "slider axis cannot be a zero vector"; axisInA = DEFAULT_SLIDER_AXIS; } else { axisInA = glm::normalize(axisInA); } if (!otherEntityID.isNull()) { // This slider is between two entities... find the other rigid body. if (glm::length(axisInB) < FLT_EPSILON) { qCWarning(physics) << "slider axis cannot be a zero vector"; axisInB = DEFAULT_SLIDER_AXIS; } else { axisInB = glm::normalize(axisInB); } glm::quat rotA = glm::rotation(DEFAULT_SLIDER_AXIS, axisInA); glm::quat rotB = glm::rotation(DEFAULT_SLIDER_AXIS, axisInB); btTransform frameInA(glmToBullet(rotA), glmToBullet(pointInA)); btTransform frameInB(glmToBullet(rotB), glmToBullet(pointInB)); btRigidBody* rigidBodyB = getOtherRigidBody(otherEntityID); if (!rigidBodyB) { HIFI_FCDEBUG_ID(physics(), repeatMessageID, "ObjectConstraintSlider::getConstraint -- no rigidBodyB"); return nullptr; } constraint = new btSliderConstraint(*rigidBodyA, *rigidBodyB, frameInA, frameInB, true); } else { // This slider is between an entity and the world-frame. glm::quat rot = glm::rotation(DEFAULT_SLIDER_AXIS, axisInA); btTransform frameInA(glmToBullet(rot), glmToBullet(pointInA)); constraint = new btSliderConstraint(*rigidBodyA, frameInA, true); } withWriteLock([&]{ _constraint = constraint; }); // if we don't wake up rigidBodyA, we may not send the dynamicData property over the network forceBodyNonStatic(); activateBody(); updateSlider(); return constraint; }