Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Node World Space Positioning #1743

Merged
merged 2 commits into from
Mar 15, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 12 additions & 0 deletions core/2d/Node.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
11 changes: 9 additions & 2 deletions core/2d/Node.h
Original file line number Diff line number Diff line change
Expand Up @@ -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.
*
Expand Down
48 changes: 48 additions & 0 deletions tests/cpp-tests/Source/NodeTest/NodeTest.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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) {}
Expand Down Expand Up @@ -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";
}
17 changes: 17 additions & 0 deletions tests/cpp-tests/Source/NodeTest/NodeTest.h
Original file line number Diff line number Diff line change
Expand Up @@ -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
Loading