`toAbsoluteRect` and `canSee` are wrong for a child of an ancestor that is rotated by a non-right angle
メンテナーはふだん 1 日以内に返信
関連するプルリクエストがすでにマージされています。
- #4109 @ufrshubham による — マージ済み
評価
- 難易度
- 2/5
- 見積もり時間
- 1〜3時間
- 初心者へのやさしさ
- 72/100
調査の方向性
packages/flame/lib/src/components/position_component.dart の _toRectImpl から始めてください。ここでは angle == 0 の近道が左上隅と右下隅しか投影していません。toAbsoluteRect() が投影された4つの隅すべての外接矩形を取るようにし、toRect() は近道を維持してください。issue にある回転した祖先のケースを実行し、(-7, 7) にある 2x2 の canSee() カメラも含めて確認し、既存の 90° と 180° のテストが引き続き通ることを確かめてください。
索引モデルが issue の本文から書いたものです。
説明
What happened?
PositionComponent.toAbsoluteRect() returns a rectangle that is too small when an ancestor of the
component is rotated by an angle that is not a multiple of a quarter turn (like 45°), and the
component has no rotation of its own.
CameraComponent.canSee() is built on toAbsoluteRect(), so it can return false for a component
that is partly visible.
This was found in a review comment on #4107:
https://github.com/flame-engine/flame/pull/4107#discussion_r4237700858
The cause is the angle == 0 shortcut in _toRectImpl
(link).
When the component's own angle is 0, it only projects the top left and the bottom right corner,
and builds the rectangle from those two. That is only correct when nothing above the component is
rotated. With a rotated ancestor, the other two corners can stick out of that rectangle.
Rotations by 90° and 180° still give the right result, because the two corners are then still the
extreme ones. That is why the existing tests don't catch this.
https://github.com/user-attachments/assets/84ad9a7c-2a12-4416-9d3a-dcc8b73f22e0
What do you expect?
The smallest rectangle that contains the whole component in world coordinates, so the one made from
all four corners. canSee() should then be true whenever any part of the component is inside the
view.
How can we reproduce this?
A 100x10 child with no rotation of its own, inside a parent that is rotated by 45°:
final child = PositionComponent(size: Vector2(100, 10));
world.add(PositionComponent(angle: pi / 4, children: [child]));
// The corners of the child in world coordinates are:
// top left (0, 0)
// top right (70.71, 70.71)
// bottom left (-7.07, 7.07)
// bottom right (63.64, 77.78)
final rect = child.toAbsoluteRect();
// Expected: left -7.07, top 0, right 70.71, bottom 77.78
// Actual: left 0, top 0, right 63.64, bottom 77.78
For canSee(), use a camera with a 2x2 viewport that looks at (-7, 7). That view only contains the
bottom left corner of the child, at (-7.07, 7.07):
final camera = CameraComponent(
world: world,
viewport: FixedSizeViewport(2, 2),
)..viewfinder.position = Vector2(-7, 7);
camera.canSee(child); // Expected: true, actual: false
What steps should take to fix this?
Make toAbsoluteRect() always use all four corners. toRect() can keep the shortcut, because it is
in the coordinate space of the parent, where only the component's own angle matters.
Add tests for both cases above, and for a rotated ancestor in toAbsoluteRect() and canSee().
- 主要言語
- Dart
- スター
- 10.8k
- フォーク
- 1.1k
- 平均マージ
- 1日 16時間
- マージ済み PR(30日)
- 60
環境構築
- Dockerfile・Docker Compose ファイルなし
- プルリクエストのテンプレートあり
- コントリビューションガイドを読む
はじめの一歩
- issue を最後まで読み、次にプロジェクトのコントリビューションガイドを読みます。
- 着手することを issue にコメントします — 二人が同じ作業をするのを防げます。
- リポジトリをフォークし、ブランチを切って変更します。
- issue 番号を参照したプルリクエストを送ります。
flame-engine/flame のほかの issue
-
bug
難易度 4/5 3〜5日 初心者へのやさしさ 30/100
flame-engine/flame#4143 · コメント 5 件 ·
メンテナーはふだん 1 日以内に返信
-
enhancement
難易度 5/5 1週間以上 初心者へのやさしさ 35/100
flame-engine/flame#4131 · リアクション 1 件 ·
メンテナーはふだん 1 日以内に返信
-
enhancement v2
難易度 4/5 3〜5日 初心者へのやさしさ 25/100
flame-engine/flame#4116 ·
メンテナーはふだん 1 日以内に返信
-
難易度 4/5 3〜5日 初心者へのやさしさ 35/100
flame-engine/flame#4063 ·
メンテナーはふだん 1 日以内に返信
-
TextComponent shadows are not affected by OpacityEffect対応中かも @spydon が 48 日前に担当しました。 オープン
難易度 3/5 1〜2日 初心者へのやさしさ 72/100
flame-engine/flame#4013 ·
メンテナーはふだん 1 日以内に返信
flame-engine/flame の issue をすべて見る
似ている issue
-
area/ci-build bug
難易度 2/5 1〜3時間 初心者へのやさしさ 65/100
DarkFlippers/qUnleashed#423 ·
メンテナーはふだん 1 日以内に返信
-
難易度 2/5 1〜3時間 初心者へのやさしさ 72/100
-
難易度 2/5 1〜3時間 初心者へのやさしさ 67/100
google/skills_lint.dart#152 ·
メンテナーはふだん 1 日以内に返信
-
Docs: correct the unbuilt "full re-verify" claim and three untrue sync comments対応中かも @ibanner56 が今日担当しました。 オープンarea: sync priority: low severity: trivial type: docs
難易度 2/5 1〜3時間 初心者へのやさしさ 75/100
ibanner56/CallersCompendium#1942 ·
メンテナーはふだん 1 日以内に返信
-
[Bug]: 编辑器替换栏关闭按钮错位オープンbug
難易度 2/5 1〜3時間 初心者へのやさしさ 64/100
appshubcc/Bettbox#584 · コメント 1 件 ·
メンテナーはふだん 1 日以内に返信