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

Questions about joints #15

Closed
aaronfranke opened this issue Feb 22, 2023 · 3 comments
Closed

Questions about joints #15

aaronfranke opened this issue Feb 22, 2023 · 3 comments

Comments

@aaronfranke
Copy link
Contributor

aaronfranke commented Feb 22, 2023

https://github.com/eoineoineoin/glTF_Physics/tree/master/RigidBodies#joints

  • For linearAxes and angularAxes, their type is described as integer[1..3]. Shouldn't the range be [0..3], so that you can define a joint constraint only for linear or only for angular? Right now, if a joint constraint is required to have at least 1 item in each array, then a constraint must constrain both linearly and angularly.
  • For linearAxes and angularAxes, should we use a bitmask instead of an array of numbers? For example, 0 would be none, 1 would be X, 2 would be Y, 4 would be Z, therefore 3 would be X and Y, and 7 would be X, Y, and Z. This would be a more compact representation, both in memory and in the data required to store it.
  • For linearAxes and angularAxes, should we use strings "X", "Y", and "Z" instead of the numbers 0, 1, 2? If we want to improve readability by having different members for each axis, we could name them explicitly.
    • The above two points are brainstorming from OMI discussion, we are also fine with an array of numbers.
    • EDIT: OMI_physics_joint uses an array of numbers just like MSFT is doing.
  • What is the unit of springConstant? Is this the same as stiffness? https://en.wikipedia.org/wiki/Stiffness If so then it would be N/m or kg/s². Should we rename it to "stiffness" or "springStiffness" to better clarify what constant we are referring to? See also the Wikipedia page on Hooke's Law: https://en.wikipedia.org/wiki/Hooke%27s_law "k is a constant factor characteristic of the spring (i.e., its stiffness)"
  • For springConstant / stiffness, Godot has a property for this (incorrectly named "softness" where larger values are harder), but it does not take into account the mass of objects (so a 1kg object would spring the same if it were 100kg, and therefore Godot's property applies acceleration and has a unit of /s²). Should we define that it should? If so, the Godot importer will need to adjust this property according to the mass.
  • How will the infinity default value of springConstant work? It's not possible to set a default value of infinity inside of a JSON spec. Should we set it to a really high number instead? Or do we set it to the string "Infinity" and hope that no spec parsers explode trying to coerce that into a number?
  • What is the unit of springDamping? What is its default value? Godot has a damping property, but I don't know how to validate if it behaves the same way as what is being defined in this spec.
  • "at least one of the connected nodes or its ancestors should have rigidBody properties" Why allow connecting a child of a body, why not just always require a connected body to be connected directly?
  • How can you have a joint between a rigid body and a static body? Is it by joining to a node without a rigid body? Godot's joints only allow a body to be connected, or null to join to a fixed point in world space. However, joining to a fixed point in world space is not a good idea if we want glTF files to be instanced away from the origin. Otherwise, I guess we could just join to a kinematic body, and not move that body, but it would be clearer to have a static body type to join to. Anyway, the spec should define how to do this.
  • In my opinion, physics joints should be separate nodes referencing two rigid bodies, not part of a rigid body referencing another. This is more intuitive to work with since it's easy to visualize where the joint is, and it's simpler since you don't need custom constraints with different offsets for each joint. This is also how Godot, Blender, and Unreal work, and is more like how real life works.
  • Do you have any example files that contain joints, or any implementations that support joints?
@eoineoineoin
Copy link
Owner

I've been asked to add breakables and motors to joints, so will be looking closely at the joints this week and I'll tighten up the language, units, etc. as you suggest. Just to address your philosophical questions, though:

I'm not terribly pushed about how the axes are represented. The current 1/2/3 just seemed simplest to us, as they correspond to the columns of your constraint space transform. Having arrays feels a little more flexible and future-proof; I imagine a joint extension which would want to express linkages between different axes which could be used to make some more exotic linkages like a rack-and-pinion (but have not thought through all the possible details here.)

The reason the axes are specified as minItems=1, maxItems=3, is that the jointLimit (of which, there can be multiple per joint) specifies oneOf linearAxes and angularAxes, so in a single jointLimit you only limit angular or linear with a single limit (because it doesn't make sense to apply the min/max limit to linear/angular simultaneously) and then, the reason there's a 1 minimum is that you have to restrict something to have an effect. Motors may change this but not 100% sure until I actually work through it - my inclination is that it won't because then there isn't a coordinate system for the motor to work in.

I didn't realize "Infinity" was explicitly forbidden by RFC-4627 (silly assumption on my part) - that's a bit of a pain, unfortunately, as infinity is also useful for inertia tensors - probably means that we'd need to store those values as the reciprocal of what they currently are, so that a value of 0 could represent infinity.

As for the pivots, the way Blender and Godot show constraints in the UI is a simplification of what's happening under the hood - they both use a single pivot in world space to represent the constraint, which means that when you're authoring content, they assume that the constraint pivots in both bodies are aligned at authoring time, which isn't necessarily the case (Unity doesn't have this property -- in their Joint object, there's fields for specifying the constraint space in each of the connected nodes.) In order to not lose information when doing a "load->simulate/modify->save" you really do need two pivots and those pivots should be children of the simulated nodes in order to ensure that the constraint space is consistent when a parent or the pivot is transformed, either by the simulation, user repositioning node or an animation repositioning the nodes.

Where those pivots are in the scene tree doesn't really matter, but obviously, the joint can only have an affect if at least one of the pivots is associated with an object which can move. Right now, the way the constraint space is specified is that the joint object itself is used for one pivot and the transform of the connectedNode is used for the other. I think you're suggesting that a joint would have two referenced nodes to provide the pivots? Not terribly opposed to this; it just adds an additional node to the scene. The transform of the joint node itself wouldn't be significant (at least, as far as the simulation is concerned) - does that feel alright?

@aaronfranke
Copy link
Contributor Author

aaronfranke commented Mar 9, 2023

EDIT: I misunderstood the spec, since then Eoin has updated the spec and explained it to me better. I'm collapsing what I wrote before. I will write some further text on this topic in the near future.

@eoineoineoin You are right that where the pivots are in the scene tree does not really matter. However, the initial position of the joint does matter, because it determines where the jointed position is relative to each of the jointed nodes.

Screenshot 2023-03-09 at 3 44 38 PM

The above image shows the initial conditions of an example. A pin joint is a type of joint that constraints all linear axes and none of the angular axes. If I put the pin joint node at the right of the pole, the cube swings like this:

Godot.-.JointTest.DEBUG.-.9.March.2023.mp4

If instead I put the pin joint in the center of the pole, the cube swings like this:~~

Godot.-.JointTest.DEBUG.-.9.March.2023.1.mp4

I'm actually unsure of how you're supposed to recreate this scenario in MSFT_RigidBodies, how can you specify the jointed position on the bodies you are jointing if you don't have a decidated node with a position? Or, for that matter, how can you specify which axes to constrain if you don't have a dedicated node with a rotation (like a hinge or slider joint in the diagonal direction instead of being aligned with any of the world or object axes).

Also, another point. Joints in Godot connect together two bodies. How are you supposed to connect a joint to a static body if MSFT_RigidBodies does not support static bodies? I guess the only option would be to connect to a kinematic body and just not move it. Note: This is not the same as jointing to a fixed point in space, because you may instance a scene at one position and teleport it somewhere else later, for example a ceiling rope that you want to duplicate and place around a gym. The ceiling would serve to joint the rope, but it's not really kinematic because it doesn't otherwise move, it does not need simulated kinematic motion.

I've been asked to add breakables ... to joints

Note that Godot does not have breakables, so the spec should define what should happen in this case. Is it acceptable for a breakable joint to not be breakable if the physics engine does not support breakable joints?

@eoineoineoin
Copy link
Owner

Hi Aarron,

I think you've misinterpreted some part of the doc - if you can point to a particular part that was confusing, I'll be happy to fix it up, but otherwise, will take a holistic view of the docs. The joint does not need to be attached to a rigidBody node directly; the joint and it's connectedNode are what define the constraint space in both bodies. Note that this spec is more expressive than what the Godot UI shows you - the Godot UI assumes that, on creation, both the constraint spaces are aligned, which isn't necessarily the case for a real simulation. This is just a minor UI improvement which can be made on the Godot side*

I made a quick demo for you; can't attach a file to this issue, so don't have a better place to put this file right now, I have just uploaded it to my personal site: http://eoinrul.es/AaronConstraintDemo.gltf

You can simply drag-and-drop this file into my Godot importer and you'll get both the configurations you were highlighting. You'll also note that the joint is attached to the static bodies:

Peek.2023-03-15.09-06.mp4
  • Would like to do a bit here, but Godot 4 has been pretty unstable on my computer; until I get to the bottom of that, it's kinda frustrating to work on.

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

No branches or pull requests

2 participants