11/*
2- * Copyright 2019-2024 Diligent Graphics LLC
2+ * Copyright 2019-2025 Diligent Graphics LLC
33 * Copyright 2015-2019 Egor Yusov
44 *
55 * Licensed under the Apache License, Version 2.0 (the "License");
2727
2828#pragma once
2929
30+ // / \file
31+ // / Additional math functions and structures.
32+
3033#include < float.h>
3134#include < vector>
3235#include < type_traits>
@@ -40,6 +43,7 @@ namespace Diligent
4043{
4144
4245// / A plane in 3D space described by the plane equation:
46+ // /
4347// / dot(Normal, Point) + Distance = 0
4448struct Plane3D
4549{
@@ -50,12 +54,13 @@ struct Plane3D
5054 float3 Normal;
5155
5256 // / Distance from the plane to the coordinate system origin along the normal direction:
57+ // /
5358 // / dot(Normal, Point) = -Distance
5459 // /
5560 // /
56- // / O | N
57- // / *<--------|==>
58- // / |
61+ // / O | N
62+ // / *<--------|==>
63+ // / |
5964 // /
6065 // / \note The distance is measured in the same units as the normal vector.
6166 float Distance = 0 ;
@@ -110,16 +115,16 @@ struct ViewFrustumExt : public ViewFrustum
110115 float3 FrustumCorners[8 ];
111116};
112117
113- // For OpenGL, matrix is still considered row-major. The only difference is that
114- // near clip plane is at -1, not 0.
115- //
116- // Note that returned plane normal vectors are not normalized, which does not make a difference
117- // when testing a point against the plane:
118- //
119- // IsPointInsidePlane = dot(Plane.Normal, Point) < Plane.Distance
120- //
121- // However, to use the planes with other distances (e.g. for testing a sphere against the plane),
122- // the normal vectors must be normalized and the distances scaled accordingly.
118+ // / For OpenGL, matrix is still considered row-major. The only difference is that
119+ // / near clip plane is at -1, not 0.
120+ // /
121+ // / Note that returned plane normal vectors are not normalized, which does not make a difference
122+ // / when testing a point against the plane:
123+ // /
124+ // / IsPointInsidePlane = dot(Plane.Normal, Point) < Plane.Distance
125+ // /
126+ // / However, to use the planes with other distances (e.g. for testing a sphere against the plane),
127+ // / the normal vectors must be normalized and the distances scaled accordingly.
123128inline void ExtractViewFrustumPlanesFromMatrix (const float4x4& Matrix, ViewFrustum& Frustum, bool bIsOpenGL)
124129{
125130 // For more details, see Gribb G., Hartmann K., "Fast Extraction of Viewing Frustum Planes from the
@@ -294,40 +299,44 @@ struct OrientedBoundingBox
294299 float HalfExtents[3 ]; // Half extents along each axis
295300};
296301
302+ // / Bounding box visibility
297303enum class BoxVisibility
298304{
299- // Bounding box is guaranteed to be outside the view frustum
300- // .
301- // . ' |
302- // . ' |
303- // | |
304- // . |
305- // ___ ' . |
306- // | | ' .
307- // |___|
308- //
305+ // / Bounding box is guaranteed to be outside the view frustum
306+ // /
307+ // / .
308+ // / . ' |
309+ // / . ' |
310+ // / | |
311+ // / . |
312+ // / ___ ' . |
313+ // / | | ' .
314+ // / |___|
315+ // /
309316 Invisible,
310317
311- // Bounding box intersects the frustum
312- // .
313- // . ' |
314- // . ' |
315- // | |
316- // _.__ |
317- // | '|. |
318- // |____| ' .
319- //
318+ // / Bounding box intersects the frustum
319+ // /
320+ // / .
321+ // / . ' |
322+ // / . ' |
323+ // / | |
324+ // / _.__ |
325+ // / | '|. |
326+ // / |____| ' .
327+ // /
320328 Intersecting,
321329
322- // Bounding box is fully inside the view frustum
323- // .
324- // . ' |
325- // . '___ |
326- // | | | |
327- // . |___| |
328- // ' . |
329- // ' .
330- //
330+ // / Bounding box is fully inside the view frustum
331+ // /
332+ // / .
333+ // / . ' |
334+ // / . '___ |
335+ // / | | | |
336+ // / . |___| |
337+ // / ' . |
338+ // / ' .
339+ // /
331340 FullyVisible
332341};
333342
@@ -356,14 +365,14 @@ inline float3 GetBoxFarthestCorner(const float3& Direction, const BoundBox& Box)
356365// / Tests if the bounding box is fully visible, intersecting or invisible with
357366// / respect to the plane.
358367// /
359- // / \remarks Plane normal doesn't have to be normalized.
360- // / The box is visible when it is in the positive halfspace of the plane.
368+ // / Plane normal doesn't have to be normalized.
369+ // / The box is visible when it is in the positive halfspace of the plane.
361370// /
362- // / Invisible | Visible
363- // / | N
364- // / |===>
365- // / |
366- // / |
371+ // / Invisible | Visible
372+ // / | N
373+ // / |===>
374+ // / |
375+ // / |
367376inline BoxVisibility GetBoxVisibilityAgainstPlane (const Plane3D& Plane, const BoundBox& Box)
368377{
369378 // Calculate the distance from the box center to the plane:
@@ -378,26 +387,26 @@ inline BoxVisibility GetBoxVisibilityAgainstPlane(const Plane3D& Plane, const Bo
378387 // Check if the box is completely outside the plane
379388 if (DistanceToCenter < -ProjHalfLen)
380389 {
381- // / . |
382- // / .' '. | N
383- // / '. .' |===>
384- // / '.' |
385- // / | |
386- // / |<-------|
387- // / Distance
390+ // . |
391+ // .' '. | N
392+ // '. .' |===>
393+ // '.' |
394+ // | |
395+ // |<-------|
396+ // Distance
388397 return BoxVisibility::Invisible;
389398 }
390399
391400 // Check if the box is fully inside the plane
392401 if (DistanceToCenter > ProjHalfLen)
393402 {
394- // / | .
395- // / | N .' '.
396- // / |===> '. .'
397- // / | '.'
398- // / | |
399- // / |----------->|
400- // / Distance
403+ // | .
404+ // | N .' '.
405+ // |===> '. .'
406+ // | '.'
407+ // | |
408+ // |----------->|
409+ // Distance
401410 return BoxVisibility::FullyVisible;
402411 }
403412
@@ -420,26 +429,26 @@ inline BoxVisibility GetBoxVisibilityAgainstPlane(const Plane3D& Plane, const Or
420429 // Check if the box is completely outside the plane
421430 if (Distance < -ProjHalfExtents)
422431 {
423- // / . |
424- // / .' '. | N
425- // / '. .' |===>
426- // / '.' |
427- // / | |
428- // / |<-------|
429- // / Distance
432+ // . |
433+ // .' '. | N
434+ // '. .' |===>
435+ // '.' |
436+ // | |
437+ // |<-------|
438+ // Distance
430439 return BoxVisibility::Invisible;
431440 }
432441
433442 // Check if the box is fully inside the plane
434443 if (Distance > ProjHalfExtents)
435444 {
436- // / | .
437- // / | N .' '.
438- // / |===> '. .'
439- // / | '.'
440- // / | |
441- // / |----------->|
442- // / Distance
445+ // | .
446+ // | N .' '.
447+ // |===> '. .'
448+ // | '.'
449+ // | |
450+ // |----------->|
451+ // Distance
443452 return BoxVisibility::FullyVisible;
444453 }
445454
@@ -703,13 +712,13 @@ T HermiteSpline(T f0, // F(0)
703712 return (2 * x3 - 3 * x2 + 1 ) * f0 + (x3 - 2 * x2 + x) * t0 + (-2 * x3 + 3 * x2) * f1 + (x3 - x2) * t1;
704713}
705714
706- // Returns the minimum bounding sphere of a view frustum
707- inline void GetFrustumMinimumBoundingSphere (float Proj_00, // cot(HorzFOV / 2)
708- float Proj_11, // cot(VertFOV / 2) == proj_00 / AspectRatio
709- float NearPlane, // Near clip plane
710- float FarPlane, // Far clip plane
711- float3& Center, // Sphere center == (0, 0, c)
712- float & Radius // Sphere radius
715+ // / Returns the minimum bounding sphere of a view frustum
716+ inline void GetFrustumMinimumBoundingSphere (float Proj_00, // /< cot(HorzFOV / 2)
717+ float Proj_11, // /< cot(VertFOV / 2) == proj_00 / AspectRatio
718+ float NearPlane, // /< Near clip plane
719+ float FarPlane, // /< Far clip plane
720+ float3& Center, // /< Sphere center == (0, 0, c)
721+ float & Radius // /< Sphere radius
713722)
714723{
715724 // https://lxjk.github.io/2017/04/15/Calculate-Minimal-Bounding-Sphere-of-Frustum.html
@@ -866,25 +875,25 @@ inline float IntersectRayTriangle(const float3& V0,
866875// / for every cell visited. The function should return true to continue
867876// / tracing and false to stop it.
868877// /
869- // / \remarks The algorithm clips the line against the grid boundaries [0 .. i2GridSize.x] x [0 .. i2GridSize.y]
878+ // / The algorithm clips the line against the grid boundaries [0 .. i2GridSize.x] x [0 .. i2GridSize.y]
870879// /
871- // / When one of the end points falls exactly on a vertical cell boundary, cell to the right is enumerated.
872- // / When one of the end points falls exactly on a horizontal cell boundary, cell above is enumerated.
880+ // / When one of the end points falls exactly on a vertical cell boundary, cell to the right is enumerated.
881+ // / When one of the end points falls exactly on a horizontal cell boundary, cell above is enumerated.
873882// /
874883// / For example, for the line below on a 2x2 grid, the algorithm will trace the following cells: (0,0), (0,1), (1,1)
875884// /
876- // / End
877- // / /
878- // / __________ _/________ 2
879- // / | |/ |
880- // / | / |
881- // / | /| |
882- // / |________/_|__________| 1
883- // / | / | |
884- // / | / | |
885- // / | Start | |
886- // / |__________|__________| 0
887- // / 0 1 2
885+ // / End
886+ // / /
887+ // / __________ _/________ 2
888+ // / | |/ |
889+ // / | / |
890+ // / | /| |
891+ // / |________/_|__________| 1
892+ // / | / | |
893+ // / | / | |
894+ // / | Start | |
895+ // / |__________|__________| 0
896+ // / 0 1 2
888897// /
889898template <typename TCallback>
890899void TraceLineThroughGrid (float2 f2Start,
@@ -1057,14 +1066,14 @@ bool IsPointInsideTriangle(const Vector2<T>& V0,
10571066// / the following locations will be enumerated:
10581067// / (1, 1), (2, 1), (3, 1), (1, 2), (2, 2), (1, 3).
10591068// /
1060- // / 3 * *. * *
1061- // / | '.
1062- // / 2 * * *. *
1063- // / | '.
1064- // / 1 * *---*---*
1069+ // / 3 * *. * *
1070+ // / | '.
1071+ // / 2 * * *. *
1072+ // / | '.
1073+ // / 1 * *---*---*
10651074// /
1066- // / 0 * * * *
1067- // / 0 1 2 3
1075+ // / 0 * * * *
1076+ // / 0 1 2 3
10681077// /
10691078// / \tparam [in] T - Vertex component type.
10701079// / \tparam TCallback - Type of the callback function.
@@ -1274,11 +1283,11 @@ class Polygon2DTriangulator
12741283 // /
12751284 // / \return The triangle list.
12761285 // /
1277- // / \remarks The winding order of each triangle is the same as the winding
1278- // / order of the polygon.
1286+ // / The winding order of each triangle is the same as the winding
1287+ // / order of the polygon.
12791288 // /
1280- // / The function does not check if the polygon is simple, e.g.
1281- // / that it does not self-intersect.
1289+ // / The function does not check if the polygon is simple, e.g.
1290+ // / that it does not self-intersect.
12821291 template <typename ComponentType>
12831292 const std::vector<IndexType>& Triangulate (const std::vector<Vector2<ComponentType>>& Polygon)
12841293 {
@@ -1516,6 +1525,7 @@ class Polygon2DTriangulator
15161525
15171526
15181527// / 3D polygon triangulator.
1528+
15191529// / The class extends the Polygon2DTriangulator class to handle simple 3D polygons.
15201530// / It first projects the polygon onto a plane and then triangulates the resulting 2D polygon.
15211531// /
@@ -1527,10 +1537,10 @@ class Polygon3DTriangulator : public Polygon2DTriangulator<typename std::enable_
15271537public:
15281538 // / Triangulates a simple polygon in 3D.
15291539
1530- // / \remarks The function first projects the polygon onto a plane and then
1531- // / triangulates the resulting 2D polygon.
1540+ // / The function first projects the polygon onto a plane and then
1541+ // / triangulates the resulting 2D polygon.
15321542 // /
1533- // / If vertices are not coplanar, the result is undefined.
1543+ // / If vertices are not coplanar, the result is undefined.
15341544 const std::vector<IndexType>& Triangulate (const std::vector<Vector3<ComponentType>>& Polygon)
15351545 {
15361546 this ->m_Triangles .clear ();
0 commit comments