131 if (!componentComplete)
135 m_containerItem->setColor(m_color);
137 if (Q_UNLIKELY(m_manualPixelsPerUnit && m_pixelsPerUnit < 0)) {
138 qWarning() <<
"XrItem invalid pixelPerUnit" << m_pixelsPerUnit;
143 newScale = 1.0 / m_pixelsPerUnit;
146 qreal diagonal = std::sqrt((m_width * m_width) + (m_height * m_height));
147 qreal ppu = calculatePPU(m_contentItem->width(), m_contentItem->height(), diagonal);
150 q->setPixelsPerUnit(ppu);
151 newScale = 1.0 / ppu;
153 QSizeF newSize(m_width / newScale, m_height / newScale);
154 m_containerItem->setSize(newSize);
155 m_containerItem->setScale(newScale);
204 QQuick3DNode::componentComplete();
206 auto findView = [
this]() -> QQuick3DXrView * {
207 QQuick3DNode *parent = parentNode();
209 if (
auto *xrView = qobject_cast<QQuick3DXrView*>(parent))
211 parent = parent->parentNode();
215 d->m_XrView = findView();
217 d->m_XrView->registerXrItem(
this);
219 qWarning(
"Could not find XrView for XrItem");
361 auto mappedPos = mapPositionFromScene(pos);
363 QPointF point = {mappedPos.x(), -mappedPos.y()};
365 constexpr qreal sideMargin = 20;
366 constexpr qreal cancelDepth = 50;
367 constexpr qreal hoverHeight = 10;
369 constexpr qreal releaseHeight = 2;
370 constexpr qreal smallDistance = 0.5;
371 constexpr qreal longDistance = 5;
372 constexpr int releaseTime = 500;
373 constexpr qreal releaseHeightSquared = releaseHeight * releaseHeight;
374 constexpr qreal smallDistanceSquared = smallDistance * smallDistance;
375 constexpr qreal longDistanceSquared = longDistance * longDistance;
377 const float z = mappedPos.z();
379 const bool wayOutside = point.x() < -sideMargin || point.x() > width() + sideMargin
380 || point.y() < -sideMargin || point.y() > height() + sideMargin || z < -cancelDepth;
381 const bool inside = point.x() >= 0 && point.x() <= width() && point.y() >= 0 && point.y() <= height() && !wayOutside;
383 const bool wasGrabbed = touchState->grabbed;
384 const bool wasPressed = touchState->pressed;
386 bool hover = z > 0 && z < hoverHeight;
388 bool pressed =
false;
390 bool resetPrevious =
false;
391 qint64 now = QDateTime::currentMSecsSinceEpoch();
401 QVector3D distFromPrev = mappedPos - touchState->previous;
402 qint64 msSincePrev = now - touchState->timestamp;
404 const qreal prevZ = touchState->previous.z();
406 if (prevZ > 0 && z <= 0) {
409 resetPrevious =
true;
410 }
else if (msSincePrev > releaseTime || z > 0) {
411 resetPrevious =
true;
414 pressed = z <= 0 && wasPressed;
417 const qreal hDistSquared = distFromPrev.x() * distFromPrev.x() + distFromPrev.y() * distFromPrev.y();
418 const qreal vDistSquared = distFromPrev.z() * distFromPrev.z();
419 const qreal distSquared = hDistSquared + vDistSquared;
421 if (distSquared < smallDistanceSquared) {
423 resetPrevious =
false;
424 pressed = wasPressed;
425 }
else if (hDistSquared > longDistanceSquared) {
427 resetPrevious =
true;
428 pressed = wasPressed;
429 }
else if (vDistSquared > releaseHeightSquared) {
431 resetPrevious =
true;
432 pressed = distFromPrev.z() < 0;
434 resetPrevious =
false;
435 pressed = wasPressed;
439 grab = (z <= 0 && !wayOutside) || (hover && inside);
442 grab = hover && inside;
443 resetPrevious =
true;
447 float zOffset = qMin(z, 0.0);
449 *offset = sceneRotation() * QVector3D{ 0, 0, -zOffset };
450 touchState->grabbed =
true;
451 touchState->target =
this;
452 touchState->touchDistance = z;
453 touchState->pressed = pressed;
454 touchState->cursorPos = point;
456 touchState->previous = mappedPos;
457 touchState->timestamp = now;
459 view->setTouchpoint(d->m_containerItem, point, touchState->pointId, pressed && inside);
464 touchState->grabbed =
false;
465 touchState->target =
nullptr;
466 view->setTouchpoint(d->m_containerItem, point, touchState->pointId,
false);