will
May 24, 2020, 1:09pm
#1
I have just submitted a PR for a physics joint component on GitHub. It allows you to build some pretty cool physical structures.
It would be awesome if the community could provide some comments/feedback on my implementation:
playcanvas:master
← playcanvas:physics-joints
opened 10:33AM - 24 May 20 UTC
## Joint Component
This PR add support for physics joints (AKA constraints):
…

You can even enable spring 'motors' to power constraints:

Internally, it uses the ammo.js `btGeneric6DofSpringConstraint` class to implement a generic 6 degrees of freedom joint.
## API Overview
Here is the new API (it will be private initially until it has had further testing):
| API | Type | Description |
|---|---|---|
| `pc.JointComponent#angularDampingX` | `number` | Spring damping of angular X |
| `pc.JointComponent#angularDampingY` | `number` | Spring damping of angular Y |
| `pc.JointComponent#angularDampingZ` | `number` | Spring damping of angular Z |
| `pc.JointComponent#angularEquilibriumX` | `number` | Spring equilibrium of angular X. Can be -180 to 180 degrees. |
| `pc.JointComponent#angularEquilibriumY` | `number` | Spring equilibrium of angular Y. Can be -180 to 180 degrees. |
| `pc.JointComponent#angularEquilibriumZ` | `number` | Spring equilibrium of angular Z. Can be -180 to 180 degrees. |
| `pc.JointComponent#angularLimitsX` | `pc.Vec2` | The lower and upper angular limit for the X axis |
| `pc.JointComponent#angularLimitsY` | `pc.Vec2` | The lower and upper angular limit for the Y axis |
| `pc.JointComponent#angularLimitsZ` | `pc.Vec2` | The lower and upper angular limit for the Z axis |
| `pc.JointComponent#angularMotionX` | `string` | The allowed movement for angular X. Can be `"locked"`, `"limited"` or `"free"`. Defaults to `"locked"`. |
| `pc.JointComponent#angularMotionY` | `string` | The allowed movement for angular Y. Can be `"locked"`, `"limited"` or `"free"`. Defaults to `"locked"`. |
| `pc.JointComponent#angularMotionZ` | `string` | The allowed movement for angular Z. Can be `"locked"`, `"limited"` or `"free"`. Defaults to `"locked"`. |
| `pc.JointComponent#angularSpringX` | `boolean` | Enables a spring motor for angular X |
| `pc.JointComponent#angularSpringY` | `boolean` | Enables a spring motor for angular Y |
| `pc.JointComponent#angularSpringZ` | `boolean` | Enables a spring motor for angular Z |
| `pc.JointComponent#angularStiffnessX` | `number` | Spring stiffness of angular X |
| `pc.JointComponent#angularStiffnessY` | `number` | Spring stiffness of angular Y |
| `pc.JointComponent#angularStiffnessZ` | `number` | Spring stiffness of angular Z |
| `pc.JointComponent#breakForce` | `number` | The impulse required to break the constraint |
| `pc.JointComponent#enableCollision` | `boolean` | Are collisions between linked bodies taken into account |
| `pc.JointComponent#entityA` | `pc.Entity` | The first entity linked by the constraint (must have a rigidbody component |
| `pc.JointComponent#entityB` | `pc.Entity` | The second entity linked by the constraint (must have a rigidbody component |
| `pc.JointComponent#linearDampingX` | `number` | Spring damping of linear X |
| `pc.JointComponent#linearDampingY` | `number` | Spring damping of linear Y |
| `pc.JointComponent#linearDampingZ` | `number` | Spring damping of linear Z |
| `pc.JointComponent#linearEquilibriumX` | `number` | Spring equilibrium of linear X |
| `pc.JointComponent#linearEquilibriumY` | `number` | Spring equilibrium of linear Y |
| `pc.JointComponent#linearEquilibriumZ` | `number` | Spring equilibrium of linear Z |
| `pc.JointComponent#linearLimitsX` | `pc.Vec2` | The lower and upper linear limit for the X axis |
| `pc.JointComponent#linearLimitsY` | `pc.Vec2` | The lower and upper linear limit for the Y axis |
| `pc.JointComponent#linearLimitsZ` | `pc.Vec2` | The lower and upper linear limit for the Z axis |
| `pc.JointComponent#linearMotionX` | `string` | The allowed movement for linear X. Can be `"locked"`, `"limited"` or `"free"`. Defaults to `"locked"`. |
| `pc.JointComponent#linearMotionY` | `string` | The allowed movement for linear Y. Can be `"locked"`, `"limited"` or `"free"`. Defaults to `"locked"`. |
| `pc.JointComponent#linearMotionZ` | `string` | The allowed movement for linear Z. Can be `"locked"`, `"limited"` or `"free"`. Defaults to `"locked"`. |
| `pc.JointComponent#linearSpringX` | `boolean` | Enables a spring motor for linear X |
| `pc.JointComponent#linearSpringY` | `boolean` | Enables a spring motor for linear Y |
| `pc.JointComponent#linearSpringZ` | `boolean` | Enables a spring motor for linear Z |
| `pc.JointComponent#linearStiffnessX` | `number` | Spring stiffness of linear X |
| `pc.JointComponent#linearStiffnessY` | `number` | Spring stiffness of linear Y |
| `pc.JointComponent#linearStiffnessZ` | `number` | Spring stiffness of linear Z |
Code Example:
```javascript
entity.addComponent('joint', {
angularLimitsX: new pc.Vec2(0, 0),
angularLimitsY: new pc.Vec2(0, 0),
angularLimitsZ: new pc.Vec2(0, 0),
breakForce: 100,
enableCollision: true,
entityA: entityA,
entityB: entityB,
linearLimitsX: new pc.Vec2(0, 0),
linearLimitsY: new pc.Vec2(0, 0),
linearLimitsZ: new pc.Vec2(0, 0)
});
```
## Proposed Editor UI
The following is the proposed UI for the joint component in the Editor. It's prototyped below as a script component.
<img src="https://user-images.githubusercontent.com/697563/112146720-d1d9bc00-8bd3-11eb-9fd5-c77ff214b7ce.png" width="400">
Note that the spring checkboxes should probably show/hide stiffness and equilibrium attributes of the corresponding DOF.
## Open questions
* At the moment, a joint component would live on its own entity, separate from `entityA` and `entityB`. But should a joint component be added to the same entity as `entityA`? This would mean the `entityA` property would be implicit. One benefit of that is that you'd require one fewer entity, so your hierarchy would be simpler. But then a system for offsetting/editing the position/orientation of the joint would be needed.
* Should the joint expose presets for making it easier to configure simple, commonly needed joint types like a hinge?
* Should this component leverage the other ammo.js constraint types for these presets like:
* `btPoint2PointConstraint`
* `btHingeConstraint`
* `btConeTwistConstraint`
Or should everything be built using the `btGeneric6DofConstraint` API? Are the more specialized constraint types more stable and/or more performant? It would probably make the code bulkier to utilize the other ammo.js constraint classes.
* Should limits be in pairs (so 3 `pc.Vec2`s for angular limits and 3 for linear)? Or should there be 2 `pc.Vec3's for lower and upper for angular and the same again for linear? Or should they be individual numbers? For now, I've made them pairs (one for each axis) because I think that's easier to visualize when configuring a joint.
Fixes #478
I confirm I have signed the [Contributor License Agreement](https://docs.google.com/a/playcanvas.com/forms/d/1Ih69zQfJG-QDLIEpHr6CsaAs6fPORNOVnMv5nuo0cjk/viewform).
Looking forward to getting this merged and deployed!
6 Likes
Is this like the ragdoll project, or is it something else?
will
May 24, 2020, 8:39pm
#3
This is very similar. The ragdoll project has a script that implements various types of constraint. This PR for the engine introduces an official, built-in constraint (joint). In principle, you should be able to configure this joint component to act like a hinge constraint or a cone-twist constraint - the two constraint types you need in order to construct a rag doll.
I don’t know what PR stands for. Maybe I can use it for my characters and activate it when the character dies.
will
May 24, 2020, 9:31pm
#5
PR means Pull Request . A pull request is essentially a contribution to a project on GitHub.
And yes, you should be able to use this component to implement a switch from keyframed animation to rag doll simulation.
1 Like
will
May 26, 2020, 10:28am
#6
I posted a little update on Twitter! Amazing how VR is the perfect medium for prototyping physics-based code:
2 Likes