Skip to content

Commit

Permalink
If local scale is zero, also need to set the rotation dirty flag.
Browse files Browse the repository at this point in the history
  • Loading branch information
dumganhar committed Sep 6, 2024
1 parent d5001ae commit 87d8c2d
Show file tree
Hide file tree
Showing 4 changed files with 16 additions and 7 deletions.
11 changes: 8 additions & 3 deletions cocos/scene-graph/node.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2599,9 +2599,14 @@ export class Node extends CCObject implements ISchedulable, CustomSerializable {
Mat4.multiply(m4_2, Mat4.invert(m4_2, parent._mat), m4_1);
Mat3.fromQuat(m3_1, Quat.conjugate(qt_1, this._lrot));
Mat3.multiplyMat4(m3_1, m3_1, m4_2);
this._lscale.x = Vec3.set(v3_a, m3_1.m00, m3_1.m01, m3_1.m02).length();
this._lscale.y = Vec3.set(v3_a, m3_1.m03, m3_1.m04, m3_1.m05).length();
this._lscale.z = Vec3.set(v3_a, m3_1.m06, m3_1.m07, m3_1.m08).length();

const localScale = this._lscale;
localScale.x = Vec3.set(v3_a, m3_1.m00, m3_1.m01, m3_1.m02).length();
localScale.y = Vec3.set(v3_a, m3_1.m03, m3_1.m04, m3_1.m05).length();
localScale.z = Vec3.set(v3_a, m3_1.m06, m3_1.m07, m3_1.m08).length();
if (localScale.x === 0 || localScale.y === 0 || localScale.z === 0) {
rotationFlag = TransformBit.ROTATION;
}
} else {
Vec3.copy(this._lscale, worldScale);
}
Expand Down
4 changes: 4 additions & 0 deletions native/cocos/core/scene-graph/Node.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -654,6 +654,10 @@ void Node::setWorldScale(float x, float y, float z) {
_localScale.x = Vec3{localRS.m[0], localRS.m[1], localRS.m[2]}.length();
_localScale.y = Vec3{localRS.m[3], localRS.m[4], localRS.m[5]}.length();
_localScale.z = Vec3{localRS.m[6], localRS.m[7], localRS.m[8]}.length();

if (_localScale.x == 0 || _localScale.y == 0 || _localScale.z == 0) {
rotationFlag = TransformBit::ROTATION;
}
} else {
_worldScale.set(x, y, z);
_localScale = _worldScale;
Expand Down
4 changes: 2 additions & 2 deletions native/tests/unit-test/src/node_test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -181,11 +181,11 @@ TEST(NodeTest, setWorldScale0yz_and_rotation) {
)));

EXPECT_TRUE(son->getRotation().approxEquals(Quaternion(0.09406091491321403, 0.09406091491321403, 0.07892647901187543, 0.9879654343559627)));
EXPECT_TRUE(son->getWorldRotation().approxEquals(Quaternion(0.09406091491321403, 0.09406091491321403, 0.07892647901187543, 0.9879654343559627)));
EXPECT_TRUE(son->getWorldRotation().approxEquals(Quaternion(0, 0, 0, 1))); // Could not decompose rotation in Mat4.toSRT since there is a axis is zero, so the rotation will be reset to unit quaternion.

son->setRotationFromEuler(20, 20, 20);
EXPECT_TRUE(son->getRotation().approxEquals(Quaternion(0.1981076317236749, 0.1981076317236749, 0.1387164571097902, 0.9498760324550678)));
EXPECT_TRUE(son->getWorldRotation().approxEquals(Quaternion(0, 0, 0, 1))); // Could not decompose rotation in Mat4.toSRT since there is a axis is zero, so the rotation will be reset to unit quaternion.
EXPECT_TRUE(son->getWorldRotation().approxEquals(Quaternion(0, 0, 0, 1)));

son->setRotationFromEuler(10, 10, 10);
EXPECT_TRUE(son->getRotation().approxEquals(Quaternion(0.09406091491321403, 0.09406091491321403, 0.07892647901187543, 0.9879654343559627)));
Expand Down
4 changes: 2 additions & 2 deletions tests/core/node.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -633,11 +633,11 @@ describe(`Node`, () => {
))).toBeTruthy();

expect(son.rotation.equals(new Quat(0.09406091491321403, 0.09406091491321403, 0.07892647901187543, 0.9879654343559627))).toBeTruthy();
expect(son.worldRotation.equals(new Quat(0.09406091491321403, 0.09406091491321403, 0.07892647901187543, 0.9879654343559627))).toBeTruthy();
expect(son.worldRotation.equals(new Quat(0, 0, 0, 1))).toBeTruthy(); // Could not decompose rotation in Mat4.toSRT since there is a axis is zero, so the rotation will be reset to unit quaternion.

son.setRotationFromEuler(20, 20, 20);
expect(son.rotation.equals(new Quat(0.1981076317236749, 0.1981076317236749, 0.1387164571097902, 0.9498760324550678))).toBeTruthy();
expect(son.worldRotation.equals(new Quat(0, 0, 0, 1))).toBeTruthy(); // Could not decompose rotation in Mat4.toSRT since there is a axis is zero, so the rotation will be reset to unit quaternion.
expect(son.worldRotation.equals(new Quat(0, 0, 0, 1))).toBeTruthy();

son.setRotationFromEuler(10, 10, 10);
expect(son.rotation.equals(new Quat(0.09406091491321403, 0.09406091491321403, 0.07892647901187543, 0.9879654343559627))).toBeTruthy();
Expand Down

0 comments on commit 87d8c2d

Please sign in to comment.