Library / SDK
flexible-collision-library/fcl avatar
flexible-collision-library/fcl

FCL answers one question per call, and the request struct decides which

Flexible Collision Library

1,766 stars449 forksC++NOASSERTION

At a glance

What is it?
FCL is a C++ library for proximity queries between triangle based geometric models: collision, distance, tolerance and continuous collision, with contact normals and points available as an option. It needs Eigen and libccd, the latest release tag is 0.7.0 from 2021, and the last commit is far newer than that tag.
Who is it for?
Adopt FCL if your engine or robotics stack needs collision, distance and continuous collision on meshes and analytic primitives with contact data, and you are willing to build against Eigen and libccd from source. Do not adopt it expecting a versioned dependency you can pin to a recent release, because the newest tag is 0.7.0 from 2021 while the last push was on 2026-10-13, so you are building unreleased master.
Can I use it commercially?
Check first. The repository uses a licence we do not classify automatically, so read its LICENSE file before any commercial use.
Is it still maintained?
Yes. The repository last received commits 2 days ago.
What is it written in?
Mainly C++, according to GitHub's language statistics.

Answers come from the project's GitHub data, last synced on October 22, 2026, and from our analysis. They are not legal advice.

Editorial analysis

Four queries, one pipeline, request in and result out

FCL is a library for performing proximity queries on a pair of geometric models composed of triangles. The README names four kinds.

Collision detection answers whether two models overlap and can optionally return all overlapping triangles. Distance computation returns the minimum distance between a pair of models, meaning the distance between the closest pair of points. Tolerance verification answers whether two models are closer or farther than a tolerance distance. Continuous collision detection answers whether two moving models overlap during the movement and can optionally return the time of contact.

Contact information is orthogonal to all of them: for collision and continuous collision, contact normals and contact points can be returned optionally.

The API shape is uniform across all four. You set a request data structure, run the query function with the request as input, and the result comes back in a result data structure. Collision:

cpp
CollisionRequest request;
CollisionResult result;
collide(o1, o2, request, result);

Distance is the same with `DistanceRequest`, `DistanceResult` and `distance`. Continuous collision adds the goal transforms, since the initial transform already lives in the collision object:

cpp
ContinuousCollisionRequest request;
ContinuousCollisionResult result;
continuousCollide(o1, tf_goal_o1, o2, tf_goal_o2, request, result);

That uniformity is the ergonomic point. Moving from a discrete overlap test to a continuous one, or adding contact normals, is a change of struct rather than a change of mental model.

A BVHModel over triangle soup, and no topology required

The input requirement is deliberately low. The README states that no special topological constraints or adjacency information are required for input models, and all that is necessary is a list of the model's triangles.

The geometry is set through a BVHModel template, whose default template argument is OBBRSS:

cpp
typedef BVHModel<OBBRSSf> Model;
std::shared_ptr<Model> geom = std::make_shared<Model>();
geom->beginModel();
geom->addSubModel(vertices, triangles);
geom->endModel();

That is a triangle soup pushed through a begin, add, end sequence, which is what makes it easy to feed from a mesh importer that gives you disconnected triangles.

The transform is an Eigen rotation and translation pair wrapped in a Transform3f:

cpp
Transform3f pose = Transform3f::Identity();
pose.linear() = R;
pose.translation() = T;

And geometry plus transform combine into the object you pass to a query:

cpp
std::shared_ptr<BVHModel<OBBRSSf>> geom = ...
Transform3f tf = ...
CollisionObjectf* obj = new CollisionObjectf(geom, tf);

Note that the last line allocates with `new` and the README offers no ownership discussion. Whether the query functions take ownership of the `CollisionObjectf` pointer is not stated anywhere in the documentation, and that is a question to answer from the header before you build a scene graph on top of it.

The `f` suffix throughout is the float instantiation, against Eigen's `double` default.

Eleven shape types, and a broad phase manager for the n squared problem

Supported object shapes are box, sphere, ellipsoid, capsule, cone, cylinder, convex, half-space, plane, mesh and octree. The octree support is optional and is represented through the separate octomap library.

Mixing them is the point. A convex hull against a mesh, a sphere against a half-space and a mesh against a mesh are different narrow phase problems, and a library that handles all of them through one request and result type saves you from maintaining a dispatch layer.

Above the pairwise queries sits the broad phase. FCL supports broadphase collision and distance between two groups of objects and can avoid the n squared complexity. For collision it can return all colliding pairs; for distance it can return the pair with the minimum distance.

The structure for that is a CollisionManager, and the implementation is a choice:

cpp
BroadPhaseCollisionManagerf* manager1 = new DynamicAABBTreeCollisionManagerf();

The README says FCL provides various different implementations and that generally the DynamicAABBTreeCollisionManager would provide the best performance. That is a recommendation, not a measurement, and the choice among implementations is one of the knobs to benchmark in your own scene rather than take on faith.

A dynamic AABB tree is the right default for a scene where objects move, since it updates bounds incrementally rather than rebuilding. A static tree is cheaper for a set that never moves.

libccd must come from git, and that one sentence will bite you

The installation section has two prerequisites: Eigen and libccd, the latter for collision checking between convex objects. Then there is the warning that matters.

For libccd, the README says to make sure you compile from the GitHub version instead of the zip file from the webpage, because one bug fixing is not included in the zipped version.

That is the kind of instruction that looks like a footnote and is not. If you install libccd from a distribution package or from the zip, your convex to convex queries run against a version with a known defect, and nothing in FCL will tell you. The failure will be a wrong answer, not a crash.

Two optional libraries are named for optional capabilities: octomap for octree collision, from octomap.github.io, and nothing else.

The build itself is CMake, and the README's command line sequence is the standard out of source build:

cmake
mkdir build
cd build
cmake ..

CMake generates makefiles on Linux and Visual Studio projects on Windows, where you then compile in the IDE. The same CMakeLists is used for both, and the README notes that both makefiles and Microsoft Visual projects can be generated with cmake.

Continuous integration is configured for both platforms, with Travis for Linux and macOS and AppVeyor for Windows, plus Coveralls for coverage.

A 2021 release tag and a 2026 commit

This is the fact to reconcile first.

The recent releases are 0.7.0 on 2021-09-10, v0.6.1 on 2020-02-26 and v0.6.0 on 2020-02-10. The last push was on 2026-10-13. The repository is not archived.

So five years of work exist on the default branch with no release tag attached to them. The homepage is at flexible-collision-library.github.io, the default branch is `master`, and the repository root carries a `CHANGELOG.md` that is the place to see whether the recent work is a stable line or an in progress one.

There is also a `.deprecated/` directory at the root, which is worth a look before you choose a version: it is the conventional place for a project to park an API it is removing, and its presence says the interface has changed at least once.

The packaging story is broader than a plain library. There is a `package.xml` at the root, which is the ROS package manifest, so FCL builds inside a ROS workspace as well as standalone. `CMakeModules/`, `fcl-config.cmake.in` and `fcl.pc.in` give you the standard CMake config and pkg-config files, so `find_package(FCL)` works in a consuming project. `INSTALL`, `CPPLINT.cfg`, `.clang-format`, `.clang-tidy` and `.editorconfig` describe a project with a defined style and installation layout.

The licence is a custom one that GitHub cannot classify, so the LICENSE file at the root is the text to read rather than a label to assume. In practice that matters for a library whose output most downstream consumers will never read.

Where a physics engine, or a narrow phase library of your own, fits instead

The realistic comparison is with a physics engine.

A physics engine such as the ones used for games bundles collision detection with a solver, a rigid body integrator, contacts and constraints. You get a moving, stable simulation out of the box. What you do not get is a clean separation between the geometric query and the simulation step, because the two are wired together.

FCL is only the query. It answers overlap, distance and time of contact and returns contact information. Integrating that with velocity, mass and restitution is your code. For a robotics planner, a collision aware path search or a grasp evaluation, that separation is exactly what you want, because the consumer of the query is not a simulation.

The other comparison is writing the narrow phase yourself against a mesh. For two convex shapes that is tractable. For mesh against mesh, dynamic transforms and continuous motion, it is not, and the value FCL adds is the accumulated set of cases rather than any one algorithm.

The limitation to weigh is precision of the input. Because any triangle soup is acceptable, FCL will happily answer about a mesh with inconsistent winding or duplicated vertices, and it will not be wrong about the geometry it was given. The validation belongs at import time, and FCL is not where it happens.

Editorial conclusion

Adopt FCL if your engine or robotics stack needs collision, distance and continuous collision on meshes and analytic primitives with contact data, and you are willing to build against Eigen and libccd from source. Do not adopt it expecting a versioned dependency you can pin to a recent release, because the newest tag is 0.7.0 from 2021 while the last push was on 2026-10-13, so you are building unreleased master. Verify first that libccd is compiled from the GitHub version rather than the zip from its website, as the README warns a bug fix is missing from the zip, and measure the cost of enabling contact information in your `CollisionRequest`, since the README describes that path as slower than a binary answer.

Frequently asked questions

What does FCL need to build?

Eigen and libccd, with libccd compiled from its GitHub source rather than the zip on its website, because a bug fix is missing from the zip. Octomap is needed for the optional octree support. CMake generates the makefiles or Visual Studio projects.

How do I build FCL with cmake?

Create a build directory, change into it and run `cmake ..`. On Linux you then compile with make; on Windows CMake generates a Visual Studio project to open.

What queries can FCL perform?

Collision detection, distance computation, tolerance verification and continuous collision detection. Contact normals and contact points can be returned optionally for collision and continuous collision.

Which shapes does FCL support?

Box, sphere, ellipsoid, capsule, cone, cylinder, convex, half-space, plane, mesh and octree. The octree type is optional and is represented using the separate octomap library.

How current is the latest FCL release?

The most recent tag is 0.7.0 from 2021-09-10, while the last push to the default branch was on 2026-10-13. The repository is not archived, so there is unreleased work on master that no tag covers.

Official sources

  1. flexible-collision-library/fcl on GitHub
  2. Issues
  3. Project website
  4. README
  5. Releases
Add this badge to your README

If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.

Add this badge to your README

markdown
[![Hysen Labs](https://hysenlabs.com/badge/flexible-collision-library-fcl.svg)](https://hysenlabs.com/projects/flexible-collision-library-fcl)

Was this useful?