Sometimes there comes a need to detect a collision, when simple raycast is not suitable. For example, when you want to check if camera sphere can fit into that new location, or a car can pass between two trees without hitting them.
To manage such cases, you would want to cast a sphere along the path or some sort of a shape, that would detect the collision. I’ve made a physics extension to do just that:
Example project. (Click to change shapes. An invisible shape is a custom shape - convex triangle. Check example sources for details.)
How to install
No intallation needed. Just download rigidbody-extensions.js
from the example project and drop it anywhere in your project.
How to use
You can refer to example.js
to see how to cast a shape for collision detection.
// Example sphere cast:
// radius - sphere radius
// start - position from where to start the cast
// end - position where the cast should end
var result = this.app.systems.rigidbody.sphereCast(radius, start, end);
// result will contain the sweep test result or null if no collision
Supported shapes
Sphere: .sphereCast(radius, start, end)
Cone: .coneCast(radius, height, start, end)
Box: .boxCast(halfExtents, start, end)
Cylinder: .cylinderCast(halfExtents, start, end)
Capsule: .capsuleCast(radius, height, start, end)
Custom shape: .shapeCast(vertices, start, end)
Advanced use
The .shapeCast()
method shows how to create your own custom convex shape and use it for the sweep test. Here, I provide 3 consecutive vertices, which comprise a triangle shape:
var triangle = new Float32Array([ 1, -1, 0, -1, -1, 0, 0, 1, 0 ]);
result = this.app.systems.rigidbody.shapeCast(triangle, start, end);
All of the mentioned methods for shape casting are simply convenience methods that use one method only.
this.app.systems.rigidbody.convexCast();
Their responsibility is to generate a desired shape and pass it to the .convexCast()
method for sweep test. It requires to be passed a shape, starting position of the sweep and the end position. All other arguments are optional:
@param {Ammo shape} shape - Convex shape used for sweep test.
@param {pc.Vec3} startPos - The world space point where the hit test starts.
@param {pc.Vec3} endPos - The world space point where the test ends.
@param {pc.Quat} [startRot] - Initial rotation of the shape.
@param {pc.Quat} [endRot] - Final rotation of the shape.
@param {number} [allowedPenetration] - CCD allowance margin.
@param {boolean} [findEntity] - Flag to do a separate raycast to return an entity.
Notes
- Some shape methods take an optional
margin
attribute. It is for adjusting the collision shape margin, for example, you can make rounded corners in a box shape. The engine sets a default safe margin value (something like 0.03-0.04). If your shape is very small, you would want to adjust it. - You can optionally specify the initial and final rotations of the shape by providing the related
pc.Quat
quaternions. The extesion will default the rotations of the shape to face towards the end position of the sweep. - The collision detection is performed using the CCD method, which allows you to provide a collision penetration allowance via
allowedPenetration
attribute. If your object is moving at high speed, you would want to adjust this value to avoid passing through an obstacle. Defaults to 0. - By default the result will provide you the point in world space where collision occured, the normal of the surface that was hit and the hit fraction. The hit fraction is basically a normalized value of the sweep path location, where the collision occured. For example, it will be 0.5 if the collision occured in the middle of the sweep path.
- The method allows you to make a separate rraycast test to find the entity at the hit point. You can pass
findEntity
astrue
to include the hit entity into the cast result. Deafults to false, because it is expensive. - Some shape generation methods accept an optional
orientation
axis. You can provide pc.Vec3.RIGHT to generate the shape around the X axis, or pc.Vec3.BACK for Z axis. Defaults to pc.Vec3.UP.