Browse Source

Collider docs;

bjorn 1 year ago
parent
commit
64007233c5
40 changed files with 962 additions and 176 deletions
  1. 51 0
      api/lovr/physics/Collider/applyAngularImpulse.lua
  2. 22 10
      api/lovr/physics/Collider/applyForce.lua
  3. 79 0
      api/lovr/physics/Collider/applyLinearImpulse.lua
  4. 14 6
      api/lovr/physics/Collider/applyTorque.lua
  5. 6 2
      api/lovr/physics/Collider/getAABB.lua
  6. 10 11
      api/lovr/physics/Collider/getAngularDamping.lua
  7. 41 0
      api/lovr/physics/Collider/getAutomaticMass.lua
  8. 46 0
      api/lovr/physics/Collider/getCenterOfMass.lua
  9. 35 0
      api/lovr/physics/Collider/getEnabledAxes.lua
  10. 13 4
      api/lovr/physics/Collider/getFriction.lua
  11. 74 0
      api/lovr/physics/Collider/getInertia.lua
  12. 8 12
      api/lovr/physics/Collider/getLinearDamping.lua
  13. 6 6
      api/lovr/physics/Collider/getLinearVelocity.lua
  14. 12 9
      api/lovr/physics/Collider/getLinearVelocityFromLocalPoint.lua
  15. 9 8
      api/lovr/physics/Collider/getLinearVelocityFromWorldPoint.lua
  16. 8 8
      api/lovr/physics/Collider/getLocalPoint.lua
  17. 5 5
      api/lovr/physics/Collider/getLocalVector.lua
  18. 3 5
      api/lovr/physics/Collider/getMass.lua
  19. 7 0
      api/lovr/physics/Collider/getOrientation.lua
  20. 8 1
      api/lovr/physics/Collider/getPose.lua
  21. 7 0
      api/lovr/physics/Collider/getPosition.lua
  22. 39 0
      api/lovr/physics/Collider/getRawOrientation.lua
  23. 35 0
      api/lovr/physics/Collider/getRawPosition.lua
  24. 11 5
      api/lovr/physics/Collider/getRestitution.lua
  25. 13 8
      api/lovr/physics/Collider/getTag.lua
  26. 10 8
      api/lovr/physics/Collider/getWorldPoint.lua
  27. 5 7
      api/lovr/physics/Collider/getWorldVector.lua
  28. 27 0
      api/lovr/physics/Collider/resetMassData.lua
  29. 11 13
      api/lovr/physics/Collider/setAngularDamping.lua
  30. 18 2
      api/lovr/physics/Collider/setAngularVelocity.lua
  31. 41 0
      api/lovr/physics/Collider/setAutomaticMass.lua
  32. 56 0
      api/lovr/physics/Collider/setCenterOfMass.lua
  33. 39 0
      api/lovr/physics/Collider/setEnabledAxes.lua
  34. 14 5
      api/lovr/physics/Collider/setFriction.lua
  35. 85 0
      api/lovr/physics/Collider/setInertia.lua
  36. 10 14
      api/lovr/physics/Collider/setLinearDamping.lua
  37. 23 11
      api/lovr/physics/Collider/setLinearVelocity.lua
  38. 36 4
      api/lovr/physics/Collider/setMass.lua
  39. 14 6
      api/lovr/physics/Collider/setRestitution.lua
  40. 11 6
      api/lovr/physics/Collider/setTag.lua

+ 51 - 0
api/lovr/physics/Collider/applyAngularImpulse.lua

@@ -0,0 +1,51 @@
+return {
+  summary = 'Apply an angular impulse to the Collider.',
+  description = [[
+    Applies an angular impulse to the Collider.
+
+    An impulse is a single instantaneous push.  Impulses are independent of time, and are meant to
+    only be applied once.  Use `Collider:applyTorque` for a time-dependent push that happens over
+    multiple frames.
+  ]],
+  arguments = {
+    x = {
+      type = 'number',
+      description = 'The x component of the world-space impulse vector, in newton meter seconds.'
+    },
+    y = {
+      type = 'number',
+      description = 'The y component of the world-space impulse vector, in newton meter seconds.'
+    },
+    z = {
+      type = 'number',
+      description = 'The z component of the world-space impulse vector, in newton meter seconds.'
+    },
+    impulse = {
+      type = 'Vec3',
+      description = 'The world-space impulse vector, in newton meter seconds.'
+    }
+  },
+  returns = {},
+  variants = {
+    {
+      arguments = { 'x', 'y', 'z' },
+      returns = {}
+    },
+    {
+      arguments = { 'impulse' },
+      returns = {}
+    }
+  },
+  notes = [[
+    Kinematic colliders ignore forces.
+
+    If the Collider is asleep, this will wake it up.
+
+    Impulses are accumulated and processed during `World:update`.
+  ]],
+  related = {
+    'Collider:applyTorque',
+    'Collider:applyForce',
+    'Collider:applyLinearImpulse'
+  }
+}

+ 22 - 10
api/lovr/physics/Collider/applyForce.lua

@@ -4,58 +4,70 @@ return {
   arguments = {
   arguments = {
     x = {
     x = {
       type = 'number',
       type = 'number',
-      description = 'The x component of the force to apply.'
+      description = 'The x component of the world-space force vector, in newtons.'
     },
     },
     y = {
     y = {
       type = 'number',
       type = 'number',
-      description = 'The y component of the force to apply.'
+      description = 'The y component of the world-space force vector, in newtons.'
     },
     },
     z = {
     z = {
       type = 'number',
       type = 'number',
-      description = 'The z component of the force to apply.'
+      description = 'The z component of the world-space force vector, in newtons.'
     },
     },
     px = {
     px = {
       type = 'number',
       type = 'number',
-      description = 'The x position to apply the force at, in world coordinates.'
+      description = 'The x position to apply the force at, in world space.'
     },
     },
     py = {
     py = {
       type = 'number',
       type = 'number',
-      description = 'The y position to apply the force at, in world coordinates.'
+      description = 'The y position to apply the force at, in world space.'
     },
     },
     pz = {
     pz = {
       type = 'number',
       type = 'number',
-      description = 'The z position to apply the force at, in world coordinates.'
+      description = 'The z position to apply the force at, in world space.'
     },
     },
     force = {
     force = {
       type = 'Vec3',
       type = 'Vec3',
-      description = 'The force vector to apply.'
+      description = 'The world-space force vector, in newtons.'
     },
     },
     position = {
     position = {
       type = 'Vec3',
       type = 'Vec3',
-      description = 'The position to apply the force at, in world coordinates.'
+      description = 'The position to apply the force at, in world space.'
     }
     }
   },
   },
   returns = {},
   returns = {},
   variants = {
   variants = {
     {
     {
+      description = 'Apply a force at the center of mass.',
       arguments = { 'x', 'y', 'z' },
       arguments = { 'x', 'y', 'z' },
       returns = {}
       returns = {}
     },
     },
     {
     {
+      description = 'Apply a force at a custom position.',
       arguments = { 'x', 'y', 'z', 'px', 'py', 'pz' },
       arguments = { 'x', 'y', 'z', 'px', 'py', 'pz' },
       returns = {}
       returns = {}
     },
     },
     {
     {
+      description = 'Apply a force at the center of mass, using vector types.',
       arguments = { 'force' },
       arguments = { 'force' },
       returns = {}
       returns = {}
     },
     },
     {
     {
+      description = 'Apply a force at a custom position, using vector types.',
       arguments = { 'force', 'position' },
       arguments = { 'force', 'position' },
       returns = {}
       returns = {}
     }
     }
   },
   },
-  notes = 'If the Collider is asleep, calling this function will wake it up.',
+  notes = [[
+    Kinematic colliders ignore forces.
+
+    If the Collider is asleep, this will wake it up.
+
+    Forces are accumulated and processed during `World:update`.
+  ]],
   related = {
   related = {
-    'Collider:applyTorque'
+    'Collider:applyLinearImpulse',
+    'Collider:applyTorque',
+    'Collider:applyAngularImpulse'
   }
   }
 }
 }

+ 79 - 0
api/lovr/physics/Collider/applyLinearImpulse.lua

@@ -0,0 +1,79 @@
+return {
+  summary = 'Apply a linear impulse to the Collider.',
+  description = [[
+    Applies a linear impulse to the Collider.
+
+    An impulse is a single instantaneous push.  Impulses are independent of time, and are meant to
+    only be applied once.  Use `Collider:applyForce` for a time-dependent push that happens over
+    multiple frames.
+  ]],
+  arguments = {
+    x = {
+      type = 'number',
+      description = 'The x component of the world-space impulse vector, in newton seconds.'
+    },
+    y = {
+      type = 'number',
+      description = 'The y component of the world-space impulse vector, in newton seconds.'
+    },
+    z = {
+      type = 'number',
+      description = 'The z component of the world-space impulse vector, in newton seconds.'
+    },
+    px = {
+      type = 'number',
+      description = 'The x position to apply the impulse at, in world space.'
+    },
+    py = {
+      type = 'number',
+      description = 'The y position to apply the impulse at, in world space.'
+    },
+    pz = {
+      type = 'number',
+      description = 'The z position to apply the impulse at, in world space.'
+    },
+    impulse = {
+      type = 'Vec3',
+      description = 'The world-space impulse vector, in newton seconds.'
+    },
+    position = {
+      type = 'Vec3',
+      description = 'The position to apply the impulse at, in world space.'
+    }
+  },
+  returns = {},
+  variants = {
+    {
+      description = 'Apply an impulse at the center of mass.',
+      arguments = { 'x', 'y', 'z' },
+      returns = {}
+    },
+    {
+      description = 'Apply an impulse at a custom position.',
+      arguments = { 'x', 'y', 'z', 'px', 'py', 'pz' },
+      returns = {}
+    },
+    {
+      description = 'Apply an impulse at the center of mass, using vector types.',
+      arguments = { 'impulse' },
+      returns = {}
+    },
+    {
+      description = 'Apply an impulse at a custom position, using vector types.',
+      arguments = { 'impulse', 'position' },
+      returns = {}
+    }
+  },
+  notes = [[
+    Kinematic colliders ignore forces.
+
+    If the Collider is asleep, this will wake it up.
+
+    Impulses are accumulated and processed during `World:update`.
+  ]],
+  related = {
+    'Collider:applyForce',
+    'Collider:applyTorque',
+    'Collider:applyAngularImpulse'
+  }
+}

+ 14 - 6
api/lovr/physics/Collider/applyTorque.lua

@@ -4,19 +4,19 @@ return {
   arguments = {
   arguments = {
     x = {
     x = {
       type = 'number',
       type = 'number',
-      description = 'The x component of the torque.'
+      description = 'The x component of the world-space torque vector, in newton meters.'
     },
     },
     y = {
     y = {
       type = 'number',
       type = 'number',
-      description = 'The y component of the torque.'
+      description = 'The y component of the world-space torque vector, in newton meters.'
     },
     },
     z = {
     z = {
       type = 'number',
       type = 'number',
-      description = 'The z component of the torque.'
+      description = 'The z component of the world-space torque vector, in newton meters.'
     },
     },
     torque = {
     torque = {
       type = 'Vec3',
       type = 'Vec3',
-      description = 'The torque to apply.'
+      description = 'The world-space torque vector, in newton meters.'
     }
     }
   },
   },
   returns = {},
   returns = {},
@@ -30,8 +30,16 @@ return {
       returns = {}
       returns = {}
     }
     }
   },
   },
-  notes = 'If the Collider is asleep, calling this function will wake it up.',
+  notes = [[
+    Kinematic colliders ignore forces.
+
+    If the Collider is asleep, this will wake it up.
+
+    Forces are accumulated and processed during `World:update`.
+  ]],
   related = {
   related = {
-    'Collider:applyForce'
+    'Collider:applyAngularImpulse',
+    'Collider:applyForce',
+    'Collider:applyLinearImpulse'
   }
   }
 }
 }

+ 6 - 2
api/lovr/physics/Collider/getAABB.lua

@@ -1,6 +1,9 @@
 return {
 return {
   summary = 'Get the Collider\'s axis aligned bounding box.',
   summary = 'Get the Collider\'s axis aligned bounding box.',
-  description = 'Returns the bounding box for the Collider, computed from attached shapes.',
+  description = [[
+    Returns the world-space axis-aligned bounding box of the Collider, computed from attached
+    shapes.
+  ]],
   arguments = {},
   arguments = {},
   returns = {
   returns = {
     minx = {
     minx = {
@@ -35,6 +38,7 @@ return {
     }
     }
   },
   },
   related = {
   related = {
-    'Shape:getAABB'
+    'Shape:getAABB',
+    'World:queryBox'
   }
   }
 }
 }

+ 10 - 11
api/lovr/physics/Collider/getAngularDamping.lua

@@ -1,32 +1,31 @@
 return {
 return {
   summary = 'Get the angular damping of the Collider.',
   summary = 'Get the angular damping of the Collider.',
   description = [[
   description = [[
-    Returns the angular damping parameters of the Collider.  Angular damping makes things less
-    "spinny", making them slow down their angular velocity over time.
+    Returns the angular damping of the Collider.  Angular damping is similar to drag or air
+    resistance, reducing the Collider's angular velocity over time.
   ]],
   ]],
   arguments = {},
   arguments = {},
   returns = {
   returns = {
     damping = {
     damping = {
       type = 'number',
       type = 'number',
       description = 'The angular damping.'
       description = 'The angular damping.'
-    },
-    threshold = {
-      type = 'number',
-      description = 'Velocity limit below which the damping is not applied.'
     }
     }
   },
   },
   variants = {
   variants = {
     {
     {
       arguments = {},
       arguments = {},
-      returns = { 'damping', 'threshold' }
+      returns = { 'damping' }
     }
     }
   },
   },
   notes = [[
   notes = [[
-    When the Collider is created, it will use the world's angular damping value, which is set using
-    `World:setAngularDamping`.
+    The default damping is .05, meaning the collider will lose approximately 5% of its angular
+    velocity each second.  A damping value of zero means the Collider will not lose velocity over
+    time.
   ]],
   ]],
   related = {
   related = {
-    'World:getAngularDamping',
-    'World:setAngularDamping'
+    'Collider:getLinearDamping',
+    'Collider:setLinearDamping',
+    'Collider:getInertia',
+    'Collider:setInertia'
   }
   }
 }
 }

+ 41 - 0
api/lovr/physics/Collider/getAutomaticMass.lua

@@ -0,0 +1,41 @@
+return {
+  summary = 'Get whether automatic mass is enabled.',
+  description = [[
+    Returns whether automatic mass is enabled for the Collider.
+
+    When enabled, the Collider's mass, inertia, and center of mass will be recomputed when:
+
+    - A shape is added to or removed from the Collider.
+    - A shape attached to the Collider changes shape (e.g. `SphereShape:setRadius`).
+    - A shape attached to the Collider is moved using `Shape:setOffset`.
+    - A shape attached to the Collider changes its density using `Shape:setDensity`.
+
+    Additionally, changing the center of mass of a Collider will automatically update its inertia
+    when automatic mass is enabled.
+
+    Disable this to manage the mass properties manually.  When automatic mass is disabled,
+    `Collider:resetMassData` can still be used to reset the mass from attached shapes if needed.
+  ]],
+  arguments = {},
+  returns = {
+    enabled = {
+      type = 'boolean',
+      description = 'Whether automatic mass is enabled.'
+    }
+  },
+  variants = {
+    {
+      arguments = {},
+      returns = { 'enabled' }
+    }
+  },
+  related = {
+    'Collider:resetMassData',
+    'Collider:getMass',
+    'Collider:setMass',
+    'Collider:getInertia',
+    'Collider:setInertia',
+    'Collider:getCenterOfMass',
+    'Collider:setCenterOfMass'
+  }
+}

+ 46 - 0
api/lovr/physics/Collider/getCenterOfMass.lua

@@ -0,0 +1,46 @@
+return {
+  summary = 'Get the Collider\'s local center of mass.',
+  description = [[
+    Returns the Collider's center of mass, in the Collider's local coordinate space.
+  ]],
+  arguments = {},
+  returns = {
+    x = {
+      type = 'number',
+      description = 'The x component of the center of mass.'
+    },
+    y = {
+      type = 'number',
+      description = 'The y component of the center of mass.'
+    },
+    z = {
+      type = 'number',
+      description = 'The z component of the center of mass.'
+    }
+  },
+  variants = {
+    {
+      arguments = {},
+      returns = { 'x', 'y', 'z' }
+    }
+  },
+  notes = [[
+    By default, the center of mass of the Collider is kept up to date automatically as the
+    Collider's shapes change.  To disable this, use `Collider:setAutomaticMass`.
+
+    Use `Collider:resetMassData` to reset the center of mass and other mass properties based on the
+    Collider's shapes.
+  ]],
+  related = {
+    'Shape:getCenterOfMass',
+    'Collider:getMass',
+    'Collider:setMass',
+    'Collider:getInertia',
+    'Collider:setInertia',
+    'Collider:getAutomaticMass',
+    'Collider:setAutomaticMass',
+    'Collider:resetMassData',
+    'Shape:getOffset',
+    'Shape:setOffset'
+  }
+}

+ 35 - 0
api/lovr/physics/Collider/getEnabledAxes.lua

@@ -0,0 +1,35 @@
+return {
+  summary = 'Get the enabled translation/rotation axes.',
+  description = 'Get the axes that are enabled for translation and rotation.',
+  arguments = {},
+  returns = {
+    translation = {
+      type = 'string',
+      description = [[
+        A string containing the world-space axes the Collider is allowed to move on.  The string
+        will have 'x', 'y', and 'z' letters representing which axes are enabled.  If no axes are
+        enabled then it will be an empty string.
+      ]]
+    },
+    rotation = {
+      type = 'string',
+      description = [[
+        A string containing the world-space axes the Collider is allowed to rotate around.  The
+        string will have 'x', 'y', and 'z' letters representing which axes are enabled.  If no axes
+        are enabled then it will be an empty string.
+      ]]
+    }
+  },
+  variants = {
+    {
+      arguments = {},
+      returns = { 'translation', 'rotation' }
+    }
+  },
+  notes = [[
+    The default state is `xyz` for both translation and rotation.
+
+    The physics engine does not support disabling all axes.  At least one translation or rotation
+    axis needs to be enabled.  To disable all movement for a collider, make it kinematic.
+  ]]
+}

+ 13 - 4
api/lovr/physics/Collider/getFriction.lua

@@ -1,8 +1,9 @@
 return {
 return {
   summary = 'Get the friction of the Collider.',
   summary = 'Get the friction of the Collider.',
   description = [[
   description = [[
-    Returns the friction of the Collider.  By default, the friction of two Colliders is combined
-    (multiplied) when they collide to generate a friction force.  The initial friction is 0.
+    Returns the friction of the Collider.  Friction determines how easy it is for two colliders to
+    slide against each other.  Low friction makes it easier for a collider to slide, simulating a
+    smooth surface.
   ]],
   ]],
   arguments = {},
   arguments = {},
   returns = {
   returns = {
@@ -17,9 +18,17 @@ return {
       returns = { 'friction' }
       returns = { 'friction' }
     }
     }
   },
   },
+  notes = [[
+    The default friction is .2.
+
+    When two colliders collide, their friction is combined using the geometric mean:
+
+        friction = (frictionA * frictionB) ^ .5
+  ]],
   related = {
   related = {
+    'Contact:getFriction',
+    'Contact:setFriction',
     'Collider:getRestitution',
     'Collider:getRestitution',
-    'Collider:setRestitution',
-    'World:collide'
+    'Collider:setRestitution'
   }
   }
 }
 }

+ 74 - 0
api/lovr/physics/Collider/getInertia.lua

@@ -0,0 +1,74 @@
+return {
+  summary = 'Get the inertia of the Collider.',
+  description = [[
+    Returns the inertia of the Collider.
+
+    Inertia is kind of like "angular mass".  Regular mass determines how resistant the Collider is
+    to linear forces (movement), whereas inertia determines how resistant the Collider is to torque
+    (rotation).  Colliders with less inertia are more spinny.
+
+    In 3D, inertia is represented by a 3x3 matrix, called a tensor.  To make calculations easier,
+    the physics engine stores the inertia using eigenvalue decomposition, splitting the matrix into
+    a diagonal matrix and a rotation.  It's complicated!
+
+    In a realistic simulation, mass and inertia follow a linear relationship.  If the mass of an
+    object increases, the diagonal part of its inertia should increase proportionally.
+  ]],
+  arguments = {},
+  returns = {
+    dx = {
+      type = 'number',
+      description = 'The x component of the diagonal matrix.'
+    },
+    dy = {
+      type = 'number',
+      description = 'The y component of the diagonal matrix.'
+    },
+    dz = {
+      type = 'number',
+      description = 'The z component of the diagonal matrix.'
+    },
+    qx = {
+      type = 'number',
+      description = 'The x component of the inertia rotation quaternion.'
+    },
+    qy = {
+      type = 'number',
+      description = 'The y component of the inertia rotation quaternion.'
+    },
+    qz = {
+      type = 'number',
+      description = 'The z component of the inertia rotation quaternion.'
+    },
+    qw = {
+      type = 'number',
+      description = 'The w component of the inertia rotation quaternion.'
+    }
+  },
+  variants = {
+    {
+      arguments = {},
+      returns = { 'dx', 'dy', 'dz', 'qx', 'qy', 'qz', 'qw' }
+    }
+  },
+  notes = [[
+    By default, the inertia of the Collider is kept up to date automatically as the Collider's
+    shapes change.  To disable this, use `Collider:setAutomaticMass`.
+
+    Use `Collider:resetMassData` to reset the inertia and other mass properties based on the
+    Collider's shapes.
+
+    If the Collider is kinematic or all rotation axes are disabled, this returns 0 for the diagonal
+    and an identity quaternion for the rotation.
+  ]],
+  related = {
+    'Collider:getMass',
+    'Collider:setMass',
+    'Collider:getCenterOfMass',
+    'Collider:setCenterOfMass',
+    'Collider:getAutomaticMass',
+    'Collider:setAutomaticMass',
+    'Collider:resetMassData',
+    'Shape:getInertia'
+  }
+}

+ 8 - 12
api/lovr/physics/Collider/getLinearDamping.lua

@@ -1,7 +1,7 @@
 return {
 return {
   summary = 'Get the linear damping of the Collider.',
   summary = 'Get the linear damping of the Collider.',
   description = [[
   description = [[
-    Returns the Collider's linear damping parameters.  Linear damping is similar to drag or air
+    Returns the linear damping of the Collider.  Linear damping is similar to drag or air
     resistance, slowing the Collider down over time.
     resistance, slowing the Collider down over time.
   ]],
   ]],
   arguments = {},
   arguments = {},
@@ -9,26 +9,22 @@ return {
     damping = {
     damping = {
       type = 'number',
       type = 'number',
       description = 'The linear damping.'
       description = 'The linear damping.'
-    },
-    threshold = {
-      type = 'number',
-      description = 'Velocity limit below which the damping is not applied.'
     }
     }
   },
   },
   variants = {
   variants = {
     {
     {
       arguments = {},
       arguments = {},
-      returns = { 'damping', 'threshold' }
+      returns = { 'damping' }
     }
     }
   },
   },
   notes = [[
   notes = [[
-    When the Collider is created, it will use the world's linear damping value, which is set using
-    `World:setLinearDamping`.
-
-    A linear damping of 0 means the Collider won't slow down over time.
+    The default damping is .05, meaning the collider will lose approximately 5% of its velocity each
+    second.  A damping value of zero means the Collider will not lose velocity over time.
   ]],
   ]],
   related = {
   related = {
-    'World:getLinearDamping',
-    'World:setLinearDamping'
+    'Collider:getAngularDamping',
+    'Collider:setAngularDamping',
+    'Collider:getGravityScale',
+    'Collider:setGravityScale'
   }
   }
 }
 }

+ 6 - 6
api/lovr/physics/Collider/getLinearVelocity.lua

@@ -1,22 +1,22 @@
 return {
 return {
   summary = 'Get the linear velocity of the Collider.',
   summary = 'Get the linear velocity of the Collider.',
   description = [[
   description = [[
-    Returns the linear velocity of the Collider.  This is how fast the Collider is moving.  There is
-    also angular velocity, which is how fast the Collider is spinning.
+    Returns the world-space linear velocity of the center of mass of the Collider, in meters per
+    second.
   ]],
   ]],
   arguments = {},
   arguments = {},
   returns = {
   returns = {
     vx = {
     vx = {
       type = 'number',
       type = 'number',
-      description = 'The x velocity of the Collider, in meters per second.'
+      description = 'The x component of the velocity.'
     },
     },
     vy = {
     vy = {
       type = 'number',
       type = 'number',
-      description = 'The y velocity of the Collider, in meters per second.'
+      description = 'The y component of the velocity.'
     },
     },
     vz = {
     vz = {
       type = 'number',
       type = 'number',
-      description = 'The z velocity of the Collider, in meters per second.'
+      description = 'The z component of the velocity.'
     }
     }
   },
   },
   variants = {
   variants = {
@@ -26,11 +26,11 @@ return {
     }
     }
   },
   },
   related = {
   related = {
+    'Collider:applyForce',
     'Collider:getLinearVelocityFromLocalPoint',
     'Collider:getLinearVelocityFromLocalPoint',
     'Collider:getLinearVelocityFromWorldPoint',
     'Collider:getLinearVelocityFromWorldPoint',
     'Collider:getAngularVelocity',
     'Collider:getAngularVelocity',
     'Collider:setAngularVelocity',
     'Collider:setAngularVelocity',
-    'Collider:applyForce',
     'Collider:getPosition',
     'Collider:getPosition',
     'Collider:setPosition'
     'Collider:setPosition'
   }
   }

+ 12 - 9
api/lovr/physics/Collider/getLinearVelocityFromLocalPoint.lua

@@ -1,36 +1,39 @@
 return {
 return {
-  summary = 'Get the linear velocity of the Collider at a point.',
-  description = 'Returns the linear velocity of a point relative to the Collider.',
+  summary = 'Get the linear velocity of a point on the Collider.',
+  description = [[
+    Returns the linear velocity of a point on the Collider.  This includes the velocity of the
+    center of mass plus the angular velocity at that point.
+  ]],
   arguments = {
   arguments = {
     x = {
     x = {
       type = 'number',
       type = 'number',
-      description = 'The x coordinate.'
+      description = 'The x position in local space.'
     },
     },
     y = {
     y = {
       type = 'number',
       type = 'number',
-      description = 'The y coordinate.'
+      description = 'The y position in local space.'
     },
     },
     z = {
     z = {
       type = 'number',
       type = 'number',
-      description = 'The z coordinate.'
+      description = 'The z position in local space.'
     },
     },
     point = {
     point = {
       type = 'number',
       type = 'number',
-      description = 'The point.'
+      description = 'The local-space point.'
     }
     }
   },
   },
   returns = {
   returns = {
     vx = {
     vx = {
       type = 'number',
       type = 'number',
-      description = 'The x component of the velocity of the point.'
+      description = 'The x velocity of the point.'
     },
     },
     vy = {
     vy = {
       type = 'number',
       type = 'number',
-      description = 'The y component of the velocity of the point.'
+      description = 'The y velocity of the point.'
     },
     },
     vz = {
     vz = {
       type = 'number',
       type = 'number',
-      description = 'The z component of the velocity of the point.'
+      description = 'The z velocity of the point.'
     }
     }
   },
   },
   variants = {
   variants = {

+ 9 - 8
api/lovr/physics/Collider/getLinearVelocityFromWorldPoint.lua

@@ -1,38 +1,39 @@
 return {
 return {
   summary = 'Get the linear velocity of the Collider at a world space point.',
   summary = 'Get the linear velocity of the Collider at a world space point.',
   description = [[
   description = [[
-    Returns the linear velocity of a point on the Collider specified in world space.
+    Returns the linear velocity of a point on the Collider.  This includes the velocity of the
+    center of mass plus the angular velocity at that point.
   ]],
   ]],
   arguments = {
   arguments = {
     x = {
     x = {
       type = 'number',
       type = 'number',
-      description = 'The x coordinate in world space.'
+      description = 'The x position in world space.'
     },
     },
     y = {
     y = {
       type = 'number',
       type = 'number',
-      description = 'The y coordinate in world space.'
+      description = 'The y position in world space.'
     },
     },
     z = {
     z = {
       type = 'number',
       type = 'number',
-      description = 'The z coordinate in world space.'
+      description = 'The z position in world space.'
     },
     },
     point = {
     point = {
       type = 'Vec3',
       type = 'Vec3',
-      descriptio = 'The point.'
+      descriptio = 'The world-space point.'
     }
     }
   },
   },
   returns = {
   returns = {
     vx = {
     vx = {
       type = 'number',
       type = 'number',
-      description = 'The x component of the velocity of the point.'
+      description = 'The x velocity of the point.'
     },
     },
     vy = {
     vy = {
       type = 'number',
       type = 'number',
-      description = 'The y component of the velocity of the point.'
+      description = 'The y velocity of the point.'
     },
     },
     vz = {
     vz = {
       type = 'number',
       type = 'number',
-      description = 'The z component of the velocity of the point.'
+      description = 'The z velocity of the point.'
     }
     }
   },
   },
   variants = {
   variants = {

+ 8 - 8
api/lovr/physics/Collider/getLocalPoint.lua

@@ -1,20 +1,20 @@
 return {
 return {
-  summary = 'Convert a point from world space to collider space.',
+  summary = 'Transform a point from world space to collider space.',
   description = [[
   description = [[
-    Converts a point from world coordinates into local coordinates relative to the Collider.
+    Transforms a point from world coordinates into local coordinates relative to the Collider.
   ]],
   ]],
   arguments = {
   arguments = {
     wx = {
     wx = {
       type = 'number',
       type = 'number',
-      description = 'The x coordinate of the world point.'
+      description = 'The x component of the world point.'
     },
     },
     wy = {
     wy = {
       type = 'number',
       type = 'number',
-      description = 'The y coordinate of the world point.'
+      description = 'The y component of the world point.'
     },
     },
     wz = {
     wz = {
       type = 'number',
       type = 'number',
-      description = 'The z coordinate of the world point.'
+      description = 'The z component of the world point.'
     },
     },
     point = {
     point = {
       type = 'Vec3',
       type = 'Vec3',
@@ -24,15 +24,15 @@ return {
   returns = {
   returns = {
     x = {
     x = {
       type = 'number',
       type = 'number',
-      description = 'The x position of the local-space point.'
+      description = 'The x component of the local point.'
     },
     },
     y = {
     y = {
       type = 'number',
       type = 'number',
-      description = 'The y position of the local-space point.'
+      description = 'The y component of the local point.'
     },
     },
     z = {
     z = {
       type = 'number',
       type = 'number',
-      description = 'The z position of the local-space point.'
+      description = 'The z component of the local point.'
     }
     }
   },
   },
   variants = {
   variants = {

+ 5 - 5
api/lovr/physics/Collider/getLocalVector.lua

@@ -1,6 +1,6 @@
 return {
 return {
-  summary = 'Convert a vector from world space to local space.',
-  description = ' Converts a direction vector from world space to local space.',
+  summary = 'Transform a vector from world space to local space.',
+  description = 'Transforms a direction vector from world space to local space.',
   arguments = {
   arguments = {
     wx = {
     wx = {
       type = 'number',
       type = 'number',
@@ -22,15 +22,15 @@ return {
   returns = {
   returns = {
     x = {
     x = {
       type = 'number',
       type = 'number',
-      description = 'The x coordinate of the local vector.'
+      description = 'The x component of the local vector.'
     },
     },
     y = {
     y = {
       type = 'number',
       type = 'number',
-      description = 'The y coordinate of the local vector.'
+      description = 'The y component of the local vector.'
     },
     },
     z = {
     z = {
       type = 'number',
       type = 'number',
-      description = 'The z coordinate of the local vector.'
+      description = 'The z component of the local vector.'
     }
     }
   },
   },
   variants = {
   variants = {

+ 3 - 5
api/lovr/physics/Collider/getMass.lua

@@ -29,15 +29,13 @@ return {
   },
   },
   notes = [[
   notes = [[
     By default, the mass of the Collider will be kept up to date automatically as shapes are added
     By default, the mass of the Collider will be kept up to date automatically as shapes are added
-    and removed from the Collider (or when the shapes change size or density).  This can be disabled
-    using `Collider:setAutomaticMass`.
+    and removed from the Collider (or if the shapes change size or density).  Use
+    `Collider:setAutomaticMass` to customize this.
 
 
     Mass can be overridden with `Collider:setMass`, or recomputed from the attached shapes with
     Mass can be overridden with `Collider:setMass`, or recomputed from the attached shapes with
     `Collider:resetMassData`.
     `Collider:resetMassData`.
 
 
-    If the Collider is kinematic, this returns 0.
-
-    If all translation axes have been disabled with `Collider:setEnabledAxes`, this returns 0.
+    If the Collider is kinematic or all translation axes are disabled, this returns 0.
   ]],
   ]],
   related = {
   related = {
     'Collider:getInertia',
     'Collider:getInertia',

+ 7 - 0
api/lovr/physics/Collider/getOrientation.lua

@@ -26,8 +26,15 @@ return {
       returns = { 'angle', 'ax', 'ay', 'az' }
       returns = { 'angle', 'ax', 'ay', 'az' }
     }
     }
   },
   },
+  notes = [[
+    When the World is using a fixed timestep, this returns an interpolated orientation between the
+    last two physics updates.  Use `Collider:getRawOrientation` to get the raw orientation without
+    any smoothing applied.  Alternatively, set the `tickRate` to 0 when creating the world to
+    disable fixed timestep and all collider interpolation.
+  ]],
   related = {
   related = {
     'Collider:applyTorque',
     'Collider:applyTorque',
+    'Collider:getRawOrientation',
     'Collider:getAngularVelocity',
     'Collider:getAngularVelocity',
     'Collider:setAngularVelocity',
     'Collider:setAngularVelocity',
     'Collider:getPosition',
     'Collider:getPosition',

+ 8 - 1
api/lovr/physics/Collider/getPose.lua

@@ -38,8 +38,15 @@ return {
       returns = { 'x', 'y', 'z', 'angle', 'ax', 'ay', 'az' }
       returns = { 'x', 'y', 'z', 'angle', 'ax', 'ay', 'az' }
     }
     }
   },
   },
+  notes = [[
+    When the World is using a fixed timestep, this returns an interpolated pose between the last
+    two physics updates.  Use `Collider:getRawPose` to get the raw pose without any smoothing
+    applied.  Alternatively, set the `tickRate` to 0 when creating the world to disable fixed
+    timestep and all collider interpolation.
+  ]],
   related = {
   related = {
     'Collider:getPosition',
     'Collider:getPosition',
-    'Collider:getOrientation'
+    'Collider:getOrientation',
+    'Collider:getRawPose'
   }
   }
 }
 }

+ 7 - 0
api/lovr/physics/Collider/getPosition.lua

@@ -22,8 +22,15 @@ return {
       returns = { 'x', 'y', 'z' }
       returns = { 'x', 'y', 'z' }
     }
     }
   },
   },
+  notes = [[
+    When the World is using a fixed timestep, this returns an interpolated position between the last
+    two physics updates.  Use `Collider:getRawPosition` to get the raw position without any
+    smoothing applied.  Alternatively, set the `tickRate` to 0 when creating the world to disable
+    fixed timestep and all collider interpolation.
+  ]],
   related = {
   related = {
     'Collider:applyForce',
     'Collider:applyForce',
+    'Collider:getRawPosition',
     'Collider:getLinearVelocity',
     'Collider:getLinearVelocity',
     'Collider:setLinearVelocity',
     'Collider:setLinearVelocity',
     'Collider:getOrientation',
     'Collider:getOrientation',

+ 39 - 0
api/lovr/physics/Collider/getRawOrientation.lua

@@ -0,0 +1,39 @@
+return {
+  summary = 'Get the raw orientation of the Collider, without any interpolation.',
+  description = 'Returns the raw orientation of the Collider, without any interpolation applied.',
+  arguments = {},
+  returns = {
+    angle = {
+      type = 'number',
+      description = 'The number of radians the Collider is rotated around its axis of rotation.'
+    },
+    ax = {
+      type = 'number',
+      description = 'The x component of the axis of rotation.'
+    },
+    ay = {
+      type = 'number',
+      description = 'The y component of the axis of rotation.'
+    },
+    az = {
+      type = 'number',
+      description = 'The z component of the axis of rotation.'
+    }
+  },
+  variants = {
+    {
+      arguments = {},
+      returns = { 'angle', 'ax', 'ay', 'az' }
+    }
+  },
+  notes = [[
+    To disable all interpolation, disable fixed timestep by setting the `tickRate` to 0 when
+    creating the world.
+  ]],
+  related = {
+    'Collider:getOrientation',
+    'Collider:setOrientation',
+    'Collider:getRawPosition',
+    'Collider:getPosition'
+  }
+}

+ 35 - 0
api/lovr/physics/Collider/getRawPosition.lua

@@ -0,0 +1,35 @@
+return {
+  summary = 'Get the raw position of the Collider, without any interpolation.',
+  description = 'Returns the raw position of the Collider, without any interpolation applied.',
+  arguments = {},
+  returns = {
+    x = {
+      type = 'number',
+      description = 'The x position of the Collider, in meters.'
+    },
+    y = {
+      type = 'number',
+      description = 'The y position of the Collider, in meters.'
+    },
+    z = {
+      type = 'number',
+      description = 'The z position of the Collider, in meters.'
+    }
+  },
+  variants = {
+    {
+      arguments = {},
+      returns = { 'x', 'y', 'z' }
+    }
+  },
+  notes = [[
+    To disable all interpolation, disable fixed timestep by setting the `tickRate` to 0 when
+    creating the world.
+  ]],
+  related = {
+    'Collider:getPosition',
+    'Collider:setPosition',
+    'Collider:getRawOrientation',
+    'Collider:getOrientation'
+  }
+}

+ 11 - 5
api/lovr/physics/Collider/getRestitution.lua

@@ -1,9 +1,9 @@
 return {
 return {
   summary = 'Get the bounciness of the Collider.',
   summary = 'Get the bounciness of the Collider.',
   description = [[
   description = [[
-    Returns the restitution (bounciness) of the Collider.  By default, the restitution of two
-    Colliders is combined (the max is used) when they collide to cause them to bounce away from each
-    other.  The initial restitution is 0.
+    Returns the restitution of the Collider.  Restitution makes a Collider bounce when it collides
+    with other objects.  A restitution value of zero would result in an inelastic collision
+    response, whereas 1.0 would result in an elastic collision that preserves all of the velocity.
   ]],
   ]],
   arguments = {},
   arguments = {},
   returns = {
   returns = {
@@ -18,9 +18,15 @@ return {
       returns = { 'restitution' }
       returns = { 'restitution' }
     }
     }
   },
   },
+  notes = [[
+    To improve stability of the simulation and allow colliders to come to rest, restitution is only
+    applied if the collider is moving above a certain speed.  This can be configured using the
+    `restitutionThreshold` option in `lovr.physics.newWorld`.
+  ]],
   related = {
   related = {
+    'Contact:getRestitution',
+    'Contact:setRestitution',
     'Collider:getFriction',
     'Collider:getFriction',
-    'Collider:setFriction',
-    'World:collide'
+    'Collider:setFriction'
   }
   }
 }
 }

+ 13 - 8
api/lovr/physics/Collider/getTag.lua

@@ -1,24 +1,29 @@
 return {
 return {
   summary = 'Get the Collider\'s tag.',
   summary = 'Get the Collider\'s tag.',
-  description = 'Returns the Collider\'s tag.',
+  description = [[
+    Returns the Collider's tag.
+
+    Tags are strings that represent the category of a collider.  Use `World:enableCollisionBetween`
+    and `World:disableCollisionBetween` to control which pairs of tags should collide with each
+    other.  Physics queries like `World:raycast` also use tags to filter their results.
+
+    The list of available tags is set in `lovr.physics.newWorld`.
+  ]],
   arguments = {},
   arguments = {},
   returns = {
   returns = {
     tag = {
     tag = {
       type = 'string',
       type = 'string',
-      description = 'The Collider\'s collision tag, or `nil` if the Collider doesn\'t have a tag.'
+      description = 'The Collider\'s tag.'
     }
     }
   },
   },
   variants = {
   variants = {
     {
     {
-      arguments = {},
-      returns = { 'tag' }
+      arguments = {}
+      returns = { 'tag' },
     }
     }
   },
   },
-  notes = [[
-    Collision between tags can be enabled and disabled using `World:enableCollisionBetween` and
-    `World:disableCollisionBetween`.
-  ]],
   related = {
   related = {
+    'World:getTags',
     'World:disableCollisionBetween',
     'World:disableCollisionBetween',
     'World:enableCollisionBetween',
     'World:enableCollisionBetween',
     'World:isCollisionEnabledBetween',
     'World:isCollisionEnabledBetween',

+ 10 - 8
api/lovr/physics/Collider/getWorldPoint.lua

@@ -1,18 +1,20 @@
 return {
 return {
-  summary = 'Convert a point from local space to world space.',
-  description = 'Convert a point relative to the collider to a point in world coordinates.',
+  summary = 'Transform a point from local space to world space.',
+  description = [[
+    Transforms a local point relative to the collider to a point in world coordinates.
+  ]],
   arguments = {
   arguments = {
     x = {
     x = {
       type = 'number',
       type = 'number',
-      description = 'The x position of the point.'
+      description = 'The x component of the local point.'
     },
     },
     y = {
     y = {
       type = 'number',
       type = 'number',
-      description = 'The y position of the point.'
+      description = 'The y component of the local point.'
     },
     },
     z = {
     z = {
       type = 'number',
       type = 'number',
-      description = 'The z position of the point.'
+      description = 'The z component of the local point.'
     },
     },
     point = {
     point = {
       type = 'Vec3',
       type = 'Vec3',
@@ -22,15 +24,15 @@ return {
   returns = {
   returns = {
     wx = {
     wx = {
       type = 'number',
       type = 'number',
-      description = 'The x coordinate of the world point.'
+      description = 'The x component of the world point.'
     },
     },
     wy = {
     wy = {
       type = 'number',
       type = 'number',
-      description = 'The y coordinate of the world point.'
+      description = 'The y component of the world point.'
     },
     },
     wz = {
     wz = {
       type = 'number',
       type = 'number',
-      description = 'The z coordinate of the world point.'
+      description = 'The z component of the world point.'
     }
     }
   },
   },
   variants = {
   variants = {

+ 5 - 7
api/lovr/physics/Collider/getWorldVector.lua

@@ -1,20 +1,18 @@
 return {
 return {
-  summary = 'Convert a vector from local space to world space.',
-  description = [[
-    Converts a direction vector from local space to world space.
-  ]],
+  summary = 'Transform a vector from local space to world space.',
+  description = 'Transforms a direction vector from local space to world space.',
   arguments = {
   arguments = {
     x = {
     x = {
       type = 'number',
       type = 'number',
-      description = 'The x coordinate of the local vector.'
+      description = 'The x component of the local vector.'
     },
     },
     y = {
     y = {
       type = 'number',
       type = 'number',
-      description = 'The y coordinate of the local vector.'
+      description = 'The y component of the local vector.'
     },
     },
     z = {
     z = {
       type = 'number',
       type = 'number',
-      description = 'The z coordinate of the local vector.'
+      description = 'The z component of the local vector.'
     },
     },
     vector = {
     vector = {
       type = 'Vec3',
       type = 'Vec3',

+ 27 - 0
api/lovr/physics/Collider/resetMassData.lua

@@ -0,0 +1,27 @@
+return {
+  summary = 'Reset mass properties.',
+  description = [[
+    Resets the mass, inertia, and center of mass of the Collider based on its attached shapes.
+
+    If automatic mass is enabled, these properties will be kept up to date automatically.  Use this
+    function when automatic mass is disabled or if mass needs to be reset after being overridden.
+  ]],
+  arguments = {},
+  returns = {},
+  variants = {
+    {
+      arguments = {},
+      returns = {}
+    }
+  },
+  related = {
+    'Collider:getAutomaticMass',
+    'Collider:setAutomaticMass',
+    'Collider:getMass',
+    'Collider:setMass',
+    'Collider:getInertia',
+    'Collider:setInertia',
+    'Collider:getCenterOfMass',
+    'Collider:setCenterOfMass'
+  }
+}

+ 11 - 13
api/lovr/physics/Collider/setAngularDamping.lua

@@ -1,34 +1,32 @@
 return {
 return {
   summary = 'Set the angular damping of the Collider.',
   summary = 'Set the angular damping of the Collider.',
   description = [[
   description = [[
-    Sets the angular damping of the Collider.  Angular damping makes things less "spinny", causing
-    them to slow down their angular velocity over time. Damping is only applied when angular
-    velocity is over the threshold value.
+    Sets the angular damping of the Collider.  Angular damping is similar to drag or air resistance,
+    reducing the Collider's angular velocity over time.
   ]],
   ]],
   arguments = {
   arguments = {
     damping = {
     damping = {
       type = 'number',
       type = 'number',
       description = 'The angular damping.'
       description = 'The angular damping.'
-    },
-    threshold = {
-      type = 'number',
-      default = '0',
-      description = 'Velocity limit below which the damping is not applied.'
     }
     }
   },
   },
   returns = {},
   returns = {},
   variants = {
   variants = {
     {
     {
-      arguments = { 'damping', 'threshold' },
+      arguments = { 'damping' },
       returns = {}
       returns = {}
     }
     }
   },
   },
   notes = [[
   notes = [[
-    When the Collider is created, it will use the world's angular damping value, which is set using
-    `World:setAngularDamping`.
+    The default damping is .05, meaning the collider will lose approximately 5% of its velocity each
+    second.  A damping value of zero means the Collider will not lose velocity over time.
+
+    Negative damping is not meaningful and will be clamped to zero.
   ]],
   ]],
   related = {
   related = {
-    'World:getAngularDamping',
-    'World:setAngularDamping'
+    'Collider:getLinearDamping',
+    'Collider:setLinearDamping',
+    'Collider:getInertia',
+    'Collider:setInertia'
   }
   }
 }
 }

+ 18 - 2
api/lovr/physics/Collider/setAngularVelocity.lua

@@ -32,11 +32,27 @@ return {
       returns = {}
       returns = {}
     }
     }
   },
   },
-  notes = 'If the Collider is asleep, calling this function will wake it up.',
+  notes = [[
+    Although setting the velocity directly is useful sometimes, it can cause problems:
+
+    - Velocity ignores mass, so it can lead to unnaturally sharp changes in motion.
+    - If the velocity of a Collider is changed multiple times during a frame, only the last one is
+      going to have an effect, nullifying the other velocities that were set.
+    - Setting the velocity of a Collider every frame can mess up collisions, since the forces used
+      to resolve a collision will get ignored by changing the velocity.
+
+    Using forces and impulses to move Colliders will avoid all of these issues.
+
+    If the Collider is asleep, setting the angular velocity to a non-zero value will wake it up.
+
+    If the Collider has a tag that was marked as static when the World was created, then the
+    Collider can not move and this function will do nothing.
+  ]],
   related = {
   related = {
+    'Collider:applyTorque',
+    'Collider:applyAngularImpulse',
     'Collider:getLinearVelocity',
     'Collider:getLinearVelocity',
     'Collider:setLinearVelocity',
     'Collider:setLinearVelocity',
-    'Collider:applyTorque',
     'Collider:getOrientation',
     'Collider:getOrientation',
     'Collider:setOrientation'
     'Collider:setOrientation'
   }
   }

+ 41 - 0
api/lovr/physics/Collider/setAutomaticMass.lua

@@ -0,0 +1,41 @@
+return {
+  summary = 'Enable or disable automatic mass.',
+  description = [[
+    Enables or disables automatic mass for the Collider.
+
+    When enabled, the Collider's mass, inertia, and center of mass will be recomputed when:
+
+    - A shape is added to or removed from the Collider.
+    - A shape attached to the Collider changes shape (e.g. `SphereShape:setRadius`).
+    - A shape attached to the Collider is moved using `Shape:setOffset`.
+    - A shape attached to the Collider changes its density using `Shape:setDensity`.
+
+    Additionally, changing the center of mass of a Collider will automatically update its inertia
+    when automatic mass is enabled.
+
+    Disable this to manage the mass properties manually.  When automatic mass is disabled,
+    `Collider:resetMassData` can still be used to reset the mass from attached shapes if needed.
+  ]],
+  arguments = {
+    enable = {
+      type = 'boolean',
+      description = 'Whether automatic mass should be enabled.'
+    }
+  },
+  returns = {},
+  variants = {
+    {
+      arguments = { 'enable' },
+      returns = {}
+    }
+  },
+  related = {
+    'Collider:resetMassData',
+    'Collider:getMass',
+    'Collider:setMass',
+    'Collider:getInertia',
+    'Collider:setInertia',
+    'Collider:getCenterOfMass',
+    'Collider:setCenterOfMass'
+  }
+}

+ 56 - 0
api/lovr/physics/Collider/setCenterOfMass.lua

@@ -0,0 +1,56 @@
+return {
+  summary = 'Set the Collider\'s center of mass.',
+  description = [[
+    Sets the Collider's center of mass, in the Collider's local coordinate space.
+
+    This does not change the Collider's position.
+  ]],
+  arguments = {
+    x = {
+      type = 'number',
+      description = 'The x component of the center of mass.'
+    },
+    y = {
+      type = 'number',
+      description = 'The y component of the center of mass.'
+    },
+    z = {
+      type = 'number',
+      description = 'The z component of the center of mass.'
+    },
+    center = {
+      type = 'Vec3',
+      description = 'The center of mass.'
+    }
+  },
+  returns = {},
+  variants = {
+    {
+      arguments = { 'x', 'y', 'z' },
+      returns = {}
+    },
+    {
+      arguments = { 'center' },
+      returns = {}
+    }
+  },
+  notes = [[
+    By default, the center of mass of the Collider is kept up to date automatically as the
+    Collider's shapes change.  To disable this, use `Collider:setAutomaticMass`.
+
+    Use `Collider:resetMassData` to reset the center and other mass properties based on the
+    Collider's shapes.
+  ]],
+  related = {
+    'Shape:getCenterOfMass',
+    'Collider:getMass',
+    'Collider:setMass',
+    'Collider:getInertia',
+    'Collider:setInertia',
+    'Collider:getAutomaticMass',
+    'Collider:setAutomaticMass',
+    'Collider:resetMassData',
+    'Shape:getOffset',
+    'Shape:setOffset'
+  }
+}

+ 39 - 0
api/lovr/physics/Collider/setEnabledAxes.lua

@@ -0,0 +1,39 @@
+return {
+  summary = 'Set the enabled translation/rotation axes.',
+  description = 'Set the axes that are enabled for translation and rotation.',
+  arguments = {
+    translation = {
+      type = 'string',
+      description = [[
+        A string containing the world-space axes the Collider is allowed to move on.  The string
+        should have 'x', 'y', and 'z' letters representing the axes to enable.  Use nil or an empty
+        string to disable all translation.
+      ]]
+    },
+    rotation = {
+      type = 'string',
+      description = [[
+        A string containing the world-space axes the Collider is allowed to rotate on.  The string
+        should have 'x', 'y', and 'z' letters representing the axes to enable.  Use nil or an empty
+        string to disable all rotation.
+      ]]
+    }
+  },
+  returns = {},
+  variants = {
+    {
+      arguments = { 'translation', 'rotation' },
+      returns = {}
+    }
+  },
+  notes = [[
+    The default state is `xyz` for both translation and rotation.
+
+    The physics engine does not support disabling all axes.  At least one translation or rotation
+    axis needs to be enabled.  To disable all movement for a collider, make it kinematic.
+
+    When all translation axes are disabled, `Collider:getMass` will return 0.
+
+    When all rotation axes are disabled, `Collider:getInertia` will return zero/identity.
+  ]]
+}

+ 14 - 5
api/lovr/physics/Collider/setFriction.lua

@@ -1,13 +1,14 @@
 return {
 return {
   summary = 'Set the friction of the Collider.',
   summary = 'Set the friction of the Collider.',
   description = [[
   description = [[
-    Sets the friction of the Collider.  By default, the friction of two Colliders is combined
-    (multiplied) when they collide to generate a friction force.  The initial friction is 0.
+    Sets the friction of the Collider.  Friction determines how easy it is for two colliders to
+    slide against each other.  Low friction makes it easier for a collider to slide, simulating a
+    smooth surface.
   ]],
   ]],
   arguments = {
   arguments = {
     friction = {
     friction = {
       type = 'number',
       type = 'number',
-      description = 'The new friction.'
+      description = 'The friction of the Collider.'
     }
     }
   },
   },
   returns = {},
   returns = {},
@@ -17,9 +18,17 @@ return {
       returns = {}
       returns = {}
     }
     }
   },
   },
+  notes = [[
+    The default friction is .2.
+
+    When two colliders collide, their friction is combined using the geometric mean:
+
+        friction = (frictionA * frictionB) ^ .5
+  ]],
   related = {
   related = {
+    'Contact:getFriction',
+    'Contact:setFriction',
     'Collider:getRestitution',
     'Collider:getRestitution',
-    'Collider:setRestitution',
-    'World:collide'
+    'Collider:setRestitution'
   }
   }
 }
 }

+ 85 - 0
api/lovr/physics/Collider/setInertia.lua

@@ -0,0 +1,85 @@
+return {
+  summary = 'Set the inertia of the Collider.',
+  description = [[
+    Sets the inertia of the Collider.
+
+    Inertia is kind of like "angular mass".  Regular mass determines how resistant the Collider is
+    to linear forces (movement), whereas inertia determines how resistant the Collider is to torque
+    (rotation).  Colliders with less inertia are more spinny.
+
+    In 3D, inertia is represented by a 3x3 matrix, called a tensor.  To make calculations easier,
+    the physics engine stores the inertia using eigenvalue decomposition, splitting the matrix into
+    a diagonal matrix and a rotation.  It's complicated!
+
+    In a realistic simulation, mass and inertia follow a linear relationship.  If the mass of an
+    object increases, the diagonal part of its inertia should increase proportionally.
+  ]],
+  arguments = {
+    dx = {
+      type = 'number',
+      description = 'The x component of the diagonal matrix.'
+    },
+    dy = {
+      type = 'number',
+      description = 'The y component of the diagonal matrix.'
+    },
+    dz = {
+      type = 'number',
+      description = 'The z component of the diagonal matrix.'
+    },
+    angle = {
+      type = 'number',
+      description = 'The angle of the inertia rotation, in radians.'
+    },
+    ax = {
+      type = 'number',
+      description = 'The x component of the rotation axis.'
+    },
+    ay = {
+      type = 'number',
+      description = 'The y component of the rotation axis.'
+    },
+    az = {
+      type = 'number',
+      description = 'The z component of the rotation axis.'
+    },
+    diagonal = {
+      type = 'Vec3',
+      description = 'A vector containing the 3 elements of a diagonal matrix.'
+    },
+    rotation = {
+      type = 'Quat',
+      description = 'The inertia rotation.'
+    }
+  },
+  variants = {
+    {
+      arguments = { 'dx', 'dy', 'dz', 'angle', 'ax', 'ay', 'az' },
+      returns = {}
+    },
+    {
+      arguments = { 'diagonal', 'rotation' },
+      returns = {}
+    }
+  },
+  notes = [[
+    By default, the inertia of the Collider is kept up to date automatically as the Collider's
+    shapes change.  To disable this, use `Collider:setAutomaticMass`.
+
+    Use `Collider:resetMassData` to reset the inertia and other mass properties based on the
+    Collider's shapes.
+
+    If the Collider is kinematic or all rotation axes are disabled, this returns 0 for the diagonal
+    and an identity quaternion for the rotation.
+  ]],
+  related = {
+    'Collider:getMass',
+    'Collider:setMass',
+    'Collider:getCenterOfMass',
+    'Collider:setCenterOfMass',
+    'Collider:getAutomaticMass',
+    'Collider:setAutomaticMass',
+    'Collider:resetMassData',
+    'Shape:getInertia'
+  }
+}

+ 10 - 14
api/lovr/physics/Collider/setLinearDamping.lua

@@ -1,36 +1,32 @@
 return {
 return {
   summary = 'Set the linear damping of the Collider.',
   summary = 'Set the linear damping of the Collider.',
   description = [[
   description = [[
-    Sets the Collider's linear damping parameter.  Linear damping is similar to drag or air
-    resistance, slowing the Collider down over time. Damping is only applied when linear
-    velocity is over the threshold value.
+    Sets the linear damping of the Collider.  Linear damping is similar to drag or air resistance,
+    slowing the Collider down over time.
   ]],
   ]],
   arguments = {
   arguments = {
     damping = {
     damping = {
       type = 'number',
       type = 'number',
       description = 'The linear damping.'
       description = 'The linear damping.'
-    },
-    threshold = {
-      type = 'number',
-      default = '0',
-      description = 'Velocity limit below which the damping is not applied.'
     }
     }
   },
   },
   returns = {},
   returns = {},
   variants = {
   variants = {
     {
     {
-      arguments = { 'damping', 'threshold' },
+      arguments = { 'damping' },
       returns = {}
       returns = {}
     }
     }
   },
   },
   notes = [[
   notes = [[
-    When the Collider is created, it will use the world's linear damping value, which is set using
-    `World:setLinearDamping`.
+    The default damping is .05, meaning the collider will lose approximately 5% of its velocity each
+    second.  A damping value of zero means the Collider will not lose velocity over time.
 
 
-    A linear damping of 0 means the Collider won't slow down over time.
+    Negative damping is not meaningful and will be clamped to zero.
   ]],
   ]],
   related = {
   related = {
-    'World:getLinearDamping',
-    'World:setLinearDamping'
+    'Collider:getAngularDamping',
+    'Collider:setAngularDamping',
+    'Collider:getGravityScale',
+    'Collider:setGravityScale'
   }
   }
 }
 }

+ 23 - 11
api/lovr/physics/Collider/setLinearVelocity.lua

@@ -1,26 +1,22 @@
 return {
 return {
   summary = 'Set the linear velocity of the Collider.',
   summary = 'Set the linear velocity of the Collider.',
-  description = [[
-    Sets the linear velocity of the Collider directly.  Usually it's preferred to use
-    `Collider:applyForce` to change velocity since instantaneous velocity changes can lead to weird
-    glitches.
-  ]],
+  description = 'Sets the world-space linear velocity of the center of mass of the Collider.',
   arguments = {
   arguments = {
     vx = {
     vx = {
       type = 'number',
       type = 'number',
-      description = 'The x velocity of the Collider, in meters per second.'
+      description = 'The x component of the new velocity, in meters per second.'
     },
     },
     vy = {
     vy = {
       type = 'number',
       type = 'number',
-      description = 'The y velocity of the Collider, in meters per second.'
+      description = 'The y component of the new velocity, in meters per second.'
     },
     },
     vz = {
     vz = {
       type = 'number',
       type = 'number',
-      description = 'The z velocity of the Collider, in meters per second.'
+      description = 'The z component of the new velocity, in meters per second.'
     },
     },
     velocity = {
     velocity = {
       type = 'Vec3',
       type = 'Vec3',
-      description = 'The velocity of the Collider, in meters per second.'
+      description = 'The new velocity, in meters per second.'
     }
     }
   },
   },
   returns = {},
   returns = {},
@@ -36,13 +32,29 @@ return {
       returns = {}
       returns = {}
     }
     }
   },
   },
-  notes = 'If the Collider is asleep, calling this function will wake it up.',
+  notes = [[
+    Although setting the velocity directly is useful sometimes, it can cause problems:
+
+    - Velocity ignores mass, so it can lead to unnaturally sharp changes in motion.
+    - If the velocity of a Collider is changed multiple times during a frame, only the last one is
+      going to have an effect, nullifying the other velocities that were set.
+    - Setting the velocity of a Collider every frame can mess up collisions, since the forces used
+      to resolve a collision will get ignored by changing the velocity.
+
+    Using forces and impulses to move Colliders will avoid all of these issues.
+
+    If the Collider is asleep, setting the velocity to a non-zero value will wake it up.
+
+    If the Collider has a tag that was marked as static when the World was created, then the
+    Collider can not move and this function will do nothing.
+  ]],
   related = {
   related = {
+    'Collider:applyForce',
+    'Collider:applyLinearImpulse',
     'Collider:getLinearVelocityFromLocalPoint',
     'Collider:getLinearVelocityFromLocalPoint',
     'Collider:getLinearVelocityFromWorldPoint',
     'Collider:getLinearVelocityFromWorldPoint',
     'Collider:getAngularVelocity',
     'Collider:getAngularVelocity',
     'Collider:setAngularVelocity',
     'Collider:setAngularVelocity',
-    'Collider:applyForce',
     'Collider:getPosition',
     'Collider:getPosition',
     'Collider:setPosition'
     'Collider:setPosition'
   }
   }

+ 36 - 4
api/lovr/physics/Collider/setMass.lua

@@ -1,6 +1,19 @@
 return {
 return {
-  summary = 'Set the total mass of the Collider.',
-  description = 'Sets the total mass of the Collider.',
+  summary = 'Set the mass of the Collider.',
+  description = [[
+    Sets the mass of the Collider.
+
+    The relative mass of colliders determines how they react when they collide.  A heavier collider
+    has more momentum than a lighter collider moving the same speed, and will impart more force on
+    the lighter collider.
+
+    More generally, heavier colliders react less to forces they receive, including forces applied
+    with functions like `Collider:applyForce`.
+
+    Colliders with higher mass do not fall faster.  Use `Collider:setLinearDamping` to give a
+    collider drag to make it fall slower or `Collider:setGravityScale` to change the way it reacts
+    to gravity.
+  ]],
   arguments = {
   arguments = {
     mass = {
     mass = {
       type = 'number',
       type = 'number',
@@ -14,9 +27,28 @@ return {
       returns = {}
       returns = {}
     }
     }
   },
   },
+  notes = [[
+    The mass must be positive.  Attempting to set a zero or negative mass will error.
+
+    By default, the mass of the Collider is kept up to date automatically as the Collider's shapes
+    change.  Use `Collider:setAutomaticMass` to disable this.
+
+    Use `Collider:resetMassData` to reset the mass based on the Collider's shapes.
+
+    If the Collider is kinematic or all translation axes are disabled, this function will do
+    nothing.
+  ]],
   related = {
   related = {
-    'Collider:getMassData',
-    'Collider:setMassData',
+    'Collider:getInertia',
+    'Collider:setInertia',
+    'Collider:getCenterOfMass',
+    'Collider:setCenterOfMass',
+    'Collider:getAutomaticMass',
+    'Collider:setAutomaticMass',
+    'Collider:resetMassData',
+    'Shape:getDensity',
+    'Shape:setDensity',
+    'Shape:getVolume',
     'Shape:getMass'
     'Shape:getMass'
   }
   }
 }
 }

+ 14 - 6
api/lovr/physics/Collider/setRestitution.lua

@@ -1,14 +1,14 @@
 return {
 return {
   summary = 'Set the bounciness of the Collider.',
   summary = 'Set the bounciness of the Collider.',
   description = [[
   description = [[
-    Sets the restitution (bounciness) of the Collider.  By default, the restitution of two Colliders
-    is combined (the max is used) when they collide to cause them to bounce away from each other.
-    The initial restitution is 0.
+    Sets the restitution of the Collider.  Restitution makes a Collider bounce when it collides with
+    other objects.  A restitution value of zero would result in an inelastic collision response,
+    whereas 1.0 would result in an elastic collision that preserves all of the velocity.
   ]],
   ]],
   arguments = {
   arguments = {
     restitution = {
     restitution = {
       type = 'number',
       type = 'number',
-      description = 'The new restitution.'
+      description = 'The restitution of the Collider.'
     }
     }
   },
   },
   returns = {},
   returns = {},
@@ -18,9 +18,17 @@ return {
       returns = {}
       returns = {}
     }
     }
   },
   },
+  notes = [[
+    To improve stability of the simulation and allow colliders to come to rest, restitution is only
+    applied if the collider is moving above a certain speed.  This can be configured using the
+    `restitutionThreshold` option in `lovr.physics.newWorld`.
+
+    Negative restitution is not meaningful and is clamped to zero.
+  ]],
   related = {
   related = {
+    'Contact:getRestitution',
+    'Contact:setRestitution',
     'Collider:getFriction',
     'Collider:getFriction',
-    'Collider:setFriction',
-    'World:collide'
+    'Collider:setFriction'
   }
   }
 }
 }

+ 11 - 6
api/lovr/physics/Collider/setTag.lua

@@ -1,10 +1,18 @@
 return {
 return {
   summary = 'Set the Collider\'s tag.',
   summary = 'Set the Collider\'s tag.',
-  description = 'Sets the Collider\'s tag.',
+  description = [[
+    Sets the Collider's tag.
+
+    Tags are strings that represent the category of a collider.  Use `World:enableCollisionBetween`
+    and `World:disableCollisionBetween` to control which pairs of tags should collide with each
+    other.  Physics queries like `World:raycast` also use tags to filter their results.
+
+    The list of available tags is set in `lovr.physics.newWorld`.
+  ]],
   arguments = {
   arguments = {
     tag = {
     tag = {
       type = 'string',
       type = 'string',
-      description = 'The Collider\'s collision tag.'
+      description = 'The Collider\'s tag.'
     }
     }
   },
   },
   returns = {},
   returns = {},
@@ -19,11 +27,8 @@ return {
       returns = {}
       returns = {}
     }
     }
   },
   },
-  notes = [[
-    Collision between tags can be enabled and disabled using `World:enableCollisionBetween` and
-    `World:disableCollisionBetween`.
-  ]],
   related = {
   related = {
+    'World:getTags',
     'World:disableCollisionBetween',
     'World:disableCollisionBetween',
     'World:enableCollisionBetween',
     'World:enableCollisionBetween',
     'World:isCollisionEnabledBetween',
     'World:isCollisionEnabledBetween',