@@ -34,6 +34,8 @@ THE SOFTWARE.
3434#include " axmol/base/text_utils.h"
3535#include " axmol/platform/StdC.h"
3636
37+ #include < cmath>
38+ #include < limits>
3739#include < vector>
3840
3941using namespace std ;
4648 kDefaultPadding = 5 ,
4749};
4850
51+ static bool hitTestNodeWithPointer (PointerEvent* event, const Camera* camera, Node* node, Vec3* outLocalHit)
52+ {
53+ if (!event || !camera || !node)
54+ return false ;
55+
56+ Rect rect;
57+ rect.size = node->getContentSize ();
58+ if (rect.size .width <= 0 .0f || rect.size .height <= 0 .0f )
59+ return false ;
60+
61+ if (event->hasRay ())
62+ {
63+ Ray localRay (event->getRay ().value ());
64+ localRay.transform (node->getWorldToNodeTransform ());
65+
66+ if (std::abs (localRay.direction .z ) <= std::numeric_limits<float >::epsilon ())
67+ return false ;
68+
69+ const float t = -localRay.origin .z / localRay.direction .z ;
70+ if (t < 0 .0f )
71+ return false ;
72+
73+ Vec3 localHit = localRay.origin + t * localRay.direction ;
74+ if (!rect.containsPoint (Vec2 (localHit.x , localHit.y )))
75+ return false ;
76+
77+ if (outLocalHit)
78+ *outLocalHit = localHit;
79+ return true ;
80+ }
81+
82+ return camera->isWorldPointInRect (event->getLocation (), node->getWorldToNodeTransform (), rect, outLocalHit);
83+ }
84+
4985//
5086// CCMenu
5187//
@@ -228,7 +264,8 @@ bool Menu::onPointerHitTest(PointerEvent* event, const Camera* camera, Vec3* out
228264 if (!event || !camera)
229265 return false ;
230266
231- if (!event->isPrimaryPressed ())
267+ const bool isControllerRay = event->getPointerType () == PointerType::Controller && event->hasRay ();
268+ if (!event->isPrimaryPressed () && !isControllerRay)
232269 return false ;
233270
234271 if (_state != Menu::State::WAITING || !_visible || !_enabled)
@@ -576,18 +613,24 @@ void Menu::alignItemsInRowsWithArray(const ValueVector& columns)
576613
577614MenuItem* Menu::hitTestItem (PointerEvent* event, const Camera* camera, Vec3* outHitPoint)
578615{
579- Vec2 touchLocation = event->getLocation ();
580616 for (const auto & item : _children)
581617 {
582618 MenuItem* child = dynamic_cast <MenuItem*>(item);
583619 if (!child || !child->isVisible () || !child->isEnabled ())
584620 {
585621 continue ;
586622 }
587- Rect rect;
588- rect. size = child-> getContentSize () ;
589- if (camera-> isWorldPointInRect (touchLocation, child-> getWorldToNodeTransform (), rect, outHitPoint ))
623+
624+ Vec3 childLocalHit ;
625+ if (hitTestNodeWithPointer (event, camera, child, &childLocalHit ))
590626 {
627+ if (outHitPoint)
628+ {
629+ Vec3 worldHit = childLocalHit;
630+ child->getNodeToWorldTransform ().transformPoint (&worldHit);
631+ *outHitPoint = worldHit;
632+ getWorldToNodeTransform ().transformPoint (outHitPoint);
633+ }
591634 return child;
592635 }
593636 }
0 commit comments