`toAbsoluteRect` and `canSee` are wrong for a child of an ancestor that is rotated by a non-right angle
Los mantenedores suelen responder en 1 día
Ya se ha fusionado un pull request relacionado.
- #4109 de @ufrshubham — fusionado
Evaluación
- Dificultad
- 2/5
- Tiempo estimado
- 1-3 horas
- Aptitud para principiantes
- 72/100
Línea de trabajo
Empieza con _toRectImpl en packages/flame/lib/src/components/position_component.dart, donde el atajo angle == 0 solo proyecta las esquinas superior izquierda e inferior derecha. Haz que toAbsoluteRect() tome el cuadro delimitador de las cuatro esquinas proyectadas, mientras que toRect() conserva el atajo. Ejecuta los casos con ancestros rotados del issue, incluida la cámara 2x2 de canSee() en (-7, 7), y comprueba que las pruebas existentes de 90° y 180° siguen pasando.
Escrito por el modelo de indexación a partir del texto del issue.
Descripción
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().
- Lenguaje dominante
- Dart
- Estrellas
- 10.8k
- Forks
- 1.1k
- Merge medio
- 1 d 14 h
- PR fusionados (30 d)
- 62
Preparar el entorno
- Sin Dockerfile ni archivo de Docker Compose
- Tiene una plantilla de pull request
- Leer la guía de contribución
Primeros pasos
- Lee el issue completo y luego la guía de contribución del proyecto.
- Comenta en el issue que vas a ocuparte — evita que dos personas hagan lo mismo.
- Haz un fork del repositorio y trabaja en una rama.
- Abre un pull request que haga referencia al número del issue.
Más de flame-engine/flame
-
[flame_3d] Object3D.isVisible only checks the center point, so partially visible objects are not drawnPosiblemente ocupada @ufrshubham la tomó hace 1 día. Abiertobug flame_3d
flame-engine/flame#4166 · 1 asignado ·
Los mantenedores suelen responder en 1 día
-
[flame_3d] Nested Object3D without computeLocalAabb is culled using its local positionPosiblemente ocupada @ufrshubham la tomó hace 1 día. Abiertobug flame_3d
flame-engine/flame#4165 · 1 asignado ·
Los mantenedores suelen responder en 1 día
-
[flame_3d] Children added to an Object3D after it was rendered can be culled while on screenPosiblemente ocupada @ufrshubham la tomó hace 1 día. Abiertobug flame_3d
flame-engine/flame#4164 · 1 asignado ·
Los mantenedores suelen responder en 1 día
-
[flame_3d] Nested components are culled at their old position after an ancestor movesPosiblemente ocupada @ufrshubham la tomó hace 1 día. Abiertobug flame_3d
flame-engine/flame#4163 · 1 asignado ·
Los mantenedores suelen responder en 1 día
-
Dificultad 5/5 Más de una semana Aptitud para principiantes 35/100
flame-engine/flame#4157 ·
Los mantenedores suelen responder en 1 día
Todos los issues de flame-engine/flame
Issues similares
-
Dificultad 2/5 1-3 horas Aptitud para principiantes 78/100
Los mantenedores suelen responder en 5 días
-
Dificultad 2/5 1-3 horas Aptitud para principiantes 76/100
Los mantenedores suelen responder en 4 días
-
area-clientside-dartpad
Dificultad 2/5 1-3 horas Aptitud para principiantes 65/100
Los mantenedores suelen responder en 2 días
-
'图片收藏'功能无法滑动Abierto
Dificultad 2/5 1-3 horas Aptitud para principiantes 68/100
venera-app/venera-prime#50 ·
-
Dificultad 1/5 1-3 horas Aptitud para principiantes 90/100
bannzai/medicalarm#475 ·
Los mantenedores suelen responder en 1 día