graphx icon indicating copy to clipboard operation
graphx copied to clipboard

DisplayObject.hitTest could bail out early when localPoint has a negative coordinate

Open tlvenn opened this issue 3 years ago • 5 comments

image As it can be seen in the image above, if the local point has either x or y negative, it's impossible to have a hit test so we should bail as early as possible.

For context, this is happening because I compute a layout of my background scene and then place each container / sprite using sprite.setPosition(x,y) to that their children are positioned in relative position to their parent.

tlvenn avatar Feb 25 '22 01:02 tlvenn

Mmm not sure if i understand this one... bounds should be transformed based on a coordinate space (display object container), based on their "pivot" points, the origin ( 0,0 ) of each display object. What are u trying to achieve?

roipeker avatar Feb 25 '22 03:02 roipeker

I am trying to have some relative positioning instead of absolute ones, and this is actually working just fine.

So for example, I create in my scene area1 sprite that I position at let's say (100, 200):

final area1 = GSprite()..setPosition(100,200);
addChild(area1);

Then I attach some children to that area1 that I want to position in relative position to where area1 is so I simply do:

final child1 = GSprite()..setPosition(10,20);
area1.addChild(child1);

And ultimately whenever a component want to draw in any given area, it can use a local coordinate system of that area without any computation or translation of coordinates.

So in the example above, If i click at (50, 200) in the canvas, when the GPoint is converted to a local coordinate of the area1, it will end up being (-50, 0). As soon as we observe such local point we know for sure it's outside of the bound.

Actually my assumption is that the area is clipped from (0,0) so you cannot draw outside of it but that actually might not be true so maybe we can do this optimization only when we have a rect clipping and we use its leftTop point as a comparison point.

tlvenn avatar Feb 25 '22 03:02 tlvenn

As a general rule of thumb, bounding boxes are processed for hit test when they are on the stage. Graphx tries to mimic flash display list, relative drawing is a basic concept (thats why we have display list hierarchies). I didnt understand the clipping part, are u using masks?

Btw, if by clipping you refer to the entire Scene, Canvas are not clipped by default, and you are free to draw anywhere.

I think there is a stage.maskBoundRect that clips the stage area, if thats what u need.

roipeker avatar Feb 25 '22 03:02 roipeker

Right now I am clipping some containers(sprites) to make sure their children cannot paint outside of them. To do this clipping, i use: sprite.maskRect = GRect(0, 0, layout.width - 1, layout.height - 1);

Also I have many GSprite / GShape that uses mouseUseShape = true so that the hitTest logic does not use the bounding box for those but do proper hit testing on the shape.

The conversation helped me frame better the ask, to illustrate the proposal, let's say we have this in the stage:

  • Container(Sprite with maskRect as above)
    • Child (Shape or Sprite using mouseUseShape = true so any hitTest is relatively expensive)

When the container receives the mouse event and transforms it to local coordinates, if the container has a mask and the point is outside of it, we should not try to hitTest the children, this is potentially expensive when they uses shapes for hitTesting and it's a waste of resources given we already know they cant match.

tlvenn avatar Feb 25 '22 04:02 tlvenn

Now I understood ... yep, you are correct.

roipeker avatar Feb 25 '22 04:02 roipeker