Jump to content

bounds of pixi.graphic unexpected behavior


unrealnl
 Share

Recommended Posts

Hi,

I was playing around with a selection tool in my application and i wanted to highlight the current selected objects with a simple outline.
However i noticed very strange behavior that i will illustrate below:

example1.jpg.4f4564824c7d5a8e34c1d64754fde031.jpg

this image was created using the (debug) code that you can find below, some observations and info:

  • using sprite position + sprite width / height etc, has a weird offset that can see by comparing the blue line to the green line.
  • using getbounds from PIXI and getbounds from box2d give the same result, yay!
  • my graphic is drawn using coordinates around (0,0), so can be negative and positive coordinates
body = this.selectedPhysicsBodies[i];
fixture = body.GetFixtureList();
while(fixture != null){
	aabb.Combine(aabb, fixture.GetAABB());
	fixture = fixture.GetNext();
}


//BLUE LINE
var sprite = body.myGraphic;
this.graphics.lineStyle(2, 0x0000FF, 1);
this.graphics.moveTo(sprite.x-sprite.width/2, sprite.y-sprite.height/2);
this.graphics.lineTo(sprite.x+sprite.width/2, sprite.y-sprite.height/2);
this.graphics.lineTo(sprite.x+sprite.width/2, sprite.y+sprite.height/2);
this.graphics.lineTo(sprite.x-sprite.width/2, sprite.y+sprite.height/2);
this.graphics.lineTo(sprite.x-sprite.width/2, sprite.y-sprite.height/2);

bounds = sprite.getBounds(true);

//GREEN LINE
this.graphics.lineStyle(3, 0x00FF00, 1);
this.graphics.moveTo(sprite.x+bounds.x, sprite.y+bounds.y);
this.graphics.lineTo(sprite.x+bounds.x+bounds.width, sprite.y+bounds.y);
this.graphics.lineTo(sprite.x+bounds.x+bounds.width, sprite.y+bounds.y+bounds.height);
this.graphics.lineTo(sprite.x+bounds.x, sprite.y+bounds.y+bounds.height);
this.graphics.lineTo(sprite.x+bounds.x, sprite.y+bounds.y);


//RED LINE
var lowerBoundPixi = getPIXIPointFromWorldPoint(aabb.lowerBound);
var upperBoundPixi = getPIXIPointFromWorldPoint(aabb.upperBound);

this.graphics.lineStyle(1, 0xFF0000, 1);
this.graphics.moveTo(lowerBoundPixi.x, lowerBoundPixi.y);
this.graphics.lineTo(upperBoundPixi.x, lowerBoundPixi.y);
this.graphics.lineTo(upperBoundPixi.x, upperBoundPixi.y);
this.graphics.lineTo(lowerBoundPixi.x, upperBoundPixi.y);
this.graphics.lineTo(lowerBoundPixi.x, lowerBoundPixi.y);

 

So we already found that using sprite position + width/height etc gives a weird result, but it will get funkier:

rotation90.jpg.29cbf45dc9cebdebdbe16a5f6ae8899f.jpg

 

Here you can find an object rotated 90 degree, some observations:

  • blue line has become irrelevant as it doesn't account for rotation
  • PIXI bounds are exactly the same as box2d bounds, again yay!

 

rotation45.jpg.e063b81dbaa903c0abcd95bbb89c947b.jpg

 

But look at this! This is an object rotation around 45 degrees, observations:

  • Uhh PIXI are you drunk?

I tried to debug what is going on here, but i cant seem to figure it out. I tried also to just use positive coordinates in my drawing but didn't seem to change a thing.

Any idea's what's going on here with any of these 2:

  1. Why do i have this weird offset in the first image with the blue line?
  2. Why is PIXI bounds not working for objects rotated around 45 degrees (or anywhere between the 90 degrees intervals)?

Thanks in advance!

 

 

 

 

Link to comment
Share on other sites

We had a bug about it: https://github.com/pixijs/pixi.js/pull/4176

Please use the latest version.

And even if it wont help, I agree that getBounds() has many problems, so yes, PIXI behaves like a drunk sometimes. I also advice to use getBounds() and not to use getLocalBounds() , width and height, because they actually change the transform.

Link to comment
Share on other sites

position + width/height is a bad idea, because anchors and if there are any children, getLocalBounds() will change the transform and affect everything.

Also, getBounds(skipBounds=true) should be called only if you are sure that transform is up-to-date. For example, you called some functions like toLocal, toGLobal or getBounds() before and didnt change coords, didnt call getLocalBounds/width/height after it. Or if it global updateTransform() was called, (from renderer.render).

It is all because of lazy transform computation, it saves a lot of CPU time. For example, if you change position.x, position.y, then scale.x, scale.y and other things, you dont want to compute matrix after each operation right? So PIXI does it only when necessary, and with skipUpdate=true it assumes that you know that transform is OK at this particular moment of time.

Link to comment
Share on other sites

I think its time for you to look at the sources: https://github.com/pixijs/pixi.js/blob/dev/src/core/display/DisplayObject.js#L194 , https://github.com/pixijs/pixi.js/blob/dev/src/core/display/Container.js#L343 

PIXI is not a black box, its an open-source. One I was a hero that wanted to fix all issues with bounds, but only a part of my PR's were merged, my solution was too heavy, I spent too much time on it and I dont care anymore. If you are ready to fix it and make more tests, I'll bless you and fight for your PR's.

Link to comment
Share on other sites

Thanks for the info! I played both with .getBounds(true) and with .getBounds(false) with similar results.
Anyways if its not worth further investigation on PIXI end, i leave it like that :)!

Ps. small FYI: your twitter link below your avatar does not work, only if i copy the link and remove the '@'  ;)!

Link to comment
Share on other sites

Here's a function I hacked up from pixie src that's getting the proper bounds even when rotated. It applies the world transform before calculating bounds. The function PIXI.Graphics.getPolyBounds() is right at the top of the CodePen. As far as I can tell so far it’s working well.. IDK if it's the best way but hopefully can be useful.. :)

 

Link to comment
Share on other sites

  • 7 months later...

Hi,

After looking again at this issue, i still have to conclude that its not working for complexer shapes.
@Tazi tried your polygonbounds, but also there i get weird results when rotating, see here:

image.png.be31ecdf914169e66a4cdb593b221b71.png

 

The Pen can be found here:

 

@ivan.popelyshev
I'm currently running version 4.7.0 and the normal getBounds() is giving me similar results.
Do note that my graphic is inside a container.
The setup is 
Stage > Container > Graphic
The Container is only being scaled and positioned.

Hope you can help me out!

Best

Link to comment
Share on other sites

Ok, i've got it. Pixi stores local bounds, and rotates them => bounds are bigger than needed.

https://github.com/pixijs/pixi.js/blob/dev/src/core/graphics/Graphics.js#L861

https://github.com/pixijs/pixi.js/blob/dev/src/core/graphics/Graphics.js#L927

I dont know when will I have time to make better implementation. I'll try today but no guarantees.

Link to comment
Share on other sites

  • 11 months later...

I have a similar problem, i am using graphics that are placed on the stage and rotated, and it provides me with some interesting results, i have tried Taz's implementation but it still seems to give me the wrong bounds.

 

Taz getPolyBounds

getPolyBounds().PNG.c5ccb264a9b6e60c1c5c67f7d2885e45.PNG

Graphics.getBounds(true)

getBounds(true).PNG.5a76ad4e099e9b54d52de3047b90773b.PNG

 

Both returns incorrect bounds of the graphics object. 

Link to comment
Share on other sites

  • 3 months later...

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Loading...
 Share

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...