Browse Source

More Collider docs;

bjorn 1 year ago
parent
commit
3e2102925d

+ 26 - 0
api/lovr/physics/Collider/getGravityScale.lua

@@ -0,0 +1,26 @@
+return {
+  summary = 'Get the gravity scale of the Collider.',
+  description = [[
+    Returns the gravity scale of the Collider.  This is multiplied with the global gravity from the
+    World, so 1.0 is regular gravity, 0.0 will ignore gravity, etc.
+  ]],
+  arguments = {},
+  returns = {
+    scale = {
+      type = 'number',
+      description = 'The gravity scale.'
+    }
+  },
+  variants = {
+    {
+      arguments = {},
+      returns = { 'scale' }
+    }
+  },
+  related = {
+    'World:getGravity',
+    'World:setGravity',
+    'Collider:getLinearDamping',
+    'Collider:setLinearDamping'
+  }
+}

+ 35 - 4
api/lovr/physics/Collider/getMass.lua

@@ -1,7 +1,18 @@
 return {
 return {
-  summary = 'Get the total mass of the Collider.',
+  summary = 'Get the mass of the Collider.',
   description = [[
   description = [[
-    Returns the total mass of the Collider.  The mass of a Collider depends on its attached shapes.
+    Returns 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 = {},
   returns = {
   returns = {
@@ -16,9 +27,29 @@ return {
       returns = { 'mass' }
       returns = { 'mass' }
     }
     }
   },
   },
+  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`.
+
+    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.
+  ]],
   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'
   }
   }
 }
 }

+ 1 - 1
api/lovr/physics/Collider/getShape.lua

@@ -17,7 +17,7 @@ return {
   variants = {
   variants = {
     {
     {
       arguments = {},
       arguments = {},
-      returns = { 'shapes' }
+      returns = { 'shape' }
     }
     }
   },
   },
   notes = 'This may return `nil` if the Collider doesn\'t have any shapes attached to it.',
   notes = 'This may return `nil` if the Collider doesn\'t have any shapes attached to it.',

+ 3 - 4
api/lovr/physics/Collider/isAwake.lua

@@ -1,11 +1,11 @@
 return {
 return {
   summary = 'Check if the Collider is awake.',
   summary = 'Check if the Collider is awake.',
-  description = 'Returns whether the Collider is currently awake.',
+  description = 'Returns whether the Collider is awake.',
   arguments = {},
   arguments = {},
   returns = {
   returns = {
     awake = {
     awake = {
       type = 'boolean',
       type = 'boolean',
-      description = 'Whether the Collider is awake.'
+      description = 'Whether the Collider is finally awake.'
     }
     }
   },
   },
   variants = {
   variants = {
@@ -14,9 +14,8 @@ return {
       returns = { 'awake' }
       returns = { 'awake' }
     }
     }
   },
   },
+  notes = 'See `Collider:setSleepingAllowed` for notes about sleeping.',
   related = {
   related = {
-    'World:isSleepingAllowed',
-    'World:setSleepingAllowed',
     'Collider:isSleepingAllowed',
     'Collider:isSleepingAllowed',
     'Collider:setSleepingAllowed'
     'Collider:setSleepingAllowed'
   }
   }

+ 33 - 0
api/lovr/physics/Collider/isContinuous.lua

@@ -0,0 +1,33 @@
+return {
+  summary = 'Check if the Collider is using continuous collision detection.',
+  description = [[
+    Returns whether the Collider uses continuous collision detection.
+
+    Normally on each timestep a Collider will "teleport" to its new position based on its velocity.
+    Usually this works fine, but if a Collider is going really fast relative to its size, then it
+    might miss collisions with objects or pass through walls.  Enabling continuous collision
+    detection means the Collider will check for obstacles along its path before moving to the new
+    location.  This prevents the Collider from going through walls, but reduces performance.  It's
+    usually used for projectiles, which tend to be small and really fast.
+  ]],
+  arguments = {},
+  returns = {
+    continuous = {
+      type = 'boolean',
+      description = 'Whether the Collider uses continuous collision detection.'
+    }
+  },
+  variants = {
+    {
+      arguments = {},
+      returns = { 'continuous' }
+    }
+  },
+  notes = [[
+    The physics engine performs an optimization where continuous collision detection is only used if
+    the Collider is moving faster than 75% of its size.  So it is not necessary to enable and
+    disable continuous collision detection based on how fast the Collider is moving.
+
+    Colliders that are sensors are not able to use continuous collision detection.
+  ]]
+}

+ 1 - 0
api/lovr/physics/Collider/isGravityIgnored.lua

@@ -1,4 +1,5 @@
 return {
 return {
+  deprecated = true,
   summary = 'Check if the Collider ignores gravity.',
   summary = 'Check if the Collider ignores gravity.',
   description = 'Returns whether the Collider is currently ignoring gravity.',
   description = 'Returns whether the Collider is currently ignoring gravity.',
   arguments = {},
   arguments = {},

+ 10 - 6
api/lovr/physics/Collider/isKinematic.lua

@@ -1,6 +1,14 @@
 return {
 return {
   summary = 'Check if the Collider is kinematic.',
   summary = 'Check if the Collider is kinematic.',
-  description = 'Returns whether the Collider is kinematic.',
+  description = [[
+    Returns whether the Collider is kinematic.
+
+    Kinematic colliders behave like they have infinite mass.  They ignore forces applied to them
+    from gravity, joints, and collisions, but they can still move if given a velocity.  Kinematic
+    colliders don't collide with other kinematic colliders.  They're useful for static environment
+    objects in a level, or for objects that have their position managed outside of the physics
+    system like tracked hands.
+  ]],
   arguments = {},
   arguments = {},
   returns = {
   returns = {
     kinematic = {
     kinematic = {
@@ -14,9 +22,5 @@ return {
       returns = { 'kinematic' }
       returns = { 'kinematic' }
     }
     }
   },
   },
-  notes = [[
-    Kinematic colliders behave as though they have infinite mass, ignoring external forces like
-    gravity, joints, or collisions (though non-kinematic colliders will collide with them). They can
-    be useful for static objects like floors or walls.
-  ]]
+  notes = 'If a Collider has a `MeshShape` or a `TerrainShape`, it will always be kinematic.'
 }
 }

+ 54 - 0
api/lovr/physics/Collider/isSensor.lua

@@ -0,0 +1,54 @@
+return {
+  summary = 'Check if the Collider is a sensor.',
+  description = [[
+    Returns whether the Collider is a sensor.  Sensors do not collide with other objects, but they
+    can still sense collisions with the collision callbacks set by `World:setCallbacks`.  Use them
+    to trigger gameplay behavior when an object is inside a region of space.
+  ]],
+  arguments = {},
+  returns = {
+    sensor = {
+      type = 'boolean',
+      description = 'Whether the Collider is a sensor.'
+    }
+  },
+  variants = {
+    {
+      arguments = {},
+      returns = { 'sensor' }
+    }
+  },
+  notes = [[
+    Sensors are still reported as hits when doing raycasts and other queries.  Use tags to ignore
+    sensors if needed.
+
+    When a World is created, a set of collision tags can be marked as "static", for performance.
+    Sensors do not detect collision with colliders that have a static tag.  Also, if a sensor itself
+    has a static tag, it will not be able to detect collisions with sleeping colliders.  If a
+    Collider enters a static sensor and goes to sleep, the `exit` callback is called and the sensor
+    is no longer able to detect that collider.
+
+    Sensors can not use continuous collision detection.
+
+    Sensors will never go to sleep.
+  ]],
+  example = [[
+    danger = world:newBoxCollider(x, y, z, width, height, depth)
+    danger:setKinematic(true)
+    danger:setSensor(true)
+
+    world:setCallbacks({
+      enter = function(a, b)
+        if (a == danger and b == player) or (a == player and b == danger) then
+          damagePlayer()
+        end
+      end
+    })
+  ]],
+  related = {
+    'Collider:setKinematic',
+    'Collider:setEnabled',
+    'World:overlapShape',
+    'World:setCallbacks'
+  }
+}

+ 29 - 12
api/lovr/physics/Collider/isSleepingAllowed.lua

@@ -1,9 +1,15 @@
 return {
 return {
   summary = 'Check if the Collider is allowed to sleep.',
   summary = 'Check if the Collider is allowed to sleep.',
-  description = 'Returns whether the Collider is allowed to sleep.',
+  description = [[
+    Returns whether the Collider is allowed to automatically go to sleep.
+
+    When enabled, the Collider will go to sleep if it hasn't moved in a while.  The physics engine
+    does not simulate movement for colliders that are asleep, which saves a lot of CPU for a typical
+    physics world where most objects are at rest at any given time.  
+  ]],
   arguments = {},
   arguments = {},
   returns = {
   returns = {
-    allowed = {
+    sleepy = {
       type = 'boolean',
       type = 'boolean',
       description = 'Whether the Collider can go to sleep.'
       description = 'Whether the Collider can go to sleep.'
     }
     }
@@ -11,23 +17,34 @@ return {
   variants = {
   variants = {
     {
     {
       arguments = {},
       arguments = {},
-      returns = { 'allowed' }
+      returns = { 'sleepy' }
     }
     }
   },
   },
   notes = [[
   notes = [[
-    If sleeping is enabled, the simulation will put the Collider to sleep if it hasn't moved in a
-    while. Sleeping colliders don't impact the physics simulation, which makes updates more
-    efficient and improves physics performance.  However, the physics engine isn't perfect at waking
-    up sleeping colliders and this can lead to bugs where colliders don't react to forces or
-    collisions properly.
+    Sleeping is enabled by default.  Sleeping can be disabled globally using the `allowSleep` option
+    in `lovr.physics.newWorld`.
+
+    Colliders can still be put to sleep manually with `Collider:setAwake`, even if automatic
+    sleeping is disabled.
+
+    Sleeping colliders will wake up when:
+
+    - Colliding with a moving collider
+    - Awakened explicitly with `Collider:setAwake`
+    - Changing position `Collider:setPosition` or `Collider:setOrientation`
+    - Changing velocity (to something non-zero)
+    - Applying force, torque, or an impulse
+    - Enabling a joint connected to the sleeping collider
+
+    Notably, the following will not wake up the collider:
 
 
-    It is possible to set the default value for new colliders using `World:setSleepingAllowed`.
+    - Changing its kinematic state with `Collider:setKinematic`
+    - Changing its shape with `Collider:addShape` or `Collider:removeShape`
+    - Disabling or destroying a sleeping collider it is resting on
 
 
-    Colliders can be manually put to sleep or woken up using `Collider:setAwake`.
+    Sensors will never go to sleep.
   ]],
   ]],
   related = {
   related = {
-    'World:isSleepingAllowed',
-    'World:setSleepingAllowed',
     'Collider:isAwake',
     'Collider:isAwake',
     'Collider:setAwake'
     'Collider:setAwake'
   }
   }

+ 5 - 6
api/lovr/physics/Collider/setAwake.lua

@@ -1,9 +1,6 @@
 return {
 return {
   summary = 'Put the Collider to sleep or wake it up.',
   summary = 'Put the Collider to sleep or wake it up.',
-  description = [[
-    Manually puts the Collider to sleep or wakes it up.  You can do this if you know a Collider
-    won't be touched for a while or if you need to it be active.
-  ]],
+  description = 'Puts the Collider to sleep or wakes it up manually.',
   arguments = {
   arguments = {
     awake = {
     awake = {
       type = 'boolean',
       type = 'boolean',
@@ -17,9 +14,11 @@ return {
       returns = {}
       returns = {}
     }
     }
   },
   },
+  notes = [[
+    This function can still be used to put a Collider to sleep even if automatic sleeping has been
+    disabled with `Collider:setSleepingAllowed`.
+  ]],
   related = {
   related = {
-    'World:isSleepingAllowed',
-    'World:setSleepingAllowed',
     'Collider:isSleepingAllowed',
     'Collider:isSleepingAllowed',
     'Collider:setSleepingAllowed'
     'Collider:setSleepingAllowed'
   }
   }

+ 33 - 0
api/lovr/physics/Collider/setContinuous.lua

@@ -0,0 +1,33 @@
+return {
+  summary = 'Set whether the Collider uses continuous collision detection.',
+  description = [[
+    Sets whether the Collider uses continuous collision detection.
+
+    Normally on each timestep a Collider will "teleport" to its new position based on its velocity.
+    Usually this works fine, but if a Collider is going really fast relative to its size, then it
+    might miss collisions with objects or pass through walls.  Enabling continuous collision
+    detection means the Collider will check for obstacles along its path before moving to the new
+    location.  This prevents the Collider from going through walls, but reduces performance.  It's
+    usually used for projectiles, which tend to be small and really fast.
+  ]],
+  arguments = {
+    continuous = {
+      type = 'boolean',
+      description = 'Whether the Collider uses continuous collision detection.'
+    }
+  },
+  returns = {},
+  variants = {
+    {
+      arguments = { 'continuous' },
+      returns = {}
+    }
+  },
+  notes = [[
+    The physics engine performs an optimization where continuous collision detection is only used if
+    the Collider is moving faster than 75% of its size.  So it is not necessary to enable and
+    disable continuous collision detection based on how fast the Collider is moving.
+
+    Colliders that are sensors are not able to use continuous collision detection.
+  ]]
+}

+ 1 - 0
api/lovr/physics/Collider/setGravityIgnored.lua

@@ -1,4 +1,5 @@
 return {
 return {
+  deprecated = true,
   summary = 'Set whether the Collider ignores gravity.',
   summary = 'Set whether the Collider ignores gravity.',
   description = 'Sets whether the Collider should ignore gravity.',
   description = 'Sets whether the Collider should ignore gravity.',
   arguments = {
   arguments = {

+ 26 - 0
api/lovr/physics/Collider/setGravityScale.lua

@@ -0,0 +1,26 @@
+return {
+  summary = 'Set the gravity scale of the Collider.',
+  description = [[
+    Sets the gravity scale of the Collider.  This is multiplied with the global gravity from the
+    World, so 1.0 is regular gravity, 0.0 will ignore gravity, etc.
+  ]],
+  arguments = {
+    scale = {
+      type = 'number',
+      description = 'The gravity scale.'
+    }
+  },
+  returns = {},
+  variants = {
+    {
+      arguments = { 'scale' },
+      returns = {}
+    }
+  },
+  related = {
+    'World:getGravity',
+    'World:setGravity',
+    'Collider:getLinearDamping',
+    'Collider:setLinearDamping'
+  }
+}

+ 12 - 5
api/lovr/physics/Collider/setKinematic.lua

@@ -1,10 +1,18 @@
 return {
 return {
   summary = 'Set whether the Collider is kinematic.',
   summary = 'Set whether the Collider is kinematic.',
-  description = 'Sets whether the Collider is kinematic.',
+  description = [[
+    Sets whether the Collider is kinematic.',
+
+    Kinematic colliders behave like they have infinite mass.  They ignore forces applied to them
+    from gravity, joints, and collisions, but they can still move if given a velocity.  Kinematic
+    colliders don't collide with other kinematic colliders.  They're useful for static environment
+    objects in a level, or for objects that have their position managed outside of the physics
+    system like tracked hands.
+  ]],
   arguments = {
   arguments = {
     kinematic = {
     kinematic = {
       type = 'boolean',
       type = 'boolean',
-      description = 'Whether the Collider is kinematic.'
+      description = 'Whether the Collider should be kinematic.'
     }
     }
   },
   },
   returns = {},
   returns = {},
@@ -15,8 +23,7 @@ return {
     }
     }
   },
   },
   notes = [[
   notes = [[
-    Kinematic colliders behave as though they have infinite mass, ignoring external forces like
-    gravity, joints, or collisions (though non-kinematic colliders will collide with them). They can
-    be useful for static objects like floors or walls.
+    If a Collider has a `MeshShape` or a `TerrainShape`, the collider will always be kinematic and
+    this function will do nothing.
   ]]
   ]]
 }
 }

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

@@ -0,0 +1,41 @@
+return {
+  summary = 'Set whether the Collider should be a sensor.',
+  description = [[
+    Sets whether the Collider should be a sensor.  Sensors do not collide with other objects, but
+    they can still sense collisions with the collision callbacks set by `World:setCallbacks`.  Use
+    them to trigger gameplay behavior when an object is inside a region of space.
+  ]],
+  arguments = {
+    sensor = {
+      type = 'boolean',
+      description = 'Whether the Collider should be a sensor.'
+    }
+  },
+  returns = {},
+  variants = {
+    {
+      arguments = { 'sensor' },
+      returns = {}
+    }
+  },
+  notes = [[
+    Sensors are still reported as hits when doing raycasts and other queries.  Use tags to ignore
+    sensors if needed.
+
+    When a World is created, a set of collision tags can be marked as "static", for performance.
+    Sensors do not detect collision with colliders that have a static tag.  Also, if a sensor itself
+    has a static tag, it will not be able to detect collisions with sleeping colliders.  If a
+    Collider enters a static sensor and goes to sleep, the `exit` callback is called and the sensor
+    is no longer able to detect that collider.
+
+    Sensors can not use continuous collision detection.
+
+    Sensors will never go to sleep.
+  ]],
+  related = {
+    'Collider:setKinematic',
+    'Collider:setEnabled',
+    'World:overlapShape',
+    'World:setCallbacks'
+  }
+}

+ 29 - 12
api/lovr/physics/Collider/setSleepingAllowed.lua

@@ -1,8 +1,14 @@
 return {
 return {
   summary = 'Set whether the Collider is allowed to sleep.',
   summary = 'Set whether the Collider is allowed to sleep.',
-  description = 'Sets whether the Collider is allowed to sleep.',
+  description = [[
+    Sets whether the Collider is allowed to automatically go to sleep.
+
+    When enabled, the Collider will go to sleep if it hasn't moved in a while.  The physics engine
+    does not simulate movement for colliders that are asleep, which saves a lot of CPU for a typical
+    physics world where most objects are at rest at any given time.  
+  ]],
   arguments = {
   arguments = {
-    allowed = {
+    sleepy = {
       type = 'boolean',
       type = 'boolean',
       description = 'Whether the Collider can go to sleep.'
       description = 'Whether the Collider can go to sleep.'
     }
     }
@@ -10,24 +16,35 @@ return {
   returns = {},
   returns = {},
   variants = {
   variants = {
     {
     {
-      arguments = { 'allowed' },
+      arguments = { 'sleepy' },
       returns = {}
       returns = {}
     }
     }
   },
   },
   notes = [[
   notes = [[
-    If sleeping is enabled, the simulation will put the Collider to sleep if it hasn't moved in a
-    while. Sleeping colliders don't impact the physics simulation, which makes updates more
-    efficient and improves physics performance.  However, the physics engine isn't perfect at waking
-    up sleeping colliders and this can lead to bugs where colliders don't react to forces or
-    collisions properly.
+    Sleeping is enabled by default.  Sleeping can be disabled globally using the `allowSleep` option
+    in `lovr.physics.newWorld`.
+
+    Colliders can still be put to sleep manually with `Collider:setAwake`, even if automatic
+    sleeping is disabled.
+
+    Sleeping colliders will wake up when:
+
+    - Colliding with a moving collider
+    - Awakened explicitly with `Collider:setAwake`
+    - Changing position `Collider:setPosition` or `Collider:setOrientation`
+    - Changing velocity (to something non-zero)
+    - Applying force, torque, or an impulse
+    - Enabling a joint connected to the sleeping collider
+
+    Notably, the following will not wake up the collider:
 
 
-    It is possible to set the default value for new colliders using `World:setSleepingAllowed`.
+    - Changing its kinematic state with `Collider:setKinematic`
+    - Changing its shape with `Collider:addShape` or `Collider:removeShape`
+    - Disabling or destroying a sleeping collider it is resting on
 
 
-    Colliders can be manually put to sleep or woken up using `Collider:setAwake`.
+    Sensors will never go to sleep.
   ]],
   ]],
   related = {
   related = {
-    'World:isSleepingAllowed',
-    'World:setSleepingAllowed',
     'Collider:isAwake',
     'Collider:isAwake',
     'Collider:setAwake'
     'Collider:setAwake'
   }
   }

+ 0 - 20
api/lovr/physics/Shape/isSensor.lua

@@ -1,20 +0,0 @@
-return {
-  summary = 'Check if the Shape is a sensor.',
-  description = [[
-    Returns whether the Shape is a sensor.  Sensors do not trigger any collision response, but they
-    still report collisions in `World:collide`.
-  ]],
-  arguments = {},
-  returns = {
-    sensor = {
-      type = 'boolean',
-      description = 'Whether the Shape is a sensor.'
-    }
-  },
-  variants = {
-    {
-      arguments = {},
-      returns = { 'sensor' }
-    }
-  }
-}

+ 0 - 21
api/lovr/physics/Shape/setSensor.lua

@@ -1,21 +0,0 @@
-return {
-  summary = 'Set the sensor status for the Shape.',
-  description = [[
-    Sets whether this Shape is a sensor.  When a Shape is a sensor, it will not generate any
-    collision response when it collides with things, but collisions can still be detected with
-    `World:collide` and `World:getContacts`.
-  ]],
-  arguments = {
-    sensor = {
-      type = 'boolean',
-      description = 'Whether the Shape should be a sensor.'
-    }
-  },
-  returns = {},
-  variants = {
-    {
-      arguments = { 'sensor' },
-      returns = {}
-    }
-  }
-}

+ 1 - 1
api/lovr/physics/World/getColliderCount.lua

@@ -1,5 +1,5 @@
 return {
 return {
-  tag = 'colliders'
+  tag = 'colliders',
   summary = 'Get the number of colliders in the world.',
   summary = 'Get the number of colliders in the world.',
   description = [[
   description = [[
     Returns the number of colliders in the world.  This includes sleeping and disabled colliders.
     Returns the number of colliders in the world.  This includes sleeping and disabled colliders.

+ 1 - 1
api/lovr/physics/World/getColliders.lua

@@ -1,5 +1,5 @@
 return {
 return {
-  tag = 'colliders'
+  tag = 'colliders',
   summary = 'Get a list of colliders in the World.',
   summary = 'Get a list of colliders in the World.',
   description = [[
   description = [[
     Returns a list of colliders in the world.  This includes sleeping and disabled colliders.
     Returns a list of colliders in the world.  This includes sleeping and disabled colliders.

+ 1 - 1
api/lovr/physics/World/getJointCount.lua

@@ -1,5 +1,5 @@
 return {
 return {
-  tag = 'joints'
+  tag = 'joints',
   summary = 'Get the number of joints in the world.',
   summary = 'Get the number of joints in the world.',
   description = [[
   description = [[
     Returns the number of joints in the world.  This includes disabled joints.
     Returns the number of joints in the world.  This includes disabled joints.

+ 2 - 2
api/lovr/physics/World/getJoints.lua

@@ -1,12 +1,12 @@
 return {
 return {
-  tag = 'joints'
+  tag = 'joints',
   summary = 'Get a list of joints in the World.',
   summary = 'Get a list of joints in the World.',
   description = [[
   description = [[
     Returns a table with all the joints in the World.  This includes disabled joints.
     Returns a table with all the joints in the World.  This includes disabled joints.
   ]],
   ]],
   arguments = {},
   arguments = {},
   returns = {
   returns = {
-    colliders = {
+    joints = {
       type = 'table',
       type = 'table',
       description = 'The list of `Joint` objects in the World.'
       description = 'The list of `Joint` objects in the World.'
     }
     }