Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add RigidBodyComponent#getPosition/getRotation to reduce Ammo coupling #6948

Open
wants to merge 1 commit into
base: main
Choose a base branch
from

Conversation

kungfooman
Copy link
Collaborator

@kungfooman kungfooman commented Sep 11, 2024

Partly helps with #2801

I basically just added RigidBodyComponent#getPosition and RigidBodyComponent#getRotation to reduce Ammo coupling and extended the comment a little bit for more info. This also allowed for code simplification, hence the render-physics.js script looks a bit simpler.

Why?

User scripts ideally shouldn't know what kind of physics engine we are using. If it's Ammo, Jolt, Havoc, Cannon.js or any other engine, we should not have a special case for any. The rigid body component on an entity should simply implement one interface for all. That will then of course also aid reusability of physics scripts.

Is this ideal?

Not sure, for starters:

  1. We have to call this._body.getWorldTransform() twice now since we ask for position and rotation individually.

  2. Should we use body.getWorldTransform() at all, isn't it better to use the motion shape transform?

  3. Since we have get linearVelocity(), should we rather have a get position() aswell instead of getPosition()?

I would love some feedback from the usual suspects when it comes to Ammo, for example @Maksims @willeastcott @yaustar @MushAsterion @LeXXik

I confirm I have read the contributing guidelines and signed the Contributor License Agreement.

@MushAsterion
Copy link
Collaborator

Definitely good to centralize interaction with body in a single script. Maybe add some documentation to the new functions?

@yaustar
Copy link
Contributor

yaustar commented Sep 12, 2024

Hmm, I don't tend to use getWorldTransform in my apps and usually grab the position and rotation from the entity. Trying to think of a situation where I would use this API and can't think of a use case

@kungfooman
Copy link
Collaborator Author

Thank you @yaustar very good point, I was also wondering about that - why is the render-physics.js script even using the position from the rigid body Ammo body. The biggest argument I found was that the entity position may be (0, 0, 0) in the first frame.

@Maksims
Copy link
Contributor

Maksims commented Sep 12, 2024

The only case where developer would need to use rigidbody's transforms directly - are some custom solutions, like ragdolls, some instancing cases, and mostly only when there are really a large quantity of rigidbodies, and developer want to avoid using entities for each ridigbody.

For the function names, it should be consistent with the rest of the APIs, so getPosition - is consistent with other (8) cases. There are cases of "position" in API, but these are not related to transform matrices, and are simply a vec3, while for rigidbody or entity it is more involved as it has to optionally compute world transform matrix, which is costly, so we want to emphasize the computation by having a function instead of an accessor.

@LeXXik
Copy link
Contributor

LeXXik commented Sep 20, 2024

We have to call this._body.getWorldTransform() twice now since we ask for position and rotation individually.

Its a bit expensive, but the cost is not high, unless you have hundreds of objects to sync.

Should we use body.getWorldTransform() at all, isn't it better to use the motion shape transform?

I assume you speak of motion state in Ammo. It should be preferred over using body transform. Body transforms are updated once per physics world update. Motion states are updated every frame with interpolated values, to make the body appear moving smoothly.

Overall, not sure I like the idea of storing the position/rotation on the rigidbody component. I don't see where it would be needed for the user. If the physics changed the transforms of a body, then the system should sync/update (preferably only if user allows it) the entity transform to reflect it.

@kungfooman
Copy link
Collaborator Author

I assume you speak of motion state in Ammo. It should be preferred over using body transform. Body transforms are updated once per physics world update. Motion states are updated every frame with interpolated values, to make the body appear moving smoothly.

Right, my main concern here is the Ammo coupling. If we end up with position/rotation on the rigidbody component isn't my main goal, even though @Maksims made a great point about ragdolls etc.

Maybe we should just simplify the render-physics.js script to use entity positions?

The bugs that are hiding in this Ammo coupling are also clearly visible when using e.g. linearOffset:

    const chassis = new pc.Entity('Chassis');
    chassis.addComponent('collision', {
        type: 'box',
        halfExtents: [0.6, 0.35, 1.65],
        linearOffset: [5, 5, 5]
    });
    chassis.setLocalPosition(0, 0.65, 0);

    // Create the car chassis, offset upwards in Y from the compound body
    const cab = new pc.Entity('Cab');
    cab.addComponent('collision', {
        type: 'box',
        halfExtents: [0.5, 0.2, 1],
        linearOffset: [5, 5, 5]
    });
    cab.setLocalPosition(0, 1.2, -0.25);

Result: 👻 🚗

image

We basically support offsets already, but probably the lack of a nice API just makes developers use the first internal Ammo function they can find, causing coupling effects aswell.

One way or another we just have to refactor it, so it's nice to get as many ideas/usecases as possible 👍

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants