From 28f39154451ef5fb9ad27f8c6a60939417d05ff7 Mon Sep 17 00:00:00 2001 From: Turky Mohammed <45469625+DelinWorks@users.noreply.github.com> Date: Fri, 15 Mar 2024 04:33:38 +0300 Subject: [PATCH] Node World Space Positioning (#1743) * node set world position * Adapt tests --- core/2d/Node.cpp | 12 +++++ core/2d/Node.h | 11 ++++- tests/cpp-tests/Source/NodeTest/NodeTest.cpp | 48 ++++++++++++++++++++ tests/cpp-tests/Source/NodeTest/NodeTest.h | 17 +++++++ 4 files changed, 86 insertions(+), 2 deletions(-) diff --git a/core/2d/Node.cpp b/core/2d/Node.cpp index d89ac6c891f7..db1f8a10cf73 100644 --- a/core/2d/Node.cpp +++ b/core/2d/Node.cpp @@ -1935,6 +1935,18 @@ Vec2 Node::getWorldPosition() const return convertToWorldSpace(Vec2(_anchorPoint.x * _contentSize.width, _anchorPoint.y * _contentSize.height)); } +void Node::setWorldPosition(const Vec2& position) +{ + auto p = getParent(); + if (p) + { + auto m = p->getNodeToWorldTransform(); + auto v = m.getInversed() * (Vec3(-m.m[12], -m.m[13], 0) + Vec3(position.x, position.y, 0)); + setPosition(Vec2(v.x, v.y)); + } + else setPosition(position); +} + void Node::updateTransform() { // Recursively iterate over children diff --git a/core/2d/Node.h b/core/2d/Node.h index a8984f387d56..410193931f0c 100644 --- a/core/2d/Node.h +++ b/core/2d/Node.h @@ -1609,12 +1609,19 @@ class AX_DLL Node : public Ref Vec2 convertTouchToNodeSpaceAR(Touch* touch) const; /** - * Gets position of widget in world space. + * Gets position of node in world space. * - * @return Position of widget in world space. + * @return Position of node in world space. */ Vec2 getWorldPosition() const; + /** + * Sets position of node in world space. + * + * @param position Position of node in world space. + */ + void setWorldPosition(const Vec2& position); + /** * Sets an additional transform matrix to the node. * diff --git a/tests/cpp-tests/Source/NodeTest/NodeTest.cpp b/tests/cpp-tests/Source/NodeTest/NodeTest.cpp index 76e7c4da5807..f2cf78673f4d 100644 --- a/tests/cpp-tests/Source/NodeTest/NodeTest.cpp +++ b/tests/cpp-tests/Source/NodeTest/NodeTest.cpp @@ -72,6 +72,7 @@ CocosNodeTests::CocosNodeTests() ADD_TEST_CASE(NodeNameTest); ADD_TEST_CASE(Issue16100Test); ADD_TEST_CASE(Issue16735Test); + ADD_TEST_CASE(NodeWorldSpace); } TestCocosNodeDemo::TestCocosNodeDemo(void) {} @@ -1520,3 +1521,50 @@ std::string Issue16735Test::subtitle() const { return "Sprite should appear on the center of screen"; } + +//------------------------------------------------------------------ +// +// NodeWorldSpace +// +//------------------------------------------------------------------ +void NodeWorldSpace::onEnter() +{ + TestCocosNodeDemo::onEnter(); + + scheduleUpdate(); + + parent = Sprite::create("Images/grossini.png"); + addChild(parent); + + child = Sprite::create("Images/grossini.png"); + child->setScale(0.5); + parent->addChild(child); +} + +void NodeWorldSpace::onExit() +{ + TestCocosNodeDemo::onExit(); +} + +void NodeWorldSpace::update(float dt) +{ + elapsedTime += dt; + + auto visibleSize = Director::getInstance()->getVisibleSize(); + auto origin = Director::getInstance()->getVisibleOrigin(); + + parent->setPosition(Vec2(visibleSize.x / 2 + sin(elapsedTime * 2) * 100, 50)); + parent->setRotation(elapsedTime * 180); + + child->setWorldPosition(visibleSize / 2); +} + +std::string NodeWorldSpace::title() const +{ + return "World Space Position"; +} + +std::string NodeWorldSpace::subtitle() const +{ + return "Child sprite (small one) should always stay at the center of screen\nthe child sprite is a child of the moving parent sprite"; +} diff --git a/tests/cpp-tests/Source/NodeTest/NodeTest.h b/tests/cpp-tests/Source/NodeTest/NodeTest.h index da0062cc6ba9..e9ff2bbc8cb5 100644 --- a/tests/cpp-tests/Source/NodeTest/NodeTest.h +++ b/tests/cpp-tests/Source/NodeTest/NodeTest.h @@ -352,4 +352,21 @@ class Issue16735Test : public TestCocosNodeDemo virtual void onExit() override; }; +class NodeWorldSpace : public TestCocosNodeDemo +{ +public: + CREATE_FUNC(NodeWorldSpace); + void update(float dt) override; + virtual std::string title() const override; + virtual std::string subtitle() const override; + + float elapsedTime; + + ax::Sprite* parent; + ax::Sprite* child; + + virtual void onEnter() override; + virtual void onExit() override; +}; + #endif