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 = {
     x = {
       type = 'number',
-      description = 'The x component of the force to apply.'
+      description = 'The x component of the world-space force vector, in newtons.'
     },
     y = {
       type = 'number',
-      description = 'The y component of the force to apply.'
+      description = 'The y component of the world-space force vector, in newtons.'
     },
     z = {
       type = 'number',
-      description = 'The z component of the force to apply.'
+      description = 'The z component of the world-space force vector, in newtons.'
     },
     px = {
       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 = {
       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 = {
       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 = {
       type = 'Vec3',
-      description = 'The force vector to apply.'
+      description = 'The world-space force vector, in newtons.'
     },
     position = {
       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 = {},
   variants = {
     {
+      description = 'Apply a force at the center of mass.',
       arguments = { 'x', 'y', 'z' },
       returns = {}
     },
     {
+      description = 'Apply a force at a custom position.',
       arguments = { 'x', 'y', 'z', 'px', 'py', 'pz' },
       returns = {}
     },
     {
+      description = 'Apply a force at the center of mass, using vector types.',
       arguments = { 'force' },
       returns = {}
     },
     {
+      description = 'Apply a force at a custom position, using vector types.',
       arguments = { 'force', 'position' },
       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 = {
-    '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 = {
     x = {
       type = 'number',
-      description = 'The x component of the torque.'
+      description = 'The x component of the world-space torque vector, in newton meters.'
     },
     y = {
       type = 'number',
-      description = 'The y component of the torque.'
+      description = 'The y component of the world-space torque vector, in newton meters.'
     },
     z = {
       type = 'number',
-      description = 'The z component of the torque.'
+      description = 'The z component of the world-space torque vector, in newton meters.'
     },
     torque = {
       type = 'Vec3',
-      description = 'The torque to apply.'
+      description = 'The world-space torque vector, in newton meters.'
     }
   },
   returns = {},
@@ -30,8 +30,16 @@ return {
       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 = {
-    'Collider:applyForce'
+    'Collider:applyAngularImpulse',
+    'Collider:applyForce',
+    'Collider:applyLinearImpulse'
   }
 }

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

@@ -1,6 +1,9 @@
 return {
   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 = {},
   returns = {
     minx = {
@@ -35,6 +38,7 @@ return {
     }
   },
   related = {
-    'Shape:getAABB'
+    'Shape:getAABB',
+    'World:queryBox'
   }
 }

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

@@ -1,32 +1,31 @@
 return {
   summary = 'Get the angular damping of the Collider.',
   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 = {},
   returns = {
     damping = {
       type = 'number',
       description = 'The angular damping.'
-    },
-    threshold = {
-      type = 'number',
-      description = 'Velocity limit below which the damping is not applied.'
     }
   },
   variants = {
     {
       arguments = {},
-      returns = { 'damping', 'threshold' }
+      returns = { 'damping' }
     }
   },
   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 = {
-    '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 {
   summary = 'Get the friction of the Collider.',
   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 = {},
   returns = {
@@ -17,9 +18,17 @@ return {
       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 = {
+    'Contact:getFriction',
+    'Contact:setFriction',
     '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 {
   summary = 'Get the linear damping of the Collider.',
   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.
   ]],
   arguments = {},
@@ -9,26 +9,22 @@ return {
     damping = {
       type = 'number',
       description = 'The linear damping.'
-    },
-    threshold = {
-      type = 'number',
-      description = 'Velocity limit below which the damping is not applied.'
     }
   },
   variants = {
     {
       arguments = {},
-      returns = { 'damping', 'threshold' }
+      returns = { 'damping' }
     }
   },
   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 = {
-    '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 {
   summary = 'Get the linear velocity of the Collider.',
   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 = {},
   returns = {
     vx = {
       type = 'number',
-      description = 'The x velocity of the Collider, in meters per second.'
+      description = 'The x component of the velocity.'
     },
     vy = {
       type = 'number',
-      description = 'The y velocity of the Collider, in meters per second.'
+      description = 'The y component of the velocity.'
     },
     vz = {
       type = 'number',
-      description = 'The z velocity of the Collider, in meters per second.'
+      description = 'The z component of the velocity.'
     }
   },
   variants = {
@@ -26,11 +26,11 @@ return {
     }
   },
   related = {
+    'Collider:applyForce',
     'Collider:getLinearVelocityFromLocalPoint',
     'Collider:getLinearVelocityFromWorldPoint',
     'Collider:getAngularVelocity',
     'Collider:setAngularVelocity',
-    'Collider:applyForce',
     'Collider:getPosition',
     'Collider:setPosition'
   }

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

@@ -1,36 +1,39 @@
 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 = {
     x = {
       type = 'number',
-      description = 'The x coordinate.'
+      description = 'The x position in local space.'
     },
     y = {
       type = 'number',
-      description = 'The y coordinate.'
+      description = 'The y position in local space.'
     },
     z = {
       type = 'number',
-      description = 'The z coordinate.'
+      description = 'The z position in local space.'
     },
     point = {
       type = 'number',
-      description = 'The point.'
+      description = 'The local-space point.'
     }
   },
   returns = {
     vx = {
       type = 'number',
-      description = 'The x component of the velocity of the point.'
+      description = 'The x velocity of the point.'
     },
     vy = {
       type = 'number',
-      description = 'The y component of the velocity of the point.'
+      description = 'The y velocity of the point.'
     },
     vz = {
       type = 'number',
-      description = 'The z component of the velocity of the point.'
+      description = 'The z velocity of the point.'
     }
   },
   variants = {

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

@@ -1,38 +1,39 @@
 return {
   summary = 'Get the linear velocity of the Collider at a world space point.',
   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 = {
     x = {
       type = 'number',
-      description = 'The x coordinate in world space.'
+      description = 'The x position in world space.'
     },
     y = {
       type = 'number',
-      description = 'The y coordinate in world space.'
+      description = 'The y position in world space.'
     },
     z = {
       type = 'number',
-      description = 'The z coordinate in world space.'
+      description = 'The z position in world space.'
     },
     point = {
       type = 'Vec3',
-      descriptio = 'The point.'
+      descriptio = 'The world-space point.'
     }
   },
   returns = {
     vx = {
       type = 'number',
-      description = 'The x component of the velocity of the point.'
+      description = 'The x velocity of the point.'
     },
     vy = {
       type = 'number',
-      description = 'The y component of the velocity of the point.'
+      description = 'The y velocity of the point.'
     },
     vz = {
       type = 'number',
-      description = 'The z component of the velocity of the point.'
+      description = 'The z velocity of the point.'
     }
   },
   variants = {

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

@@ -1,20 +1,20 @@
 return {
-  summary = 'Convert a point from world space to collider space.',
+  summary = 'Transform a point from world space to collider space.',
   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 = {
     wx = {
       type = 'number',
-      description = 'The x coordinate of the world point.'
+      description = 'The x component of the world point.'
     },
     wy = {
       type = 'number',
-      description = 'The y coordinate of the world point.'
+      description = 'The y component of the world point.'
     },
     wz = {
       type = 'number',
-      description = 'The z coordinate of the world point.'
+      description = 'The z component of the world point.'
     },
     point = {
       type = 'Vec3',
@@ -24,15 +24,15 @@ return {
   returns = {
     x = {
       type = 'number',
-      description = 'The x position of the local-space point.'
+      description = 'The x component of the local point.'
     },
     y = {
       type = 'number',
-      description = 'The y position of the local-space point.'
+      description = 'The y component of the local point.'
     },
     z = {
       type = 'number',
-      description = 'The z position of the local-space point.'
+      description = 'The z component of the local point.'
     }
   },
   variants = {

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

@@ -1,6 +1,6 @@
 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 = {
     wx = {
       type = 'number',
@@ -22,15 +22,15 @@ return {
   returns = {
     x = {
       type = 'number',
-      description = 'The x coordinate of the local vector.'
+      description = 'The x component of the local vector.'
     },
     y = {
       type = 'number',
-      description = 'The y coordinate of the local vector.'
+      description = 'The y component of the local vector.'
     },
     z = {
       type = 'number',
-      description = 'The z coordinate of the local vector.'
+      description = 'The z component of the local vector.'
     }
   },
   variants = {

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

@@ -29,15 +29,13 @@ return {
   },
   notes = [[
     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
     `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 = {
     'Collider:getInertia',

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

@@ -26,8 +26,15 @@ return {
       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 = {
     'Collider:applyTorque',
+    'Collider:getRawOrientation',
     'Collider:getAngularVelocity',
     'Collider:setAngularVelocity',
     'Collider:getPosition',

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

@@ -38,8 +38,15 @@ return {
       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 = {
     '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' }
     }
   },
+  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 = {
     'Collider:applyForce',
+    'Collider:getRawPosition',
     'Collider:getLinearVelocity',
     'Collider:setLinearVelocity',
     '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 {
   summary = 'Get the bounciness of the Collider.',
   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 = {},
   returns = {
@@ -18,9 +18,15 @@ return {
       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 = {
+    'Contact:getRestitution',
+    'Contact:setRestitution',
     'Collider:getFriction',
-    'Collider:setFriction',
-    'World:collide'
+    'Collider:setFriction'
   }
 }

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

@@ -1,24 +1,29 @@
 return {
   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 = {},
   returns = {
     tag = {
       type = 'string',
-      description = 'The Collider\'s collision tag, or `nil` if the Collider doesn\'t have a tag.'
+      description = 'The Collider\'s tag.'
     }
   },
   variants = {
     {
-      arguments = {},
-      returns = { 'tag' }
+      arguments = {}
+      returns = { 'tag' },
     }
   },
-  notes = [[
-    Collision between tags can be enabled and disabled using `World:enableCollisionBetween` and
-    `World:disableCollisionBetween`.
-  ]],
   related = {
+    'World:getTags',
     'World:disableCollisionBetween',
     'World:enableCollisionBetween',
     'World:isCollisionEnabledBetween',

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

@@ -1,18 +1,20 @@
 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 = {
     x = {
       type = 'number',
-      description = 'The x position of the point.'
+      description = 'The x component of the local point.'
     },
     y = {
       type = 'number',
-      description = 'The y position of the point.'
+      description = 'The y component of the local point.'
     },
     z = {
       type = 'number',
-      description = 'The z position of the point.'
+      description = 'The z component of the local point.'
     },
     point = {
       type = 'Vec3',
@@ -22,15 +24,15 @@ return {
   returns = {
     wx = {
       type = 'number',
-      description = 'The x coordinate of the world point.'
+      description = 'The x component of the world point.'
     },
     wy = {
       type = 'number',
-      description = 'The y coordinate of the world point.'
+      description = 'The y component of the world point.'
     },
     wz = {
       type = 'number',
-      description = 'The z coordinate of the world point.'
+      description = 'The z component of the world point.'
     }
   },
   variants = {

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

@@ -1,20 +1,18 @@
 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 = {
     x = {
       type = 'number',
-      description = 'The x coordinate of the local vector.'
+      description = 'The x component of the local vector.'
     },
     y = {
       type = 'number',
-      description = 'The y coordinate of the local vector.'
+      description = 'The y component of the local vector.'
     },
     z = {
       type = 'number',
-      description = 'The z coordinate of the local vector.'
+      description = 'The z component of the local vector.'
     },
     vector = {
       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 {
   summary = 'Set the angular damping of the Collider.',
   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 = {
     damping = {
       type = 'number',
       description = 'The angular damping.'
-    },
-    threshold = {
-      type = 'number',
-      default = '0',
-      description = 'Velocity limit below which the damping is not applied.'
     }
   },
   returns = {},
   variants = {
     {
-      arguments = { 'damping', 'threshold' },
+      arguments = { 'damping' },
       returns = {}
     }
   },
   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 = {
-    '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 = {}
     }
   },
-  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 = {
+    'Collider:applyTorque',
+    'Collider:applyAngularImpulse',
     'Collider:getLinearVelocity',
     'Collider:setLinearVelocity',
-    'Collider:applyTorque',
     'Collider:getOrientation',
     '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 {
   summary = 'Set the friction of the Collider.',
   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 = {
     friction = {
       type = 'number',
-      description = 'The new friction.'
+      description = 'The friction of the Collider.'
     }
   },
   returns = {},
@@ -17,9 +18,17 @@ return {
       returns = {}
     }
   },
+  notes = [[
+    The default friction is .2.
+
+    When two colliders collide, their friction is combined using the geometric mean:
+
+        friction = (frictionA * frictionB) ^ .5
+  ]],
   related = {
+    'Contact:getFriction',
+    'Contact:setFriction',
     '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 {
   summary = 'Set the linear damping of the Collider.',
   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 = {
     damping = {
       type = 'number',
       description = 'The linear damping.'
-    },
-    threshold = {
-      type = 'number',
-      default = '0',
-      description = 'Velocity limit below which the damping is not applied.'
     }
   },
   returns = {},
   variants = {
     {
-      arguments = { 'damping', 'threshold' },
+      arguments = { 'damping' },
       returns = {}
     }
   },
   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 = {
-    '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 {
   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 = {
     vx = {
       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 = {
       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 = {
       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 = {
       type = 'Vec3',
-      description = 'The velocity of the Collider, in meters per second.'
+      description = 'The new velocity, in meters per second.'
     }
   },
   returns = {},
@@ -36,13 +32,29 @@ return {
       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 = {
+    'Collider:applyForce',
+    'Collider:applyLinearImpulse',
     'Collider:getLinearVelocityFromLocalPoint',
     'Collider:getLinearVelocityFromWorldPoint',
     'Collider:getAngularVelocity',
     'Collider:setAngularVelocity',
-    'Collider:applyForce',
     'Collider:getPosition',
     'Collider:setPosition'
   }

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

@@ -1,6 +1,19 @@
 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 = {
     mass = {
       type = 'number',
@@ -14,9 +27,28 @@ return {
       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 = {
-    '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'
   }
 }

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

@@ -1,14 +1,14 @@
 return {
   summary = 'Set the bounciness of the Collider.',
   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 = {
     restitution = {
       type = 'number',
-      description = 'The new restitution.'
+      description = 'The restitution of the Collider.'
     }
   },
   returns = {},
@@ -18,9 +18,17 @@ return {
       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 = {
+    'Contact:getRestitution',
+    'Contact:setRestitution',
     'Collider:getFriction',
-    'Collider:setFriction',
-    'World:collide'
+    'Collider:setFriction'
   }
 }

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

@@ -1,10 +1,18 @@
 return {
   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 = {
     tag = {
       type = 'string',
-      description = 'The Collider\'s collision tag.'
+      description = 'The Collider\'s tag.'
     }
   },
   returns = {},
@@ -19,11 +27,8 @@ return {
       returns = {}
     }
   },
-  notes = [[
-    Collision between tags can be enabled and disabled using `World:enableCollisionBetween` and
-    `World:disableCollisionBetween`.
-  ]],
   related = {
+    'World:getTags',
     'World:disableCollisionBetween',
     'World:enableCollisionBetween',
     'World:isCollisionEnabledBetween',