Skip to content

CollisionShapes

Michael edited this page Sep 9, 2023 · 2 revisions

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.

Shape Constructors

new ColPoint(position)

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.

new ColSphere(position, radius)

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.

new ColAABB(position, half_size)

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.

new ColOBB(position, size, orientation)

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.

new ColPlane(normal, distance)

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.

new ColTriangle(a, b, c)

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).

new ColMesh(triangle_array)

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).

new ColTransformedModel(mesh, position*, orientation*)

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)

new ColTransformedModel(triangle_array, position*, orientation*)

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.

new ColLine(start, end)

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

new ColCapsule(line, radius)

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).

new ColRay(start, direction)

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.

Common Methods

All shapes share a few common methods. Most of the time you won't need to call these directly.

::Set(...)

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.

::CheckPoint(point)

::CheckSphere(sphere)

::CheckAABB(aabb)

::CheckOBB(obb)

::CheckPlane(plane)

::CheckTriangle(triangle)

::CheckMesh(mesh)

::CheckTransformedModel(model)

::CheckLine(line)

::CheckCapsule(capsule)

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.

::CheckRay(ray, hit_info*)

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.

::CheckObject(object)

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.

::DisplaceSphere(sphere)

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)

::GetMin()

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.

::GetMax()

Returns: Vector3

Returns the maximum extent of a shape in 3D space. The above constraints apply.

Other Methods

Some shapes have a few methods unique to them.

ColPoint::CheckFrustum(frustum)

ColSphere::CheckFrustum(frustum)

ColAABB::CheckFrustum(frustum)

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.

ColSphere::NearestPoint(vec3)

ColAABB::NearestPoint(vec3)

ColOBB::NearestPoint(vec3)

ColPlane::NearestPoint(vec3)

ColTriangle::NearestPoint(vec3)

ColLine::NearestPoint(vec3)

ColRay::NearestPoint(vec3)

Returns: Vector3

Finds the nearest point on (or inside) the shape to the input Vector3.

ColAABB::GetInterval(axis)

ColOBB::GetInterval(axis)

ColTriangle::GetInterval(axis)

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.

ColAABB::GetVertices()

ColOBB::GetVertices()

Returns: array

Return an array of eight Vector3s, each corresponding to one of the corners of the AABB or OBB.

ColAABB::GetEdges()

ColOBB::GetEdges()

Returns: array

Return an array of twelve ColLines, each corresponding to one of the edges of the AABB or OBB.

ColPlane::PlaneEquation(vec3)

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.

ColPlane::Normalize()

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.

ColTriangle::GetNormal()

Returns: Vector3

Returns the surface normal of the triangle.

ColTriangle::GetPlane()

Returns: ColPlane

Returns the ColPlane that all three vertices lie on.

ColTriangle::Barycentric(vec3)

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.

ColTransformedModel::GetTransformMatrix()

Returns: matrix

Returns the final transform matrix of a Transformed Model. This is the combination of both the model's orientation and position.

ColLine::Length()

Returns: real

Calculates the length of the line.

ColLine::NearestConnectionToLine(line)

Returns: ColLine

Calculates the shortest connecting line between two lines.

ColLine::NearestConnectionToRay(line)

Returns: ColLine

Calculates the shortest connecting line between the line and a Ray.

Clone this wiki locally