Skip to content
4 changes: 2 additions & 2 deletions en/manual/glossary/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -168,7 +168,7 @@
- Non-physical movement: Moving entities by directly changing their position without physics interactions.
- Physics-based movement: Moving entities using the physics engine to simulate realistic interactions.
- [Physics engine](../physics/index.md): Simulates physical interactions between entities in the scene.
- [Physics queries](../physics/raycasting.md): Raycasts and overlaps to test collisions.
- [Physics queries](../physics/physics-queries/index.md): Raycasts and overlaps to test collisions.
- [Physics update](../physics/physics-update.md): Fixed timestep and update order considerations.
- [Rigid body](../physics/rigid-bodies.md): Dynamic colliders affected by forces (gravity, collisions).
- [Static](../physics/static-colliders.md): Non-moving colliders (terrain, walls) that other objects collide with.
Expand Down Expand Up @@ -210,4 +210,4 @@

- [Enable VR](../virtual-reality/enable-vr.md): Enable VR support for your project.
- [Overlays](../virtual-reality/overlays.md): Display UI or HUDs in VR using overlays.
- [Preview a scene in VR](../virtual-reality/preview-a-scene-in-vr.md): Test your scene with a VR headset.
- [Preview a scene in VR](../virtual-reality/preview-a-scene-in-vr.md): Test your scene with a VR headset.
7 changes: 5 additions & 2 deletions en/manual/physics/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,10 @@ This section explains how physics components work, how to add them to your proje
* [Collider Shapes](collider-shapes.md): Define the geometric shape of yours collidable components
* [Triggers](triggers.md): Use triggers to detect passing objects
* [Constraints](constraints.md): Join physics objects together, constrain them around points
* [Physics Queries](raycasting.md): Operations to find objects in the scene
* [Physics queries](physics-queries/index.md): Operations to find objects in the scene
* [Raycasts](physics-queries/raycasts.md): Retrieving objects from casting a ray
* [Sweepcasts](physics-queries/sweepcasts.md): Retrieving objects from casting a shape
* [Overlaps](physics-queries/overlaps.md): Retrieving objects that are intersecting with a shape
* [Physics Update](physics-update.md): Updating logic alongside physics

### Tutorials
Expand All @@ -34,4 +37,4 @@ This section explains how physics components work, how to add them to your proje
- Stride integrates the open-source [Bepu Physics engine](https://github.com/bepu/bepuphysics2).
- Explore the [official Bepu website](https://www.bepuentertainment.com/)
- Watch demos on the [Bepu YouTube](https://www.youtube.com/@bepu)
- For solutions on mitigating physics jitter, refer to our guide on [Fixing Physics Jitter](fix-physics-jitter.md)
- For solutions on mitigating physics jitter, refer to our guide on [Fixing Physics Jitter](fix-physics-jitter.md)
50 changes: 50 additions & 0 deletions en/manual/physics/physics-queries/index.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
# Physics queries

<span class="badge text-bg-primary">Intermediate</span>
<span class="badge text-bg-success">Programmer</span>

**Physics Queries** are a set of operations to test and retrieve physics object in a given simulation. The most well known form of those queries is the [RayCast](raycasts.md) which traces an invisible line through the scene to find intersecting [Collidables](../colliders.md).

> [!Note]
> Physics queries use **collider shapes** to find objects. They ignore entities that have no Collidable Component attached or no collider shape set, see [Collidables](../colliders.md).

## Query types

* [**Raycast**](raycasts.md) - fires a ray from a point in a direction and retrieves the object(s) it hits.
* [**Sweepcast**](sweepcasts.md) - fires a shape in a direction and retrieves the object(s) it hits.
* [**Overlap**](overlaps.md) - retrieves the objects that overlap an area.

## Querying specific collision masks

[Collidables](../colliders.md) are organized into **layers**, which can be used for filtering collisions in queries.

![Image of the Collision Layer property on a Body component](media/body-component-layer.webp)

By default, every query checks all layers. This can be changed by specifying a **collision mask**.

```csharp
var mask = CollisionMask.Layer3;
var isHit = simulation.RayCast(Vector3.ZERO, -Vector3.UnitY, 3f, out var hit, mask);
```

You can create a mask for multiple layers, using [bitwise and shift operators](https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/operators/bitwise-and-shift-operators).

```csharp
// | combines multiple masks into one
// mask1 contains layer1 and layer2
var mask1 = CollisionMask.Layer1 | CollisionMask.Layer2;

// ^ removes a value from a mask
// mask2 contains every layer except layer3
var mask2 = CollisionMask.Everything ^ CollisionMask.Layer3;

// ~ inverts a mask
// mask3 contains every layer not in mask2 (only layer3)
var mask3 = ~mask2;
```

## In this section

* [Raycasts](raycasts.md)
* [Sweepcasts](sweepcasts.md)
* [Overlaps](overlaps.md)
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
113 changes: 113 additions & 0 deletions en/manual/physics/physics-queries/overlaps.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,113 @@
# Overlap

<span class="badge text-bg-primary">Intermediate</span>
<span class="badge text-bg-success">Programmer</span>

An **overlap** checks for intersecting collisions in the bounds of a shape. In more basic terms, **it checks which colliders are inside or partially inside of a shape**.

## Overlap query

In order to query an **overlap**, use [`Simulation.Overlap`](xref:Stride.BepuPhysics.BepuSimulation.Overlap*).

### Shape

An overlap requires a **shape**, which can be one of: [`Box`](https://docs.bepuphysics.com/api/BepuPhysics.Collidables.Box.html), [`Capsule`](https://docs.bepuphysics.com/api/BepuPhysics.Collidables.Capsule.html), [`ConvexHull`](https://docs.bepuphysics.com/api/BepuPhysics.Collidables.ConvexHull.html), [`Sphere`](https://docs.bepuphysics.com/api/BepuPhysics.Collidables.Sphere.html), [`Triangle`](https://docs.bepuphysics.com/api/BepuPhysics.Collidables.Triangle.html).

### Pose

The **pose** describes how the shape will be positioned in the world.

Creating a new instance of [RigidPose](xref:Stride.BepuPhysics.Definitions.RigidPose) requires two arguments: position and rotation.

If you want to use the position and rotation of an entity in the scene, you can use [`Transform.GetWorldTransform`](xref:Stride.Engine.EntityTransformExtensions.GetWorldTransformation*).

```csharp
Entity.Transform.GetWorldTransformation(out var position, out var rotation, out _);
var pose = new RigidPose(position, rotation);
```

### Collection

The **collection** is used for getting the intersecting [collidables](xref:Stride.BepuPhysics.CollidableComponent) from the overlap.

The most basic collection that you can use is a [list](https://learn.microsoft.com/en-us/dotnet/api/system.collections.generic.list-1).

```csharp
var collection = new List<OverlapInfo>();
```

## Overlap query (with `stackalloc`)

When repeatedly performing an overlap, it has to keep allocating memory on the heap for the results, which puts more strain on the Garbage Collector (meaning more ram usage). A more optimal solution would be to use `stackalloc`.

When using the stack, the method won't require a collection anymore and instead will return an enumerable.

```csharp
public void Overlap()
{
// Allocate a buffer that can hold up to 16 elements
Span<CollidableStack> buffer = stackalloc CollidableStack[16];

// Iterate over all results
foreach (var collidable in simulation.Overlap(shape, pose, buffer))
{
// Handle a successful hit
}
}
```

> [!NOTE]
> **A span has a limited amount of elements it can contain**. If there are more hits than the buffer size, only the closest ones will be returned.

## OverlapInfo query

This query works almost in the same way as the others. The main difference is that it treats each shape of a [compound collider](../collider-shapes.md#compound) separately. This can result in the same [collidables](xref:Stride.BepuPhysics.CollidableComponent) being returned multiple times.

```csharp
public void Overlap()
{
// Allocate a buffer that can hold up to 16 elements
Span<CollidableStack> buffer = stackalloc CollidableStack[16];

// Iterate over all results
foreach (var info in simulation.OverlapInfo(shape, pose, buffer))
{
// Handle a successful hit
}
}
```

## Using a collision mask

Every query has an optional parameter specifying which colliders layers it should be performed on.

For more information on how to use collision masks, visit the [main physics queries page](index.md#querying-specific-collision-masks).

## Examples

Here are a few examples of using **overlaps** in a game.

### Checking if the player is on the ground

This example will perform an overlap using a sphere slightly below the player to check if it's touching the ground.

It's assumed the player is using a capsule for it's collision with the height of `2`. So the overlap needs to be offsetted from the center by `-0.5` in order to perfectly match the bottom of the capsule with the sphere and then by an additional small value of `-0.01` to be able to check the ground.

```csharp
public bool CheckGrounded(BodyComponent body)
{
var sim = body.Simulation;

// Sphere's radius needs to match the capsule's radius
var shape = new Sphere(0.5f);
var pose = new RigidPose(Entity.Transform.WorldMatrix.TranslationVector - 0.51f, Vector3.Zero);

// Checking every layer except the one the player is on
var mask = ~body.CollisionLayer.ToMask();

Stack<CollidableStack> buffer = stackalloc CollidableStack[1];

// If there are any collisions under the player, the player is on the ground
return sim.Overlap(sphere, pose, buffer, mask).Any();
}
```
Loading