-
Notifications
You must be signed in to change notification settings - Fork 0
CollisionShapes
There are *counts on fingers* eleven different collision shapes available for use int his system. Each is defined by a few simple mathematical properties and has a set of helpful methods to go with them.
Most of the time you probably won't need do do much with the shapes after you create them (except for maybe the ::Set()
method to update its values) but I'll list them for you all the same.
Many of the shapes here are composed in part or in whole by Vectors or matrices.
Parameter | Type | Description |
---|---|---|
position | Vector3 | The 3D position of the point in space |
A single infinitesimal Point. Admittedly this isn't the most useful shape in a 3D collision world, but I included it because you never know when it'll come in handy, and also because describing collisions with the simplest possible 3D shape makes it a bit easier to explain the more complicated ones later.
Parameter | Type | Description |
---|---|---|
position | Vector3 | The 3D position of the sphere in space |
radius | real | The radius of the sphere |
Spheres are like points, but bigger. These are slightly more useful than points in actual games.
Parameter | Type | Description |
---|---|---|
position | Vector3 | The 3D position of the AABB in space |
half_size | Vector3 | The half side length of each dimension of the AABB |
AABBs (Axis-Aligned Bounding Boxes) are boxes with no rotation. Note that the size is defined by the half side length, or otherwise by the distance between the center of the box and the corners.
You can also create an AABB with the helper function NewColAABBFromMinMax
if you'd instead like to define an AABB by its two corner vertices.
AABBs are used in the collision world data structures to partition the world for faster collision detection.
Parameter | Type | Description |
---|---|---|
position | Vector3 | The 3D position of the OBB in space |
size | Vector3 | The half side length of each dimension of the OBB |
orientation | matrix | The orientation of the OBB in space, represented by a rotation matrix |
OBBs (Oriented Bounding Boxes or Oblique Bounding Boxes, depending on who you ask) are boxes with rotation. Most of the geometry in most games (boxes, walls, etc) are going to be OBBs.
AABBs are a special case of an OBB with no rotation, and are therefore somewhat faster to calculate collisions with. If you know you don't need your collision shapes to have rotation, I recommend using those instead.
Neither of these two things sound like real words anymore.
Parameter | Type | Description |
---|---|---|
normal | Vector3 | The surface normal of the plane |
distance | real | The closest distance of the plane from the world origin |
Planes are an infinite sheet in two directions. They're defined by a surface normal and the nearest distance to the world origin.
In almost all cases, this is going to be your floor, or something like a floor, and your surface normal is going to be your up vector with a distance of 0 to the origin.
Planes are also used in camera frustum culling to construct the camera frustum.
Parameter | Type | Description |
---|---|---|
a | Vector3 | The first vertex of the triangle |
b | Vector3 | The second vertex of the triangle |
c | Vector3 | The third vertex of the triangle |
Triangles are shapes defined by three vertices. Among other things, three points are guaranteed to all lie on the same plane, which makes them somewhat convenient for computer graphics.
You won't often use triangles on their own in 3D collision systems, but rather arrays of them to create meshes (see below).
Not to be confused with ColMesh
Parameter | Type | Description |
---|---|---|
triangle_array | array | An array of triangles |
Meshes are arrays of individual triangles which represent a larger object. These can be used to represent complex geometry.
Triangle meshes are sorted into a hierarchy to accelerate collision detection, similar to collision worlds as a whole. Despite this, unlike when it comes to rendering, 3D collision operations on large arrays of triangles isn't very efficient. Most of the time approximating complex shapes with one or more of the other primitives will produce a better result.
Meshes on their own can't have any transform information. Most of the time you'll be more interested in using Transformed Models (see below).
Parameter | Type | Description |
---|---|---|
mesh | ColMesh | The triangle mesh to be represented by the Transformed Model |
position | Vector3 | The 3D position of the Transformed Model in space (optional, defaults to the Zero Vector) |
orientation | matrix | The orientation of the Transformed Model in space (optional, defaults to the identity matrix) |
Parameter | Type | Description |
---|---|---|
triangle_array | array | An array of triangles to be represented by the Transformed Model |
position | Vector3 | The 3D position of the Transformed Model in space (optional, defaults to the Zero Vector) |
orientation | matrix | The orientation of the Transformed Model in space (optional, defaults to the identity matrix) |
Transformed Models are Meshes with a position offset or a rotation in space. They can be constructed by either wrapping an existing Mesh, or with an array of triangles that a new Mesh will be created from. The contents of a Mesh will not be modified, and you can use one Mesh with as many Transformed Models as you want.
Only Translation and Rotation can be applied to a Transformed Model. Uniform scale is possible, but I'm lazy. Non-uniform scale is rather difficult.
If you construct a Transformed Model with an array of Triangles instead of a Mesh, a new Mesh will be created from scratch. This is fairly slow so you should only do this if each Transformed Model's mesh is unique.
Parameter | Type | Description |
---|---|---|
start | Vector3 | The starting point of a line |
end | Vector3 | The end point of a line |
A Line (or a line segment, if you have a math teacher or another annoying pedant breathing down your neck) is the shortest distance between two points.
Lines aren't often used in 3D collision worlds themselves, but they can sometimes be useful to assist in Raycasts or to define the center of a
Parameter | Type | Description |
---|---|---|
line | ColLine | A line which runs through the center of the Capsule |
radius | real | The radius of the Capsule around the central line |
While a sphere is defined by a radius around a single point, a Capsule is defined by a radius around a Line. These are often used in games to represent humanoid characters because they're not as awkwardly wide as spheres but they have a rounded surface which makes sliding around corners easier than it would be with an AABB or an OBB (though I usually use spheres anyway because it makes my life easier).
Parameter | Type | Description |
---|---|---|
origin | Vector3 | The origin point of the ray |
direction | Vector3 | The direction of the ray |
Rays are a type of line which extend infinitely in one direction. These aren't intended to be used directly in a collision world, but rather as a utility for things like bullet hitscan, ball trajectories, screen picking with the mouse, or other such operations. See the section on Raycasting.
All shapes share a few common methods. Most of the time you won't need to call these directly.
Returns: N/A
Resets the properties of the shape. For each shape, the arguments to this method are identical to the constructors. It's important to call this method instead of setting a shape's properties directly since most of them have a few values cached to speed up collision detection computations, which are recalculated when you call this method.
Returns: boolean
Check one shape against another shape. Returns whether or not an overlap was detected.
It's mathematically possible to find an intersection between two Lines (you probably did it in school at least once), but Line::CheckLine()
will always return false because nobody's ever going to use this on purpose and I'm lazy.
It's mathematically possible to calculate if some combination of Meshes and Transformed Models are intersecting, but I can't in good conscience allow anyone to do that so those methods will also always return false.
Returns: boolean
Raycast into the shape. If a hit is detected and a RaycastHitInformation struct is supplied as an argument, information about the raycast hit will be written to the struct. Raycasts against Lines and other Rays will always return false. See Raycasting for more information.
Returns: boolean
Check a generic Collision Object against the shape. The object can represent any other collision shape. See the page about Collision Worlds for more information.
Returns: Vector3
If a collision with a sphere is detected, attempt to calculate the nearest location where it can be displaced to that will end the collision.
Planes will always displace the sphere in front of them, even if the original position of the sphere is behind them.
Undefined will be returned if:
- No collision is detected
- There are multiple equally valid locations where the sphere could be displaced to (eg the sphere is in the exact center of another shape)
Returns: Vector3
Returns the minimum extent of a shape in 3D space. For Transformed Models, this will return the minimum extent of the bounding box, which may not necessarily correspond to any actual geometry. For Planes this is undefined, as Planes are infinite. For Rays this is undefined because I said so.
Returns: Vector3
Returns the maximum extent of a shape in 3D space. The above constraints apply.
Some shapes have a few methods unique to them.
Returns: EFrustumResults
constant
Checks if a Point, Sphere, or AABB is contained within a Frustum. For purposes of speed AABBs are not checked precisely, but rather with their bounding sphere. See Frustum Culling for more information.
Returns: Vector3
Finds the nearest point on (or inside) the shape to the input Vector3.
Returns: { min, max }
Several of the collision detection algorithms make use of the Separated Axis Theorum, which essentially boils down to asking "if you hold these two shapes next to a light bulb, from any angle, can you see light between them?" The GetInterval()
methods are used to finding how far an AABB, OBB, or Triangle extends on any arbitrary axis, which you can then use to test for overlap on.
Returns: array
Return an array of eight Vector3s, each corresponding to one of the corners of the AABB or OBB.
Returns: array
Return an array of twelve ColLines, each corresponding to one of the edges of the AABB or OBB.
Returns: real
Effectively the Dot Product for a Vector3 against a Plane. A point in front of the Plane will return some positive number, a point behind the Plane will return some negative number, and a point lying exactly on the Plane will return exactly zero.
Returns: ColPlane
Return a new plane by dividing the distance from the origin by the magnitude of the surface normal (and normalizing the surface normal). Used by the frustum culling system and probably not something you care much about otherwise.
Returns: Vector3
Returns the surface normal of the triangle.
Returns: ColPlane
Returns the ColPlane that all three vertices lie on.
Returns: Vector3
Returns the barycentric coordinate of a Vector3 on the triangle. A Vector3 located on the first vertex of the triangle will have a barycentric coordinate of (1, 0, 0); a Vector3 located on the second vertex will have a barycentric coordinate of (0, 1, 0); a Vector3 located on the third vertex will have a barycentric coordinate of (0, 0, 1). Vector3s lying inside the triangle will have a barycentric coordinate somewhere in the middle. If all components of a barycentric coordinate are in the range of [0, 1] you know the point is on the triangle.
Returns: matrix
Returns the final transform matrix of a Transformed Model. This is the combination of both the model's orientation and position.
Returns: real
Calculates the length of the line.
Returns: ColLine
Calculates the shortest connecting line between two lines.
Returns: ColLine
Calculates the shortest connecting line between the line and a Ray.