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

Sync node.ts changes from PR #18280 for native platforms. #18285

Merged
merged 1 commit into from
Feb 7, 2025
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
42 changes: 27 additions & 15 deletions native/cocos/core/scene-graph/Node.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -131,7 +131,7 @@
// _Scene.DetectConflict.afterAddChild(this);
#endif

bool shouldActiveNow = isActive() && !!(newParent && newParent->isActiveInHierarchy());

Check failure on line 134 in native/cocos/core/scene-graph/Node.cpp

View workflow job for this annotation

GitHub Actions / ClangTidy Android

variable 'shouldActiveNow' of type 'bool' can be declared 'const' (misc-const-correctness)
if (isActiveInHierarchy() != shouldActiveNow) {
// Director::getInstance()->getNodeActivator()->activateNode(this, shouldActiveNow); // TODO(xwx): use TS temporarily
emit<ActiveNode>(shouldActiveNow);
Expand All @@ -139,12 +139,12 @@
}

void Node::setActive(bool isActive) {
uint8_t isActiveU8 = isActive ? 1 : 0;

Check failure on line 142 in native/cocos/core/scene-graph/Node.cpp

View workflow job for this annotation

GitHub Actions / ClangTidy Android

variable 'isActiveU8' of type 'uint8_t' (aka 'unsigned char') can be declared 'const' (misc-const-correctness)
if (_active != isActiveU8) {
_active = isActiveU8;
Node *parent = _parent;
if (parent) {
bool couldActiveInScene = parent->isActiveInHierarchy();

Check failure on line 147 in native/cocos/core/scene-graph/Node.cpp

View workflow job for this annotation

GitHub Actions / ClangTidy Android

variable 'couldActiveInScene' of type 'bool' can be declared 'const' (misc-const-correctness)
if (couldActiveInScene) {
// Director::getInstance()->getNodeActivator()->activateNode(this, isActive); // TODO(xwx): use TS temporarily
emit<ActiveNode>(isActive);
Expand Down Expand Up @@ -175,7 +175,7 @@
emit<ParentChanged>(oldParent);
if (oldParent) {
if (!(oldParent->_objFlags & Flags::DESTROYING)) {
index_t removeAt = getIdxOfChild(oldParent->_children, this);

Check failure on line 178 in native/cocos/core/scene-graph/Node.cpp

View workflow job for this annotation

GitHub Actions / ClangTidy Android

variable 'removeAt' of type 'index_t' (aka 'int') can be declared 'const' (misc-const-correctness)
// TODO(): DEV
/*if (DEV && removeAt < 0) {
errorID(1633);
Expand Down Expand Up @@ -241,9 +241,9 @@
// }

bool Node::onPreDestroyBase() {
Flags destroyingFlag = Flags::DESTROYING;

Check failure on line 244 in native/cocos/core/scene-graph/Node.cpp

View workflow job for this annotation

GitHub Actions / ClangTidy Android

variable 'destroyingFlag' of type 'Flags' can be declared 'const' (misc-const-correctness)
_objFlags |= destroyingFlag;
bool destroyByParent = (!!_parent) && (!!(_parent->_objFlags & destroyingFlag));

Check failure on line 246 in native/cocos/core/scene-graph/Node.cpp

View workflow job for this annotation

GitHub Actions / ClangTidy Android

variable 'destroyByParent' of type 'bool' can be declared 'const' (misc-const-correctness)
#if CC_EDITOR
if (!destroyByParent) {
this->notifyEditorAttached(false);
Expand All @@ -255,7 +255,7 @@
if (!destroyByParent) {
if (_parent) {
emit<ParentChanged>(this);
index_t childIdx = getIdxOfChild(_parent->_children, this);

Check failure on line 258 in native/cocos/core/scene-graph/Node.cpp

View workflow job for this annotation

GitHub Actions / ClangTidy Android

variable 'childIdx' of type 'index_t' (aka 'int') can be declared 'const' (misc-const-correctness)
if (childIdx != -1) {
_parent->_children.erase(_parent->_children.begin() + childIdx);
}
Expand Down Expand Up @@ -356,7 +356,7 @@
ccstd::vector<IntrusivePtr<Node>> &siblings = _parent->_children;
index = index >= 0 ? index : static_cast<index_t>(siblings.size()) + index;
index = index >= 0 ? index : 0;
index_t oldIdx = getIdxOfChild(siblings, this);

Check failure on line 359 in native/cocos/core/scene-graph/Node.cpp

View workflow job for this annotation

GitHub Actions / ClangTidy Android

variable 'oldIdx' of type 'index_t' (aka 'int') can be declared 'const' (misc-const-correctness)
if (index != oldIdx) {
if (oldIdx != CC_INVALID_INDEX) {
siblings.erase(siblings.begin() + oldIdx);
Expand All @@ -372,8 +372,8 @@
}

Node *Node::getChildByPath(const ccstd::string &path) const {
size_t end = 0;

Check failure on line 375 in native/cocos/core/scene-graph/Node.cpp

View workflow job for this annotation

GitHub Actions / ClangTidy Android

variable 'end' of type 'size_t' (aka 'unsigned long') can be declared 'const' (misc-const-correctness)
ccstd::vector<ccstd::string> segments = StringUtil::split(path, "/");

Check failure on line 376 in native/cocos/core/scene-graph/Node.cpp

View workflow job for this annotation

GitHub Actions / ClangTidy Android

variable 'segments' of type 'ccstd::vector<ccstd::string>' (aka 'vector<basic_string<char, char_traits<char>, allocator<char>>>') can be declared 'const' (misc-const-correctness)
auto *lastNode = const_cast<Node *>(this);
for (const ccstd::string &segment : segments) {
if (segment.empty()) {
Expand Down Expand Up @@ -495,6 +495,7 @@
dirtyBits |= currDirtyBits;
bool positionDirty = dirtyBits & static_cast<uint32_t>(TransformBit::POSITION);
bool rotationScaleSkewDirty = dirtyBits & static_cast<uint32_t>(TransformBit::RSS);
bool foundSkewInAncestor = false;
if (parent) {
if (positionDirty && !rotationScaleSkewDirty) {
_worldPosition.transformMat4(_localPosition, parent->_worldMatrix);
Expand All @@ -507,19 +508,27 @@
static Mat4 localMatrix;
Mat4 *originalWorldMatrix = &_worldMatrix;
Mat4::fromRTS(_localRotation, _localPosition, _localScale, &localMatrix);
if (_hasSkewComp) {
// Save the original world matrix without skew side effect.
Mat4::multiply(_parent->_worldMatrix, localMatrix, &tempMat4);
originalWorldMatrix = &tempMat4;
//
// If skew is dirty, rotation and scale must be also dirty.
// See _updateNodeTransformFlags in ui-skew.ts.
updateLocalMatrixBySkew(&localMatrix);
if (skewCompCount > 0) {
foundSkewInAncestor = findSkewAndGetOriginalWorldMatrix(_parent, &tempMat4);
if (_hasSkewComp || foundSkewInAncestor) {
// Save the original world matrix without skew side effect.
Mat4::multiply(tempMat4, localMatrix, &tempMat4);
originalWorldMatrix = &tempMat4;

if (_hasSkewComp) {
updateLocalMatrixBySkew(&localMatrix);
}
}
}
Mat4::multiply(parent->_worldMatrix, localMatrix, &_worldMatrix);
const bool rotChanged = dirtyBits & static_cast<uint32_t>(TransformBit::ROTATION);
Quaternion *rotTmp = rotChanged ? &_worldRotation : nullptr;
Mat4::toRTS(*originalWorldMatrix, rotTmp, &_worldPosition, &_worldScale);
if (skewCompCount > 0 && foundSkewInAncestor) {
// NOTE: world position from Mat4.toSRT(originalWorldMatrix, ...) will not consider the skew factor.
// So we need to update the world position manually here.
Vec3::transformMat4(_localPosition, parent->_worldMatrix, &_worldPosition);
}
}
} else {
if (dirtyBits & static_cast<uint32_t>(TransformBit::POSITION)) {
Expand Down Expand Up @@ -747,15 +756,16 @@
notifyLocalRotationUpdated();
}

bool Node::getParentWorldMatrixNoSkew(Node *parent, Mat4 *out) {
if (!parent) {
/* static */
bool Node::findSkewAndGetOriginalWorldMatrix(Node *node, Mat4 *out) {
if (!node) {
return false;
}
static ccstd::vector<Node*> tempNodes;
tempNodes.resize(0);
auto &ancestors = tempNodes;
Node *startNode = nullptr;
for (auto *cur = parent; cur; cur = cur->_parent) {
for (auto *cur = node; cur; cur = cur->_parent) {
ancestors.emplace_back(cur);
if (cur->_hasSkewComp) {
startNode = cur;
Expand All @@ -769,11 +779,13 @@
auto iter = std::find(ancestors.begin(), ancestors.end(), startNode);
long start = static_cast<long>(iter - ancestors.begin());
for (long i = start; i >= 0; --i) {
const auto *node = ancestors[i];
Mat4::fromRTS(node->_localRotation, node->_localPosition, node->_localScale, &curMat4);
const auto *cur = ancestors[i];
Mat4::fromRTS(cur->_localRotation, cur->_localPosition, cur->_localScale, &curMat4);
Mat4::multiply(*out, curMat4, out);
}
ret = true;
} else {
out->set(node->_worldMatrix);
}

tempNodes.resize(0);
Expand Down Expand Up @@ -803,15 +815,15 @@
if (hasSkew) {
if (oldParent) {
// Calculate old parent's world matrix without skew side effect.
const bool foundSkewInOldParent = Node::getParentWorldMatrixNoSkew(oldParent, &tempMatrix);
const bool foundSkewInOldParent = Node::findSkewAndGetOriginalWorldMatrix(oldParent, &tempMatrix);
Mat4::fromRTS(_localRotation, _localPosition, _localScale, &localMatrix);
const Mat4 &oldParentMatrix = foundSkewInOldParent ? tempMatrix : oldParent->_worldMatrix;
// Calculate current node's world matrix without skew side effect.
Mat4::multiply(oldParentMatrix, localMatrix, &_worldMatrix);
}

// Calculate new parent's world matrix without skew side effect.
const bool foundSkewInNewParent = Node::getParentWorldMatrixNoSkew(_parent, &tempMatrix);
const bool foundSkewInNewParent = Node::findSkewAndGetOriginalWorldMatrix(_parent, &tempMatrix);
if (foundSkewInNewParent) {
newParentMatrix = &tempMatrix;
}
Expand Down
8 changes: 7 additions & 1 deletion native/cocos/core/scene-graph/Node.h
Original file line number Diff line number Diff line change
Expand Up @@ -610,7 +610,13 @@ class Node : public CCObject {
virtual void onBatchCreated(bool dontChildPrefab);
virtual void updateScene();

bool getParentWorldMatrixNoSkew(Node *parent, Mat4 *out);
/**
* Check whether the node or its parent has skew components and return the original world matrix without skew to `out` parameter.
* @param node The node and its parent for finding skew.
* @param out The node's original world matrix without skew.
* @return true if the node or its parent has skew components, otherwise returns false.
*/
static bool findSkewAndGetOriginalWorldMatrix(Node *node, Mat4 *out);
void onSetParent(Node *oldParent, bool keepWorldTransform);
void onHierarchyChanged(Node *);
void onHierarchyChangedBase(Node *oldParent);
Expand Down
Loading