Updated doxygen output (#581)

- Upgraded doxyfile to latest format
- Fixed a bunch of warnings and errors in docstrings that doxygen was complaining about
- Added the doxygen-awesome theme to modernize the output
- Removed a duplicate screenshot we'd had in the docs folder
- Moved the RecastDemo screenshot into the Docs/images folder
- Changed the doxygen main page to be the README.md since the dedicated main page file we had was nearly identical but out of date
- Added CONTRIBUTING.md so it's part of the generated doxygen output
- Removed duplicate license file to avoid confusion
- Combined the FAQ with the Recast_api.txt, since the FAQ was essentially just better docs for the members of `rcConfig`
This commit is contained in:
Graham Pentheny 2022-11-22 21:13:38 -08:00 committed by GitHub
parent 53f779fa8d
commit 2b0c244d12
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
30 changed files with 4061 additions and 559 deletions

View File

@ -3,30 +3,23 @@
We'd love for you to contribute to our source code and to make Recast and Detour even better than they are
today! Here are the guidelines we'd like you to follow:
- [Code of Conduct](#coc)
- [Question or Problem?](#question)
- [Issues and Bugs](#issue)
- [Feature Requests](#feature)
- [Submission Guidelines](#submission-guidelines)
- [Git Commit Guidelines](#git-commit-guidelines)
## <a name="coc"></a> Code of Conduct
## Code of Conduct
This project adheres to the [Open Code of Conduct][code-of-conduct].
By participating, you are expected to honor this code.
## <a name="question"></a> Got a Question or Problem?
## Got a Question or Problem?
If you have questions about how to use Recast or Detour, please direct these to the [Google Group][groups]
discussion list. We are also available on [Gitter][gitter].
## <a name="issue"></a> Found an Issue?
## Found an Issue?
If you find a bug in the source code or a mistake in the documentation, you can help us by
submitting an issue to our [GitHub Repository][github]. Even better you can submit a Pull Request
with a fix.
**Please see the Submission Guidelines below**.
## <a name="feature"></a> Want a Feature?
## Want a Feature?
You can request a new feature by submitting an issue to our [GitHub Repository][github]. If you
would like to implement a new feature then consider what kind of change it is:
@ -78,8 +71,7 @@ Before you submit your pull request consider the following guidelines:
```
* Implement your changes, **including appropriate tests if appropriate/possible**.
* Commit your changes using a descriptive commit message that follows our
[commit message conventions](#commit-message-format).
* Commit your changes using a descriptive commit message that follows our commit message conventions (see below).
```shell
git commit -a
@ -108,10 +100,10 @@ Before you submit your pull request consider the following guidelines:
If you have rebased to squash commits together, you will need to force push to update the PR:
```shell
git rebase master -i
git push origin my-fix-branch -f
```
```shell
git rebase master -i
git push origin my-fix-branch -f
```
That's it! Thank you for your contribution!

View File

@ -57,11 +57,13 @@ struct duDebugDraw
/// Submit a vertex
/// @param pos [in] position of the verts.
/// @param color [in] color of the verts.
/// @param uv [in] the uv coordinates of the verts.
virtual void vertex(const float* pos, unsigned int color, const float* uv) = 0;
/// Submit a vertex
/// @param x,y,z [in] position of the verts.
/// @param color [in] color of the verts.
/// @param u,v [in] the uv coordinates of the verts.
virtual void vertex(const float x, const float y, const float z, unsigned int color, const float u, const float v) = 0;
/// End drawing primitives.

View File

@ -37,7 +37,6 @@ feature to find minor members.
/// Used to ignore a function parameter. VS complains about unused parameters
/// and this silences the warning.
/// @param [in] _ Unused parameter
template<class T> void dtIgnoreUnused(const T&) { }
/// Swaps the values of the two parameters.

View File

@ -312,8 +312,8 @@ private:
};
/// Get flags for edge in detail triangle.
/// @param triFlags[in] The flags for the triangle (last component of detail vertices above).
/// @param edgeIndex[in] The index of the first vertex of the edge. For instance, if 0,
/// @param[in] triFlags The flags for the triangle (last component of detail vertices above).
/// @param[in] edgeIndex The index of the first vertex of the edge. For instance, if 0,
/// returns flags for edge AB.
inline int dtGetDetailTriEdgeFlags(unsigned char triFlags, int edgeIndex)
{

View File

@ -175,7 +175,7 @@ public:
dtStatus init(const dtNavMesh* nav, const int maxNodes);
/// @name Standard Pathfinding Functions
// /@{
/// @{
/// Finds a path from the start polygon to the end polygon.
/// @param[in] startRef The refrence id of the start polygon.
@ -396,9 +396,9 @@ public:
/// @param[in] startPos A position within the start polygon representing
/// the start of the ray. [(x, y, z)]
/// @param[in] endPos The position to cast the ray toward. [(x, y, z)]
/// @param[in] filter The polygon filter to apply to the query.
/// @param[out] t The hit parameter. (FLT_MAX if no wall hit.)
/// @param[out] hitNormal The normal of the nearest wall hit. [(x, y, z)]
/// @param[in] filter The polygon filter to apply to the query.
/// @param[out] path The reference ids of the visited polygons. [opt]
/// @param[out] pathCount The number of visited polygons. [opt]
/// @param[in] maxPath The maximum number of polygons the @p path array can hold.
@ -414,7 +414,7 @@ public:
/// the start of the ray. [(x, y, z)]
/// @param[in] endPos The position to cast the ray toward. [(x, y, z)]
/// @param[in] filter The polygon filter to apply to the query.
/// @param[in] flags govern how the raycast behaves. See dtRaycastOptions
/// @param[in] options govern how the raycast behaves. See dtRaycastOptions
/// @param[out] hit Pointer to a raycast hit structure which will be filled by the results.
/// @param[in] prevRef parent of start ref. Used during for cost calculation [opt]
/// @returns The status flags for the query.
@ -465,6 +465,7 @@ public:
/// The location is not exactly constrained by the circle, but it limits the visited polygons.
/// @param[in] startRef The reference id of the polygon where the search starts.
/// @param[in] centerPos The center of the search circle. [(x, y, z)]
/// @param[in] maxRadius The radius of the search circle. [Units: wu]
/// @param[in] filter The polygon filter to apply to the query.
/// @param[in] frand Function returning a random number [0..1).
/// @param[out] randomRef The reference id of the random location.

View File

@ -1,49 +0,0 @@
# Configuring Recast with rcConfig
The following describes best practices for configuring Recast. They're broken down by the fields in `rcConfig` and are ordered by the sequence in which you should consider them.
## Determine Agent Size
First you should decide the size of your agent's logical cylinder. If your game world uses meters as units, a reasonable starting point for a human-sized agent might be a radius of `0.4` and a height of `2.0`.
## cs
The voxelization cell size `cs` defines the voxel size along both axes of the ground plane: x and z in Recast. This value is usually derived from the character radius `r`. A recommended starting value for `cs` is either `r/2` or `r/3`. Smaller values of `cs` will increase rasterization resolution and navmesh detail, but total generation time will increase exponentially. In outdoor environments, `r/2` is often good enough. For indoor scenes with tight spaces you might want the extra precision, so a value of `r/3` or smaller may give better results.
The initial instinct is to reduce this value to something very close to zero to maximize the detail of the generated navmesh. This quickly becomes a case of diminishing returns, however. Beyond a certain point there's usually not much perceptable difference in the generated navmesh, but huge increases in generation time. This hinders your ability to quickly iterate on level designs and provides little benefit. The general recommendation here is to use as large a value for `cs` as you can get away with.
## ch
The voxelization cell height `ch` is defined separately in order to allow greater precision in height tests. A good starting point for `ch` is half the `cs` value. Smaller `ch` values ensure that the navmesh properly connects areas that are only separated by a small curb or ditch. If small holes are generated in your navmesh around where there are discontinuities in height (for example, stairs or curbs), you may want to decrease the cell height value to increase the vertical rasterization precision of Recast.
## walkableHeight
This value defines the height `h` of the agent in voxels. This value should be calculated as `ceil(h / ch)`. Note this is based on `ch` not `cs` since it's a height value.
## walkableClimb
The `walkableClimb` value defines the maximum height of ledges and steps that the agent can walk up. Given a designer-defined `maxClimb` distance in world units, this value should be calculated as `ceil(maxClimb / ch)`. Again, note that this is using `ch` not `cs` because it's a height-based value.
## walkableRadius
The parameter `walkableRadius` defines the agent radius in voxels. Most often, this value should be calculated as `ceil(r/cs)`. Note this is based on `cs` since the agent radius is always parallel to the ground plane.
If the `walkableRadius` value is greater than zero, the edges of the navmesh will be pushed away from all obstacles by this amount.
A non-zero `walkableRadius` allows for much simpler runtime navmesh collision checks. The game only needs to check that the center point of the agent is contained within a navmesh polygon. Without this erosion, runtime navigation checks need to collide the geometric projection onto the navmesh of agent's logical cylinder with the boundary edges of the navmesh polygons.
Navmesh erosion is performed on the voxelized world representation, so some precision can be lost there. This step allows simpler checks at runtime.
If you want to have tight-fitting navmesh, or want to reuse the same navmesh for multiple agents with differing radii, you can use a `walkableRadius` value of zero.
## walkableSlopeAngle
The parameter `walkableSlopeAngle` is to filter out areas of the world where the ground slope would be too steep for an agent to traverse. This value is defined as a maximum angle in degrees that the surface normal of a polgyon can differ from the world's up vector. This value must be within the range `[0, 90]`.
## maxEdgeLen
In certain cases, long outer edges may decrease the quality of the resulting triangulation, creating very long thin triangles. This can sometimes be remedied by limiting the maximum edge length, causing the problematic long edges to be broken up into smaller segments.
The parameter `maxEdgeLen` defines the maximum edge length and is defined in terms of voxels. A good value for `maxEdgeLen` is something like `walkableRadius * 8`. A good way to adjust this value is to first set it really high and see if your data creates long edges. If it does, decrease `maxEdgeLen` until you find the largest value which improves the resulting tesselation.
## maxSimplificationError
When the rasterized areas are converted back to a vectorized representation, the `maxSimplificationError` describes how loosely the simplification is done. The simplification process uses the [RamerDouglas-Peucker algorithm](https://en.wikipedia.org/wiki/RamerDouglasPeucker_algorithm), and this value describes the max deviation in voxels.
Good values for `maxSimplificationError` are in the range `[1.1, 1.5]`. A value of `1.3` is a good starting point and usually yields good results. If the value is less than `1.1`, some sawtoothing starts to appear at the generated edges. If the value is more than `1.5`, the mesh simplification starts to cut some corners it shouldn't.
## minRegionSize
Watershed partitioning is really prone to noise in the input distance field. In order to get nicer areas, the areas are merged and small disconnected areas are removed after the water shed partitioning. The parameter `minRegionSize` describes the minimum isolated region size that is still kept. A region is removed if the number of voxels in the region is less than the square of `minRegionSize`.
## mergeRegionSize
The triangulation process works best with small, localized voxel regions. The parameter `mergeRegionSize` controls the maximum voxel area of a region that is allowed to be merged with another region. If you see small patches missing here and there, you could lower the minRegionSize.

View File

@ -1,27 +0,0 @@
/**
@page License License
<pre>
Copyright (c) 2009-2011 Mikko Mononen memon@inside.org
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
arising from the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it
freely, subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must not
claim that you wrote the original software. If you use this software
in a product, an acknowledgment in the product documentation would be
appreciated but is not required.
2. Altered source versions must be plainly marked as such, and must not be
misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.
</pre>
*/

View File

@ -1,109 +0,0 @@
/// @mainpage Recast Navigation
///
/// @image html recast_intro.png
///
/// <h2>Recast</h2>
///
/// _Recast_ is a state of the art navigation mesh construction toolset for
/// games.
///
/// - It is automatic, which means that you can throw any level
/// geometry at it and you will get a robust mesh out.
/// - It is fast, which means swift turnaround times for level designers.
/// - It is open source, so it comes with full source and you can
/// customize it to your hearts content.
///
/// The latest version can be found on
/// <a href="https://github.com/recastnavigation/recastnavigation">GitHub</a>.
///
/// The _Recast_ process starts with constructing a voxel mold from level
/// geometry and then casting a navigation mesh over it. The process
/// consists of three steps: building the voxel mold, partitioning the
/// mold into simple regions, and triangulating the regions as simple polygons.
///
/// -# The voxel mold is built from the input triangle mesh by
/// rasterizing the triangles into a multi-layer heightfield. Some
/// simple filters are then applied to the mold to prune out locations
/// where the character would not be able to move.
/// -# The walkable areas described by the mold are divided into simple
/// overlayed 2D regions. The resulting regions have only one
/// non-overlapping contour, which simplifies the final step of the
/// process tremendously.
/// -# The navigation polygons are generated from the regions by first
/// tracing the boundaries and then simplifying them. The resulting
/// polygons are finally converted to convex polygons which makes them
/// perfect for pathfinding and spatial reasoning about the level.
///
/// <h2>Detour</h2>
///
/// _Recast_ is accompanied by _Detour_, a path-finding and spatial reasoning
/// toolkit. You can use any navigation mesh with _Detour_, but of course
/// the data generated by _Recast_ fits perfectly.
///
/// _Detour_ offers a simple static navigation mesh that is suitable for
/// many simple cases, as well as a tiled navigation mesh that allows you
/// to add and remove pieces of the mesh. The tiled mesh allows you to
/// create systems where you stream new navigation data in and out as
/// the player progresses the level, or regenerate tiles as the
/// world changes.
///
/// <h2>Recast Demo</h2>
///
/// You can find a comprehensive demo project in the `RecastDemo` folder. It
/// is a kitchen sink demo containing all the major functionality of the library.
/// If you are new to _Recast_ & _Detour_, check out
/// <a href="https://github.com/recastnavigation/recastnavigation/blob/master/RecastDemo/Source/Sample_SoloMesh.cpp">
/// Sample_SoloMesh.cpp</a> to get started with building navmeshes and
/// <a href="https://github.com/recastnavigation/recastnavigation/blob/master/RecastDemo/Source/NavMeshTesterTool.cpp">
/// NavMeshTesterTool.cpp</a> to see how _Detour_ can be used to find paths.
///
/// <h3>Building RecastDemo</h3>
///
/// RecastDemo uses [premake5](http://premake.github.io/) to build platform specific projects.
/// Download it and make sure it's available on your path, or specify the path to it.
///
/// <h4>Linux</h4>
///
/// - Install SDl2 and its dependencies according to your distro's guidelines.
/// - run `premake5 gmake` from the `RecastDemo` folder.
/// - `cd Build/gmake` then `make`
/// - Run `RecastDemo\Bin\RecastDemo`
///
/// <h4>OSX</h4>
///
/// - Grab the latest SDL2 development library dmg from [here](https://www.libsdl.org/download-2.0.php) and place `SDL2.framework` in `/Library/Frameworks/`
/// - Navigate to the `RecastDemo` folder and run `premake5 xcode4`
/// - Open `Build/xcode4/recastnavigation.xcworkspace`
/// - Select the "RecastDemo" project in the left pane, go to the "BuildPhases" tab and expand "Link Binary With Libraries"
/// - Remove the existing entry for SDL2 (it should have a white box icon) and re-add it by hitting the plus, selecting "Add Other", and selecting `/Library/Frameworks/SDL2.framework`. It should now have a suitcase icon.
/// - Set the RecastDemo project as the target and build.
///
/// <h4>Windows</h4>
///
/// - Grab the latest SDL2 development library release from [here](https://www.libsdl.org/download-2.0.php) and unzip it `RecastDemo\Contrib`. Rename the SDL folder such that the path `RecastDemo\Contrib\SDL\lib\x86` is valid.
/// - Run `"premake5" vs2015` from the `RecastDemo` folder
/// - Open the solution, build, and run.
///
/// <h2>Integrating With Your Own Project</h2>
///
/// It is recommended to add the source directories `DebugUtils`, `Detour`,
/// `DetourCrowd`, `DetourTileCache`, and `Recast` into your own project
/// depending on which parts of the project you need. For example your
/// level building tool could include `DebugUtils`, `Recast`, and `Detour`,
/// and your game runtime could just include `Detour`.
///
/// <h2>Contributing</h2>
/// All development is centralized in github. Check out the <a href="https://github.com/recastnavigation/recastnavigation/blob/master/CONTRIBUTING.md">Contributing Guidelines</a> for more information.
///
/// <h2>Discuss</h2>
///
/// - Discuss _Recast_ and _Detour_:
/// <a href="http://groups.google.com/group/recastnavigation">
/// Recast Navigation Group</a>
/// - Development Blog:
/// <a href="http://digestingduck.blogspot.com/">Digesting Duck</a>
///
/// <h2>License</h2>
///
/// _Recast Navigation_ is licensed under the ZLib license.
///

View File

@ -107,7 +107,7 @@
<!-- Layout definition for a file page -->
<file>
<briefdescription visible="Description"/>
<briefdescription visible="yes"/>
<detaileddescription title=""/>
<includes visible="$SHOW_INCLUDE_FILES"/>
<includegraph visible="$INCLUDE_GRAPH"/>

View File

@ -28,9 +28,6 @@ The general life-cycle of the main classes is as follows:
-# Use the object as part of the pipeline.
-# Free the object using the Recast allocator. (E.g. #rcFreeHeightField)
@note This is a summary list of members. Use the index or search
feature to find minor members.
@struct rcConfig
@par
@ -51,6 +48,10 @@ the platform's floating point accuraccy as well as interdependencies between
the values of multiple parameters. See the individual parameter
documentation for details.
@note First you should decide the size of your agent's logical cylinder.
If your game world uses meters as units, a reasonable starting point for
a human-sized agent might be a radius of `0.4` and a height of `2.0`.
@var rcConfig::borderSize
@par
@ -66,7 +67,24 @@ This field is only used when building multi-tile meshes.
@var rcConfig::cs
@par
@p cs and #ch define voxel/grid/cell size. So their values have significant
The voxelization cell size #cs defines the voxel size along both axes of
the ground plane: x and z in Recast. This value is usually derived from the
character radius `r`. A recommended starting value for #cs is either `r/2`
or `r/3`. Smaller values of #cs will increase rasterization resolution and
navmesh detail, but total generation time will increase exponentially. In
outdoor environments, `r/2` is often good enough. For indoor scenes with
tight spaces you might want the extra precision, so a value of `r/3` or
smaller may give better results.
The initial instinct is to reduce this value to something very close to zero
to maximize the detail of the generated navmesh. This quickly becomes a case
of diminishing returns, however. Beyond a certain point there's usually not
much perceptable difference in the generated navmesh, but huge increases in
generation time. This hinders your ability to quickly iterate on level
designs and provides little benefit. The general recommendation here is to
use as large a value for #cs as you can get away with.
#cs and #ch define voxel/grid/cell size. So their values have significant
side effects on all parameters defined in voxel units.
The minimum value for this parameter depends on the platform's floating point
@ -75,7 +93,15 @@ accuracy, with the practical minimum usually around 0.05.
@var rcConfig::ch
@par
#cs and @p ch define voxel/grid/cell size. So their values have significant
The voxelization cell height #ch is defined separately in order to allow for
greater precision in height tests. A good starting point for #ch is half the
#cs value. Smaller #ch values ensure that the navmesh properly connects areas
that are only separated by a small curb or ditch. If small holes are generated
in your navmesh around where there are discontinuities in height (for example,
stairs or curbs), you may want to decrease the cell height value to increase
the vertical rasterization precision of Recast.
#cs and #ch define voxel/grid/cell size. So their values have significant
side effects on all parameters defined in voxel units.
The minimum value for this parameter depends on the platform's floating point
@ -84,44 +110,106 @@ accuracy, with the practical minimum usually around 0.05.
@var rcConfig::walkableSlopeAngle
@par
The parameter #walkableSlopeAngle is to filter out areas of the world where
the ground slope would be too steep for an agent to traverse. This value is
defined as a maximum angle in degrees that the surface normal of a polgyon
can differ from the world's up vector. This value must be within the range
`[0, 90]`.
The practical upper limit for this parameter is usually around 85 degrees.
@var rcConfig::walkableHeight
@par
This value defines the worldspace height `h` of the agent in voxels. Th value
of #walkableHeight should be calculated as `ceil(h / ch)`. Note this is based
on #ch not #cs since it's a height value.
Permits detection of overhangs in the source geometry that make the geometry
below un-walkable. The value is usually set to the maximum agent height.
@var rcConfig::walkableClimb
@par
The #walkableClimb value defines the maximum height of ledges and steps that
the agent can walk up. Given a designer-defined `maxClimb` distance in world
units, the value of #walkableClimb should be calculated as `ceil(maxClimb / ch)`.
Note that this is using #ch not #cs because it's a height-based value.
Allows the mesh to flow over low lying obstructions such as curbs and
up/down stairways. The value is usually set to how far up/down an agent can step.
@var rcConfig::walkableRadius
@par
The parameter #walkableRadius defines the worldspace agent radius `r` in voxels.
Most often, this value of #walkableRadius should be calculated as `ceil(r / cs)`.
Note this is based on #cs since the agent radius is always parallel to the ground
plane.
If the #walkableRadius value is greater than zero, the edges of the navmesh will
be pushed away from all obstacles by this amount.
A non-zero #walkableRadius allows for much simpler runtime navmesh collision checks.
The game only needs to check that the center point of the agent is contained within
a navmesh polygon. Without this erosion, runtime navigation checks need to collide
the geometric projection of the agent's logical cylinder onto the navmesh with the
boundary edges of the navmesh polygons.
In general, this is the closest any part of the final mesh should get to an
obstruction in the source geometry. It is usually set to the maximum
agent radius.
While a value of zero is legal, it is not recommended and can result in
odd edge case issues.
If you want to have tight-fitting navmesh, or want to reuse the same navmesh for
multiple agents with differing radii, you can use a `walkableRadius` value of zero.
Be advised though that you will need to perform your own collisions with the navmesh
edges, and odd edge cases issues in the mesh generation can potentially occur. For
these reasons, specifying a radius of zero is allowed but is not recommended.
@var rcConfig::maxEdgeLen
@par
In certain cases, long outer edges may decrease the quality of the resulting
triangulation, creating very long thin triangles. This can sometimes be
remedied by limiting the maximum edge length, causing the problematic long
edges to be broken up into smaller segments.
The parameter #maxEdgeLen defines the maximum edge length and is defined in
terms of voxels. A good value for #maxEdgeLen is something like
`walkableRadius * 8`. A good way to adjust this value is to first set it really
high and see if your data creates long edges. If it does, decrease #maxEdgeLen
until you find the largest value which improves the resulting tesselation.
Extra vertices will be inserted as needed to keep contour edges below this
length. A value of zero effectively disables this feature.
@var rcConfig::maxSimplificationError
@par
When the rasterized areas are converted back to a vectorized representation,
the #maxSimplificationError describes how loosely the simplification is done.
The simplification process uses the
<a href="https://en.wikipedia.org/wiki/RamerDouglasPeucker_algorithm">RamerDouglas-Peucker algorithm</a>,
and this value describes the max deviation in voxels.
Good values for #maxSimplificationError are in the range `[1.1, 1.5]`.
A value of `1.3` is a good starting point and usually yields good results.
If the value is less than `1.1`, some sawtoothing starts to appear at the
generated edges. If the value is more than `1.5`, the mesh simplification
starts to cut some corners it shouldn't.
The effect of this parameter only applies to the xz-plane.
@var rcConfig::minRegionArea
@par
Watershed partitioning is really prone to noise in the input distance field.
In order to get nicer areas, the areas are merged and small disconnected areas
are removed after the water shed partitioning. The parameter #minRegionArea
describes the minimum isolated region size that is still kept. A region is
removed if the number of voxels in the region is less than the square of
#minRegionArea.
Any regions that are smaller than this area will be marked as unwalkable.
This is useful in removing useless regions that can sometimes form on
geometry such as table tops, box tops, etc.
@ -132,6 +220,13 @@ geometry such as table tops, box tops, etc.
If the mesh data is to be used to construct a Detour navigation mesh, then the upper limit
is limited to <= #DT_VERTS_PER_POLYGON.
@var rcConfig::mergeRegionArea
@par
The triangulation process works best with small, localized voxel regions.
The parameter #mergeRegionArea controls the maximum voxel area of a region
that is allowed to be merged with another region. If you see small patches
missing here and there, you could lower the #minRegionArea value.
@struct rcHeightfield
@par

Binary file not shown.

Before

Width:  |  Height:  |  Size: 370 KiB

View File

Before

Width:  |  Height:  |  Size: 450 KiB

After

Width:  |  Height:  |  Size: 450 KiB

View File

@ -7,11 +7,6 @@ Directory Layout
High level content and format files. (E.g. css, header, footer.)
./Conceptual
Conceptual (non-api) documentation such as overviews, how-to's, etc.
The main index page content is also in this directory.
./Extern
API documentation that is located outside the source files.

View File

@ -0,0 +1,21 @@
MIT License
Copyright (c) 2021 jothepro
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

View File

@ -0,0 +1,124 @@
# Doxygen Awesome
[![GitHub release (latest by date)](https://img.shields.io/github/v/release/jothepro/doxygen-awesome-css)](https://github.com/jothepro/doxygen-awesome-css/releases/latest)
[![GitHub](https://img.shields.io/github/license/jothepro/doxygen-awesome-css)](https://github.com/jothepro/doxygen-awesome-css/blob/main/LICENSE)
![GitHub Repo stars](https://img.shields.io/github/stars/jothepro/doxygen-awesome-css)
<div class="title_screenshot">
![Screenshot of Doxygen Awesome CSS](img/screenshot.png)
</div>
**Doxygen Awesome** is a custom **CSS theme for Doxygen HTML-documentation** with lots of customization parameters.
## Motivation
I really like how the Doxygen HTML-documentation is structured! But IMHO it looks a bit outdated.
This theme is an attempt to update the visuals of Doxygen without changing its overall layout too much.
## Features
- 🌈 Clean, modern design
- 🚀 Heavily customizable by adjusting CSS-variables
- 🧩 No changes to the HTML structure of Doxygen required
- 📱 Improved mobile usability
- 🌘 Dark mode support!
- 🥇 Works best with **doxygen 1.9.1** - **1.9.4**
## Examples
Some websites using this theme:
- [Documentation of this repository](https://jothepro.github.io/doxygen-awesome-css/)
- [wxWidgets](https://docs.wxwidgets.org/3.2/)
- [OpenCV 5.x](https://docs.opencv.org/5.x/)
- [Zephyr](https://docs.zephyrproject.org/latest/doxygen/html/index.html)
- [FELTOR](https://mwiesenberger.github.io/feltor/dg/html/modules.html)
- [Spatial Audio Framework (SAF)](https://leomccormack.github.io/Spatial_Audio_Framework/index.html)
- [libCloudSync](https://jothepro.github.io/libCloudSync/)
- [libsl3](https://a4z.github.io/libsl3/)
## Installation
To use the theme in your documentation, copy the required CSS and JS files from this repository into your project or add the repository as submodule and check out the latest release:
```bash
git submodule add https://github.com/jothepro/doxygen-awesome-css.git
cd doxygen-awesome-css
git checkout v2.1.0
```
All theme files are located in the root of this repository and start with the prefix `doxygen-awesome-`. You may not need all of them. Follow the install instructions to figure out what files are required for your setup.
### Choosing a layout
There is two layout options. Choose one of them and configure Doxygen accordingly:
<div class="darkmode_inverted_image">
![Available theme variants](img/theme-variants.drawio.svg)
</div>
#### Base Theme (1)
Comes with the typical Doxygen titlebar. Optionally the treeview in the sidebar can be enabled.
Required files: `doxygen-awesome.css`
Required `Doxyfile` configuration:
```
GENERATE_TREEVIEW = YES # optional. Also works without treeview
DISABLE_INDEX = NO
FULL_SIDEBAR = NO
HTML_EXTRA_STYLESHEET = doxygen-awesome-css/doxygen-awesome.css
```
#### Sidebar-Only Theme (2)
Hides the top titlebar to give more space to the content. The treeview must be enabled in order for this theme to work.
Required files: `doxygen-awesome.css`, `doxygen-awesome-sidebar-only.css`
Required `Doxyfile` configuration:
```
GENERATE_TREEVIEW = YES # required!
DISABLE_INDEX = NO
FULL_SIDEBAR = NO
HTML_EXTRA_STYLESHEET = doxygen-awesome-css/doxygen-awesome.css \
doxygen-awesome-css/doxygen-awesome-sidebar-only.css
```
**Caution**: This theme is not compatible with the `FULL_SIDEBAR = YES` option provided by Doxygen!
### Further installation instructions:
- [Installing extensions](docs/extensions.md)
- [Customizing the theme (colors, spacing, border-radius, ...)](docs/customization.md)
- [Tips and Tricks for further configuration](docs/tricks.md)
## Browser support
Tested with
- Chrome 104, Chrome 104 for Android, Chrome 103 for iOS
- Safari 15, Safari for iOS 15
- Firefox 103, Firefox 103 for Android, Firefox Daylight 102 for iOS
- Edge 104
The theme does not strive to be backwards compatible to (significantly) older browser versions.
## Credits
- This theme was initially inspired by the [vuepress](https://vuepress.vuejs.org/) static site generator default theme.
- Thank you for all the bug reports, pull requests and inspiring feedback on github!
<span class="next_section_button">
Read Next: [Extensions](docs/extensions.md)
</span>

View File

@ -0,0 +1,157 @@
/**
Doxygen Awesome
https://github.com/jothepro/doxygen-awesome-css
MIT License
Copyright (c) 2021 - 2022 jothepro
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
*/
class DoxygenAwesomeDarkModeToggle extends HTMLElement {
// SVG icons from https://fonts.google.com/icons
// Licensed under the Apache 2.0 license:
// https://www.apache.org/licenses/LICENSE-2.0.html
static lightModeIcon = `<svg xmlns="http://www.w3.org/2000/svg" enable-background="new 0 0 24 24" height="24px" viewBox="0 0 24 24" width="24px" fill="#FCBF00"><rect fill="none" height="24" width="24"/><circle cx="12" cy="12" opacity=".3" r="3"/><path d="M12,9c1.65,0,3,1.35,3,3s-1.35,3-3,3s-3-1.35-3-3S10.35,9,12,9 M12,7c-2.76,0-5,2.24-5,5s2.24,5,5,5s5-2.24,5-5 S14.76,7,12,7L12,7z M2,13l2,0c0.55,0,1-0.45,1-1s-0.45-1-1-1l-2,0c-0.55,0-1,0.45-1,1S1.45,13,2,13z M20,13l2,0c0.55,0,1-0.45,1-1 s-0.45-1-1-1l-2,0c-0.55,0-1,0.45-1,1S19.45,13,20,13z M11,2v2c0,0.55,0.45,1,1,1s1-0.45,1-1V2c0-0.55-0.45-1-1-1S11,1.45,11,2z M11,20v2c0,0.55,0.45,1,1,1s1-0.45,1-1v-2c0-0.55-0.45-1-1-1C11.45,19,11,19.45,11,20z M5.99,4.58c-0.39-0.39-1.03-0.39-1.41,0 c-0.39,0.39-0.39,1.03,0,1.41l1.06,1.06c0.39,0.39,1.03,0.39,1.41,0s0.39-1.03,0-1.41L5.99,4.58z M18.36,16.95 c-0.39-0.39-1.03-0.39-1.41,0c-0.39,0.39-0.39,1.03,0,1.41l1.06,1.06c0.39,0.39,1.03,0.39,1.41,0c0.39-0.39,0.39-1.03,0-1.41 L18.36,16.95z M19.42,5.99c0.39-0.39,0.39-1.03,0-1.41c-0.39-0.39-1.03-0.39-1.41,0l-1.06,1.06c-0.39,0.39-0.39,1.03,0,1.41 s1.03,0.39,1.41,0L19.42,5.99z M7.05,18.36c0.39-0.39,0.39-1.03,0-1.41c-0.39-0.39-1.03-0.39-1.41,0l-1.06,1.06 c-0.39,0.39-0.39,1.03,0,1.41s1.03,0.39,1.41,0L7.05,18.36z"/></svg>`
static darkModeIcon = `<svg xmlns="http://www.w3.org/2000/svg" enable-background="new 0 0 24 24" height="24px" viewBox="0 0 24 24" width="24px" fill="#FE9700"><rect fill="none" height="24" width="24"/><path d="M9.37,5.51C9.19,6.15,9.1,6.82,9.1,7.5c0,4.08,3.32,7.4,7.4,7.4c0.68,0,1.35-0.09,1.99-0.27 C17.45,17.19,14.93,19,12,19c-3.86,0-7-3.14-7-7C5,9.07,6.81,6.55,9.37,5.51z" opacity=".3"/><path d="M9.37,5.51C9.19,6.15,9.1,6.82,9.1,7.5c0,4.08,3.32,7.4,7.4,7.4c0.68,0,1.35-0.09,1.99-0.27C17.45,17.19,14.93,19,12,19 c-3.86,0-7-3.14-7-7C5,9.07,6.81,6.55,9.37,5.51z M12,3c-4.97,0-9,4.03-9,9s4.03,9,9,9s9-4.03,9-9c0-0.46-0.04-0.92-0.1-1.36 c-0.98,1.37-2.58,2.26-4.4,2.26c-2.98,0-5.4-2.42-5.4-5.4c0-1.81,0.89-3.42,2.26-4.4C12.92,3.04,12.46,3,12,3L12,3z"/></svg>`
static title = "Toggle Light/Dark Mode"
static prefersLightModeInDarkModeKey = "prefers-light-mode-in-dark-mode"
static prefersDarkModeInLightModeKey = "prefers-dark-mode-in-light-mode"
static _staticConstructor = function() {
DoxygenAwesomeDarkModeToggle.enableDarkMode(DoxygenAwesomeDarkModeToggle.userPreference)
// Update the color scheme when the browsers preference changes
// without user interaction on the website.
window.matchMedia('(prefers-color-scheme: dark)').addEventListener('change', event => {
DoxygenAwesomeDarkModeToggle.onSystemPreferenceChanged()
})
// Update the color scheme when the tab is made visible again.
// It is possible that the appearance was changed in another tab
// while this tab was in the background.
document.addEventListener("visibilitychange", visibilityState => {
if (document.visibilityState === 'visible') {
DoxygenAwesomeDarkModeToggle.onSystemPreferenceChanged()
}
});
}()
static init() {
$(function() {
$(document).ready(function() {
const toggleButton = document.createElement('doxygen-awesome-dark-mode-toggle')
toggleButton.title = DoxygenAwesomeDarkModeToggle.title
toggleButton.updateIcon()
window.matchMedia('(prefers-color-scheme: dark)').addEventListener('change', event => {
toggleButton.updateIcon()
})
document.addEventListener("visibilitychange", visibilityState => {
if (document.visibilityState === 'visible') {
toggleButton.updateIcon()
}
});
$(document).ready(function(){
document.getElementById("MSearchBox").parentNode.appendChild(toggleButton)
})
$(window).resize(function(){
document.getElementById("MSearchBox").parentNode.appendChild(toggleButton)
})
})
})
}
constructor() {
super();
this.onclick=this.toggleDarkMode
}
/**
* @returns `true` for dark-mode, `false` for light-mode system preference
*/
static get systemPreference() {
return window.matchMedia('(prefers-color-scheme: dark)').matches
}
/**
* @returns `true` for dark-mode, `false` for light-mode user preference
*/
static get userPreference() {
return (!DoxygenAwesomeDarkModeToggle.systemPreference && localStorage.getItem(DoxygenAwesomeDarkModeToggle.prefersDarkModeInLightModeKey)) ||
(DoxygenAwesomeDarkModeToggle.systemPreference && !localStorage.getItem(DoxygenAwesomeDarkModeToggle.prefersLightModeInDarkModeKey))
}
static set userPreference(userPreference) {
DoxygenAwesomeDarkModeToggle.darkModeEnabled = userPreference
if(!userPreference) {
if(DoxygenAwesomeDarkModeToggle.systemPreference) {
localStorage.setItem(DoxygenAwesomeDarkModeToggle.prefersLightModeInDarkModeKey, true)
} else {
localStorage.removeItem(DoxygenAwesomeDarkModeToggle.prefersDarkModeInLightModeKey)
}
} else {
if(!DoxygenAwesomeDarkModeToggle.systemPreference) {
localStorage.setItem(DoxygenAwesomeDarkModeToggle.prefersDarkModeInLightModeKey, true)
} else {
localStorage.removeItem(DoxygenAwesomeDarkModeToggle.prefersLightModeInDarkModeKey)
}
}
DoxygenAwesomeDarkModeToggle.onUserPreferenceChanged()
}
static enableDarkMode(enable) {
if(enable) {
DoxygenAwesomeDarkModeToggle.darkModeEnabled = true
document.documentElement.classList.add("dark-mode")
document.documentElement.classList.remove("light-mode")
} else {
DoxygenAwesomeDarkModeToggle.darkModeEnabled = false
document.documentElement.classList.remove("dark-mode")
document.documentElement.classList.add("light-mode")
}
}
static onSystemPreferenceChanged() {
DoxygenAwesomeDarkModeToggle.darkModeEnabled = DoxygenAwesomeDarkModeToggle.userPreference
DoxygenAwesomeDarkModeToggle.enableDarkMode(DoxygenAwesomeDarkModeToggle.darkModeEnabled)
}
static onUserPreferenceChanged() {
DoxygenAwesomeDarkModeToggle.enableDarkMode(DoxygenAwesomeDarkModeToggle.darkModeEnabled)
}
toggleDarkMode() {
DoxygenAwesomeDarkModeToggle.userPreference = !DoxygenAwesomeDarkModeToggle.userPreference
this.updateIcon()
}
updateIcon() {
if(DoxygenAwesomeDarkModeToggle.darkModeEnabled) {
this.innerHTML = DoxygenAwesomeDarkModeToggle.darkModeIcon
} else {
this.innerHTML = DoxygenAwesomeDarkModeToggle.lightModeIcon
}
}
}
customElements.define("doxygen-awesome-dark-mode-toggle", DoxygenAwesomeDarkModeToggle);

View File

@ -0,0 +1,85 @@
/**
Doxygen Awesome
https://github.com/jothepro/doxygen-awesome-css
MIT License
Copyright (c) 2022 jothepro
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
*/
class DoxygenAwesomeFragmentCopyButton extends HTMLElement {
constructor() {
super();
this.onclick=this.copyContent
}
static title = "Copy to clipboard"
static copyIcon = `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="24" height="24"><path d="M0 0h24v24H0V0z" fill="none"/><path d="M16 1H4c-1.1 0-2 .9-2 2v14h2V3h12V1zm3 4H8c-1.1 0-2 .9-2 2v14c0 1.1.9 2 2 2h11c1.1 0 2-.9 2-2V7c0-1.1-.9-2-2-2zm0 16H8V7h11v14z"/></svg>`
static successIcon = `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="24" height="24"><path d="M0 0h24v24H0V0z" fill="none"/><path d="M9 16.17L4.83 12l-1.42 1.41L9 19 21 7l-1.41-1.41L9 16.17z"/></svg>`
static successDuration = 980
static init() {
$(function() {
$(document).ready(function() {
if(navigator.clipboard) {
const fragments = document.getElementsByClassName("fragment")
for(const fragment of fragments) {
const fragmentWrapper = document.createElement("div")
fragmentWrapper.className = "doxygen-awesome-fragment-wrapper"
const fragmentCopyButton = document.createElement("doxygen-awesome-fragment-copy-button")
fragmentCopyButton.innerHTML = DoxygenAwesomeFragmentCopyButton.copyIcon
fragmentCopyButton.title = DoxygenAwesomeFragmentCopyButton.title
fragment.parentNode.replaceChild(fragmentWrapper, fragment)
fragmentWrapper.appendChild(fragment)
fragmentWrapper.appendChild(fragmentCopyButton)
}
}
})
})
}
copyContent() {
const content = this.previousSibling.cloneNode(true)
// filter out line number from file listings
content.querySelectorAll(".lineno, .ttc").forEach((node) => {
node.remove()
})
let textContent = content.textContent
// remove trailing newlines that appear in file listings
let numberOfTrailingNewlines = 0
while(textContent.charAt(textContent.length - (numberOfTrailingNewlines + 1)) == '\n') {
numberOfTrailingNewlines++;
}
textContent = textContent.substring(0, textContent.length - numberOfTrailingNewlines)
navigator.clipboard.writeText(textContent);
this.classList.add("success")
this.innerHTML = DoxygenAwesomeFragmentCopyButton.successIcon
window.setTimeout(() => {
this.classList.remove("success")
this.innerHTML = DoxygenAwesomeFragmentCopyButton.copyIcon
}, DoxygenAwesomeFragmentCopyButton.successDuration);
}
}
customElements.define("doxygen-awesome-fragment-copy-button", DoxygenAwesomeFragmentCopyButton)

View File

@ -0,0 +1,81 @@
/**
Doxygen Awesome
https://github.com/jothepro/doxygen-awesome-css
MIT License
Copyright (c) 2022 jothepro
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
*/
class DoxygenAwesomeInteractiveToc {
static topOffset = 38
static hideMobileMenu = true
static headers = []
static init() {
window.addEventListener("load", () => {
let toc = document.querySelector(".contents > .toc")
if(toc) {
toc.classList.add("interactive")
if(!DoxygenAwesomeInteractiveToc.hideMobileMenu) {
toc.classList.add("open")
}
document.querySelector(".contents > .toc > h3")?.addEventListener("click", () => {
if(toc.classList.contains("open")) {
toc.classList.remove("open")
} else {
toc.classList.add("open")
}
})
document.querySelectorAll(".contents > .toc > ul a").forEach((node) => {
let id = node.getAttribute("href").substring(1)
DoxygenAwesomeInteractiveToc.headers.push({
node: node,
headerNode: document.getElementById(id)
})
document.getElementById("doc-content")?.addEventListener("scroll", () => {
DoxygenAwesomeInteractiveToc.update()
})
})
DoxygenAwesomeInteractiveToc.update()
}
})
}
static update() {
let active = DoxygenAwesomeInteractiveToc.headers[0]?.node
DoxygenAwesomeInteractiveToc.headers.forEach((header) => {
let position = header.headerNode.getBoundingClientRect().top
header.node.classList.remove("active")
header.node.classList.remove("aboveActive")
if(position < DoxygenAwesomeInteractiveToc.topOffset) {
active = header.node
active?.classList.add("aboveActive")
}
})
active?.classList.add("active")
active?.classList.remove("aboveActive")
}
}

View File

@ -0,0 +1,51 @@
/**
Doxygen Awesome
https://github.com/jothepro/doxygen-awesome-css
MIT License
Copyright (c) 2022 jothepro
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
*/
class DoxygenAwesomeParagraphLink {
// Icon from https://fonts.google.com/icons
// Licensed under the Apache 2.0 license:
// https://www.apache.org/licenses/LICENSE-2.0.html
static icon = `<svg xmlns="http://www.w3.org/2000/svg" height="20px" viewBox="0 0 24 24" width="20px"><path d="M0 0h24v24H0V0z" fill="none"/><path d="M17 7h-4v2h4c1.65 0 3 1.35 3 3s-1.35 3-3 3h-4v2h4c2.76 0 5-2.24 5-5s-2.24-5-5-5zm-6 8H7c-1.65 0-3-1.35-3-3s1.35-3 3-3h4V7H7c-2.76 0-5 2.24-5 5s2.24 5 5 5h4v-2zm-3-4h8v2H8z"/></svg>`
static title = "Permanent Link"
static init() {
$(function() {
$(document).ready(function() {
document.querySelectorAll(".contents a.anchor[id], .contents .groupheader > a[id]").forEach((node) => {
let anchorlink = document.createElement("a")
anchorlink.setAttribute("href", `#${node.getAttribute("id")}`)
anchorlink.setAttribute("title", DoxygenAwesomeParagraphLink.title)
anchorlink.classList.add("anchorlink")
node.classList.add("anchor")
anchorlink.innerHTML = DoxygenAwesomeParagraphLink.icon
node.parentElement.appendChild(anchorlink)
})
})
})
}
}

View File

@ -0,0 +1,40 @@
/**
Doxygen Awesome
https://github.com/jothepro/doxygen-awesome-css
MIT License
Copyright (c) 2021 jothepro
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
*/
@media screen and (min-width: 768px) {
#MSearchBox {
width: calc(var(--side-nav-fixed-width) - calc(2 * var(--spacing-medium)) - var(--searchbar-height) - 1px);
}
#MSearchField {
width: calc(var(--side-nav-fixed-width) - calc(2 * var(--spacing-medium)) - 66px - var(--searchbar-height));
}
}

View File

@ -0,0 +1,115 @@
/**
Doxygen Awesome
https://github.com/jothepro/doxygen-awesome-css
MIT License
Copyright (c) 2021 jothepro
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
*/
html {
/* side nav width. MUST be = `TREEVIEW_WIDTH`.
* Make sure it is wide enough to contain the page title (logo + title + version)
*/
--side-nav-fixed-width: 335px;
--menu-display: none;
--top-height: 120px;
--toc-sticky-top: -25px;
--toc-max-height: calc(100vh - 2 * var(--spacing-medium) - 25px);
}
#projectname {
white-space: nowrap;
}
@media screen and (min-width: 768px) {
html {
--searchbar-background: var(--page-background-color);
}
#side-nav {
min-width: var(--side-nav-fixed-width);
max-width: var(--side-nav-fixed-width);
top: var(--top-height);
overflow: visible;
}
#nav-tree, #side-nav {
height: calc(100vh - var(--top-height)) !important;
}
#nav-tree {
padding: 0;
}
#top {
display: block;
border-bottom: none;
height: var(--top-height);
margin-bottom: calc(0px - var(--top-height));
max-width: var(--side-nav-fixed-width);
overflow: hidden;
background: var(--side-nav-background);
}
#main-nav {
float: left;
padding-right: 0;
}
.ui-resizable-handle {
cursor: default;
width: 1px !important;
box-shadow: 0 calc(-2 * var(--top-height)) 0 0 var(--separator-color);
}
#nav-path {
position: fixed;
right: 0;
left: var(--side-nav-fixed-width);
bottom: 0;
width: auto;
}
#doc-content {
height: calc(100vh - 31px) !important;
padding-bottom: calc(3 * var(--spacing-large));
padding-top: calc(var(--top-height) - 80px);
box-sizing: border-box;
margin-left: var(--side-nav-fixed-width) !important;
}
#MSearchBox {
width: calc(var(--side-nav-fixed-width) - calc(2 * var(--spacing-medium)));
}
#MSearchField {
width: calc(var(--side-nav-fixed-width) - calc(2 * var(--spacing-medium)) - 65px);
}
#MSearchResultsWindow {
left: var(--spacing-medium) !important;
right: auto;
}
}

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,54 @@
html.alternative {
/* primary theme color. This will affect the entire websites color scheme: links, arrows, labels, ... */
--primary-color: #AF7FE4;
--primary-dark-color: #9270E4;
--primary-light-color: #7aabd6;
--primary-lighter-color: #cae1f1;
--primary-lightest-color: #e9f1f8;
/* page base colors */
--page-background-color: white;
--page-foreground-color: #2c3e50;
--page-secondary-foreground-color: #67727e;
--border-radius-large: 22px;
--border-radius-small: 9px;
--border-radius-medium: 14px;
--spacing-small: 8px;
--spacing-medium: 14px;
--spacing-large: 19px;
--top-height: 125px;
--side-nav-background: #324067;
--side-nav-foreground: #F1FDFF;
--header-foreground: var(--side-nav-foreground);
--searchbar-background: var(--side-nav-foreground);
--searchbar-border-radius: var(--border-radius-medium);
--header-background: var(--side-nav-background);
--header-foreground: var(--side-nav-foreground);
--toc-background: rgb(243, 240, 252);
--toc-foreground: var(--page-foreground-color);
}
html.alternative.dark-mode {
color-scheme: dark;
--primary-color: #AF7FE4;
--primary-dark-color: #9270E4;
--primary-light-color: #4779ac;
--primary-lighter-color: #191e21;
--primary-lightest-color: #191a1c;
--page-background-color: #1C1D1F;
--page-foreground-color: #d2dbde;
--page-secondary-foreground-color: #859399;
--separator-color: #3a3246;
--side-nav-background: #171D32;
--side-nav-foreground: #F1FDFF;
--toc-background: #20142C;
--searchbar-background: var(--page-background-color);
}

View File

@ -0,0 +1,101 @@
.github-corner svg {
fill: var(--primary-light-color);
color: var(--page-background-color);
width: 72px;
height: 72px;
}
@media screen and (max-width: 767px) {
.github-corner svg {
width: 50px;
height: 50px;
}
#projectnumber {
margin-right: 22px;
}
}
.alter-theme-button {
display: inline-block;
cursor: pointer;
background: var(--primary-color);
color: var(--page-background-color) !important;
border-radius: var(--border-radius-medium);
padding: var(--spacing-small) var(--spacing-medium);
text-decoration: none;
}
.next_section_button {
display: block;
padding: var(--spacing-large) 0 var(--spacing-small) 0;
color: var(--page-background-color);
user-select: none;
}
.next_section_button::after {
/* clearfix */
content: "";
clear: both;
display: table;
}
.next_section_button a {
overflow: hidden;
float: right;
border: 1px solid var(--separator-color);
padding: var(--spacing-medium) calc(var(--spacing-large) / 2) var(--spacing-medium) var(--spacing-large);
border-radius: var(--border-radius-medium);
color: var(--page-secondary-foreground-color) !important;
text-decoration: none;
background-color: var(--page-background-color);
transition: color .08s ease-in-out, background-color .1s ease-in-out;
}
.next_section_button a:hover {
color: var(--page-foreground-color) !important;
background-color: var(--odd-color);
}
.next_section_button a::after {
content: '〉';
color: var(--page-secondary-foreground-color) !important;
padding-left: var(--spacing-large);
display: inline-block;
transition: color .08s ease-in-out, transform .09s ease-in-out;
}
.next_section_button a:hover::after {
color: var(--page-foreground-color) !important;
transform: translateX(3px);
}
.alter-theme-button:hover {
background: var(--primary-dark-color);
}
html.dark-mode .darkmode_inverted_image img, /* < doxygen 1.9.3 */
html.dark-mode .darkmode_inverted_image object[type="image/svg+xml"] /* doxygen 1.9.3 */ {
filter: brightness(87%) hue-rotate(180deg) invert();
}
.bordered_image {
border-radius: var(--border-radius-small);
border: 1px solid var(--separator-color);
display: inline-block;
overflow: hidden;
}
html.dark-mode .bordered_image img, /* < doxygen 1.9.3 */
html.dark-mode .bordered_image object[type="image/svg+xml"] /* doxygen 1.9.3 */ {
border-radius: var(--border-radius-small);
}
.title_screenshot {
filter: drop-shadow(0px 3px 10px rgba(0,0,0,0.22));
max-width: 500px;
margin: var(--spacing-large) 0;
}
.title_screenshot .caption {
display: none;
}

View File

@ -0,0 +1,88 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>
<meta http-equiv="X-UA-Compatible" content="IE=9"/>
<meta name="generator" content="Doxygen $doxygenversion"/>
<meta name="viewport" content="width=device-width, initial-scale=1"/>
<!-- BEGIN opengraph metadata -->
<meta property="og:title" content="Doxygen Awesome" />
<meta property="og:image" content="https://repository-images.githubusercontent.com/348492097/4f16df80-88fb-11eb-9d31-4015ff22c452" />
<meta property="og:description" content="Custom CSS theme for doxygen html-documentation with lots of customization parameters." />
<meta property="og:url" content="https://jothepro.github.io/doxygen-awesome-css/" />
<!-- END opengraph metadata -->
<!-- BEGIN twitter metadata -->
<meta name="twitter:image:src" content="https://repository-images.githubusercontent.com/348492097/4f16df80-88fb-11eb-9d31-4015ff22c452" />
<meta name="twitter:title" content="Doxygen Awesome" />
<meta name="twitter:description" content="Custom CSS theme for doxygen html-documentation with lots of customization parameters." />
<!-- END twitter metadata -->
<!--BEGIN PROJECT_NAME--><title>$projectname: $title</title><!--END PROJECT_NAME-->
<!--BEGIN !PROJECT_NAME--><title>$title</title><!--END !PROJECT_NAME-->
<link href="$relpath^tabs.css" rel="stylesheet" type="text/css"/>
<link rel="icon" type="image/svg+xml" href="logo.drawio.svg"/>
<script type="text/javascript" src="$relpath^jquery.js"></script>
<script type="text/javascript" src="$relpath^dynsections.js"></script>
<script type="text/javascript" src="$relpath^doxygen-awesome-darkmode-toggle.js"></script>
<script type="text/javascript" src="$relpath^doxygen-awesome-fragment-copy-button.js"></script>
<script type="text/javascript" src="$relpath^doxygen-awesome-paragraph-link.js"></script>
<script type="text/javascript" src="$relpath^doxygen-awesome-interactive-toc.js"></script>
<script type="text/javascript" src="$relpath^toggle-alternative-theme.js"></script>
<script type="text/javascript">
DoxygenAwesomeFragmentCopyButton.init()
DoxygenAwesomeDarkModeToggle.init()
DoxygenAwesomeParagraphLink.init()
DoxygenAwesomeInteractiveToc.init()
</script>
$treeview
$search
$mathjax
<link href="$relpath^$stylesheet" rel="stylesheet" type="text/css" />
$extrastylesheet
</head>
<body>
<!-- https://tholman.com/github-corners/ -->
<a href="https://github.com/jothepro/doxygen-awesome-css" class="github-corner" title="View source on GitHub" target="_blank">
<svg viewBox="0 0 250 250" width="40" height="40" style="position: absolute; top: 0; border: 0; right: 0; z-index: 99;" aria-hidden="true">
<path d="M0,0 L115,115 L130,115 L142,142 L250,250 L250,0 Z"></path><path d="M128.3,109.0 C113.8,99.7 119.0,89.6 119.0,89.6 C122.0,82.7 120.5,78.6 120.5,78.6 C119.2,72.0 123.4,76.3 123.4,76.3 C127.3,80.9 125.5,87.3 125.5,87.3 C122.9,97.6 130.6,101.9 134.4,103.2" fill="currentColor" style="transform-origin: 130px 106px;" class="octo-arm"></path><path d="M115.0,115.0 C114.9,115.1 118.7,116.5 119.8,115.4 L133.7,101.6 C136.9,99.2 139.9,98.4 142.2,98.6 C133.8,88.0 127.5,74.4 143.8,58.0 C148.5,53.4 154.0,51.2 159.7,51.0 C160.3,49.4 163.2,43.6 171.4,40.1 C171.4,40.1 176.1,42.5 178.8,56.2 C183.1,58.6 187.2,61.8 190.9,65.4 C194.5,69.0 197.7,73.2 200.1,77.6 C213.8,80.2 216.3,84.9 216.3,84.9 C212.7,93.1 206.9,96.0 205.4,96.6 C205.1,102.4 203.0,107.8 198.3,112.5 C181.9,128.9 168.3,122.5 157.7,114.1 C157.9,116.9 156.7,120.9 152.7,124.9 L141.0,136.5 C139.8,137.7 141.6,141.9 141.8,141.8 Z" fill="currentColor" class="octo-body"></path></svg></a><style>.github-corner:hover .octo-arm{animation:octocat-wave 560ms ease-in-out}@keyframes octocat-wave{0%,100%{transform:rotate(0)}20%,60%{transform:rotate(-25deg)}40%,80%{transform:rotate(10deg)}}@media (max-width:500px){.github-corner:hover .octo-arm{animation:none}.github-corner .octo-arm{animation:octocat-wave 560ms ease-in-out}}</style>
<div id="top"><!-- do not remove this div, it is closed by doxygen! -->
<!--BEGIN TITLEAREA-->
<div id="titlearea">
<table cellspacing="0" cellpadding="0">
<tbody>
<tr style="height: 56px;">
<!--BEGIN PROJECT_LOGO-->
<td id="projectlogo"><img alt="Logo" src="$relpath^$projectlogo"/></td>
<!--END PROJECT_LOGO-->
<!--BEGIN PROJECT_NAME-->
<td id="projectalign" style="padding-left: 0.5em;">
<div id="projectname">$projectname
<!--BEGIN PROJECT_NUMBER-->&#160;<span id="projectnumber">$projectnumber</span><!--END PROJECT_NUMBER-->
</div>
<!--BEGIN PROJECT_BRIEF--><div id="projectbrief">$projectbrief</div><!--END PROJECT_BRIEF-->
</td>
<!--END PROJECT_NAME-->
<!--BEGIN !PROJECT_NAME-->
<!--BEGIN PROJECT_BRIEF-->
<td style="padding-left: 0.5em;">
<div id="projectbrief">$projectbrief</div>
</td>
<!--END PROJECT_BRIEF-->
<!--END !PROJECT_NAME-->
<!--BEGIN DISABLE_INDEX-->
<!--BEGIN SEARCHENGINE-->
<td>$searchbox</td>
<!--END SEARCHENGINE-->
<!--END DISABLE_INDEX-->
</tr>
</tbody>
</table>
</div>
<!--END TITLEAREA-->
<!-- end header part -->

View File

@ -0,0 +1,12 @@
let original_theme_active = true;
function toggle_alternative_theme() {
if(original_theme_active) {
document.documentElement.classList.add("alternative")
original_theme_active = false;
} else {
document.documentElement.classList.remove("alternative")
original_theme_active = true;
}
}

View File

@ -5,16 +5,16 @@
<ul>
$navpath
&nbsp;&nbsp;<a href="https://github.com/recastnavigation/recastnavigation">Project Home</a>
| <a href="./License.html">Licence: ZLib</a>
| Copyright (c) 2009-2014 Mikko Mononen
| <a href="./License.txt">Licence (ZLib)</a>
| Copyright 2009 Mikko Mononen
</ul>
</div>
<!--END GENERATE_TREEVIEW-->
<!--BEGIN !GENERATE_TREEVIEW-->
<hr class="footer"/><address class="footer"><small>
&nbsp;&nbsp;<a href="https://github.com/recastnavigation/recastnavigation">Project Home</a>
| <a href="./License.html">Licence: ZLib</a>
| Copyright (c) 2009-2014 Mikko Mononen
| <a href="./License.txt">Licence (ZLib)</a>
| Copyright 2009 Mikko Mononen
</small></address>
<!--END !GENERATE_TREEVIEW-->
</body>

808
Doxyfile

File diff suppressed because it is too large Load Diff

View File

@ -5,7 +5,7 @@ Recast & Detour
[![Build](https://github.com/recastnavigation/recastnavigation/actions/workflows/Build.yaml/badge.svg)](https://github.com/recastnavigation/recastnavigation/actions/workflows/Build.yaml)
[![Tests](https://github.com/recastnavigation/recastnavigation/actions/workflows/Tests.yaml/badge.svg)](https://github.com/recastnavigation/recastnavigation/actions/workflows/Tests.yaml)
![screenshot of a navmesh baked with the sample program](/RecastDemo/screenshot.png?raw=true)
![screenshot of a navmesh baked with the sample program](/Docs/Images/screenshot.png)
## Recast

View File

@ -22,6 +22,9 @@
/// The value of PI used by Recast.
static const float RC_PI = 3.14159265f;
/// Used to ignore unused function parameters and silence any compiler warnings.
template<class T> void rcIgnoreUnused(const T&) { }
/// Recast log categories.
/// @see rcContext
enum rcLogCategory
@ -146,23 +149,23 @@ protected:
/// @param[in] category The category of the message.
/// @param[in] msg The formatted message.
/// @param[in] len The length of the formatted message.
virtual void doLog(const rcLogCategory /*category*/, const char* /*msg*/, const int /*len*/) {}
virtual void doLog(const rcLogCategory category, const char* msg, const int len) { rcIgnoreUnused(category); rcIgnoreUnused(msg); rcIgnoreUnused(len); }
/// Clears all timers. (Resets all to unused.)
virtual void doResetTimers() {}
/// Starts the specified performance timer.
/// @param[in] label The category of timer.
virtual void doStartTimer(const rcTimerLabel /*label*/) {}
virtual void doStartTimer(const rcTimerLabel label) { rcIgnoreUnused(label); }
/// Stops the specified performance timer.
/// @param[in] label The category of the timer.
virtual void doStopTimer(const rcTimerLabel /*label*/) {}
virtual void doStopTimer(const rcTimerLabel label) { rcIgnoreUnused(label); }
/// Returns the total accumulated time of the specified performance timer.
/// @param[in] label The category of the timer.
/// @return The accumulated time of the timer, or -1 if timers are disabled or the timer has never been started.
virtual int doGetAccumulatedTime(const rcTimerLabel /*label*/) const { return -1; }
virtual int doGetAccumulatedTime(const rcTimerLabel label) const { rcIgnoreUnused(label); return -1; }
/// True if logging is enabled.
bool m_logEnabled;
@ -593,11 +596,6 @@ static const int RC_NOT_CONNECTED = 0x3f;
/// @name General helper functions
/// @{
/// Used to ignore a function parameter. VS complains about unused parameters
/// and this silences the warning.
/// @param [in] _ Unused parameter
template<class T> void rcIgnoreUnused(const T&) { }
/// Swaps the values of the two parameters.
/// @param[in,out] a Value A
/// @param[in,out] b Value B
@ -994,6 +992,7 @@ void rcMarkConvexPolyArea(rcContext* ctx, const float* verts, const int nverts,
/// @ingroup recast
/// @param[in] verts The vertices of the polygon [Form: (x, y, z) * @p nverts]
/// @param[in] nverts The number of vertices in the polygon.
/// @param[in] offset How much to offset the polygon by. [Units: wu]
/// @param[out] outVerts The offset vertices (should hold up to 2 * @p nverts) [Form: (x, y, z) * return value]
/// @param[in] maxOutVerts The max number of vertices that can be stored to @p outVerts.
/// @returns Number of vertices in the offset polygon or 0 if too few vertices in @p outVerts.