GDevelop
GDevelop copied to clipboard
Physics collision are in wrong position when objects have a non-default center points and non-zero angle
Describe the bug
Objects with non-default center points and non-zero angles have incorrect physics collisions.
https://user-images.githubusercontent.com/8879811/209406105-9d668ba5-ed67-4c4b-8500-9d3bd2b94001.mp4
To Reproduce
Steps to reproduce the behavior:
- Create an object and place it in the scene
- Edit the center point to be on the left edge
- Rotate the object in the scene editor
- Start a preview and notice how the physics collision doesn't match the visual object.
Note: The location of the ghost collision matches the incorrect bounding box drawn in the scene editor #4732.
Other details
Windows 11 GDevelop 5.1.153
Could the problem be found in this function?
Extensions\Physics2Behavior\physics2runtimebehavior.ts
updateBodyFromObject() {
<TRIMMED>
// The object object transform has changed, update body transform:
if (
this._objectOldX !== this.owner.getX() ||
this._objectOldY !== this.owner.getY() ||
this._objectOldAngle !== this.owner.getAngle()
) {
const pos = this.b2Vec2(
(this.owner.getDrawableX() + this.owner.getWidth() / 2) *
this._sharedData.invScaleX,
(this.owner.getDrawableY() + this.owner.getHeight() / 2) *
this._sharedData.invScaleY
);
body.SetTransform(pos, gdjs.toRad(this.owner.getAngle()));
body.SetAwake(true);
}
}
I tried changing the position vector to this, but it broke a lot of things.
const pos = this.b2Vec2(
this.owner.getAABBCenterX() * this._sharedData.invScaleX,
this.owner.getAABBCenterY() * this._sharedData.invScaleY
);
Am I on the right track?
Hi @tristanbob! Great job investigating that! I think you're on the right track, this is where the issue is happening. This issue is similar to the other one you opened that should be solved with https://github.com/4ian/GDevelop/pull/4814. We were not using the object custom center to operate the rotation transformation. So this function should:
- Test if the object is a Sprite
- If that's the case, check if the currently displayed sprite (in the animation) has a custom center
- If that's the case, we should use the position of this center (taking the object scale into account) to do the rotation.
Do you want to submit a PR for this? I can take over if needed!
@AlexandreSi thanks for your great work on this. I'd prefer you to complete this and I'll try again on the next puzzle! :)
Good call cause that's not easy! 😅 I'll try to submit a PR for this soon
Any updates on this? It breaks things like pinball paddles that pivot from one side.
https://user-images.githubusercontent.com/8879811/233738153-6c01a73b-51e7-4061-a02f-3c3649992ef4.mp4
This bug also breaks games where you want to build a structure with diagonals that are made by rotating objects with non-default centers.
https://twitter.com/VictrisGames/status/1653580321101860864?s=20
https://user-images.githubusercontent.com/8879811/235821117-f0af93d0-9ff0-4c9a-be44-6354e90e0682.mp4
I'm wondering if that's even possible with Box2D to have a center of rotation that is not the center of the body.
I'm wondering if that's even possible with Box2D to have a center of rotation that is not the center of the body.
It might be possible when you use the "SetAsBox" function:
https://gamedev.stackexchange.com/a/3760
https://box2d.org/documentation/classb2_polygon_shape.html#af80eb52027ffe85dd4d0a3110eae9d1b
Do you think this will accomplish what we want? (Collision shape to rotate around a non-center point)
Here is another use-case where this bug stops users from using Physics to swing an Axe from the handle:
https://twitter.com/VictrisGames/status/1686222172833091584
This bug is preventing pole-vaulting game mechanics that use physics.
https://twitter.com/VictrisGames/status/1788796595435344017