Geometry3D
Аналитическая 3D-геометрия: пересечения, плоскости, контуры и тетраэдры.
Статические CPU-операции над переданными координатами. Не ищут объекты в игровом мире, не учитывают CollisionLayer/CollisionMask и не создают меш или коллизию автоматически. Для всех входов используйте одну систему координат; local/world-преобразования выполните сами. Singleton — заимствованный сервис движка, его не освобождают.
Луч задаётся началом и направлением, отрезок — двумя концами. RayIntersectsTriangle и SegmentIntersectsTriangle возвращают Variant: Vector3 при попадании, Nil при промахе. Не используйте Vector3.Zero как признак промаха: начало координат бывает точкой попадания.
using Variant hit = Geometry3D.RayIntersectsTriangle(
new Vector3(0.25f, 0.25f, 1), new Vector3(0, 0, -1),
Vector3.Zero, new Vector3(1, 0, 0), new Vector3(0, 1, 0));
if (hit.VariantType == Variant.Type.Vector3)
{
Vector3 position = hit.AsVector3();
}SegmentIntersectsSphere/Cylinder/Convex возвращают массив из двух Vector3: [точка, нормаль], а не вход и выход. Пустой массив означает отсутствие принятого пересечения. Это не универсальная проверка нахождения внутри: сфера и convex при старте внутри не возвращают выход, цилиндр может вернуть само начало с нулевой нормалью. Точное касание сферы также исключается. У треугольника начало отрезка исключается с допуском, а конец включается; у луча тоже есть положительный порог параметра.
BuildBoxPlanes принимает половины размеров; BuildCylinderPlanes — полную высоту. BuildCapsulePlanes использует высоту средней цилиндрической части, поэтому общий размер по оси равен height+2*radius. Это отличается от смысла полной высоты в некоторых ресурсах коллизии. По умолчанию ось цилиндра/капсулы Z. Все построители возвращают плоскости, не готовую Mesh/Shape.
GetTriangleBarycentricCoords даёт веса a/b/c проекции на плоскость треугольника: положительные веса не доказывают, что исходная точка лежит в этой плоскости. ClipPolygon сохраняет отрицательное полупространство Plane с граничным допуском; не превращает произвольный неупорядоченный набор точек в корректный полигон. TetrahedralizeDelaunay возвращает индексы четвёрками в исходный массив, не треугольники и не разбиение произвольного меша с полостями.
34 Windows headless-проверки покрыли простые корректные фигуры, попадания/промахи, граничные случаи, форматы результата и overload-массивы/span. Произвольная топология, точность на крайних масштабах, скорость на больших данных, физический мир и рендер не приняты этим набором.
Объявления сверены с C# SDK 1.0.0. Раскройте имя, чтобы увидеть сигнатуры и описание.
Свойства1
SingletonСвойство
public static Geometry3DInstance Singleton { get; }Заимствованный Geometry3DInstance за статическим API. Не вызывайте Free/Dispose; создавать экземпляр для вычислений не нужно.
Методы18
BuildBoxPlanesReckfell.Collections.Array<Plane>
public static Reckfell.Collections.Array<Plane> BuildBoxPlanes(Vector3 extents);Возвращает шесть плоскостей центрированного в нуле axis-aligned box с наружными единичными нормалями. extents — половины размеров, не полные размеры. Внутренняя область normal.Dot(point) ≤ D.
| Имя | Тип | По умолчанию |
|---|---|---|
extents | Vector3 | — |
extentsПоложительные половины размеров X/Y/Z, центр в нуле.
Reckfell.Collections.Array<Plane>Array<Plane> из шести наружных плоскостей; не Shape3D.
BuildCapsulePlanesReckfell.Collections.Array<Plane>
public static Reckfell.Collections.Array<Plane> BuildCapsulePlanes(float radius, float height, int sides, int lats, Vector3.Axis axis = Vector3.Axis.Z);Строит плоскостную аппроксимацию капсулы: sides*(1+2*lats) плоскостей при корректных положительных параметрах. height — длина средней части, крайние торцы ±(height/2+radius). Нормали промежуточных широт получаются нормализованной интерполяцией, не равномерными угловыми шагами.
| Имя | Тип | По умолчанию |
|---|---|---|
radius | float | — |
height | float | — |
sides | int | — |
lats | int | — |
axis | Vector3.Axis | Vector3.Axis.Z |
radiusПоложительный конечный радиус в той же системе единиц, что точки.
heightНеотрицательная длина средней части капсулы; общая высота height+2*radius.
sidesЧисло боковых направлений, задавайте не меньше 3; не точность в мировых единицах.
latsПоложительное число шагов полусфер, влияет на количество плоскостей.
axisОсь X/Y/Z; по умолчанию Z, не произвольный Vector3-направление.
Reckfell.Collections.Array<Plane>Array<Plane> аппроксимации, не меш; возможны повторяющиеся полюсные плоскости.
BuildCylinderPlanesReckfell.Collections.Array<Plane>
public static Reckfell.Collections.Array<Plane> BuildCylinderPlanes(float radius, float height, int sides, Vector3.Axis axis = Vector3.Axis.Z);Возвращает sides боковых плоскостей и две торцевые для приближённого выпуклого цилиндра в начале координат. height — полная высота, торцы ±height/2; axis по умолчанию Z. Это плоскостная аппроксимация, не гладкий CylinderShape3D.
| Имя | Тип | По умолчанию |
|---|---|---|
radius | float | — |
height | float | — |
sides | int | — |
axis | Vector3.Axis | Vector3.Axis.Z |
radiusПоложительный конечный радиус в той же системе единиц, что точки.
heightПоложительная полная высота, торцы на ±height/2.
sidesЧисло боковых направлений, задавайте не меньше 3; не точность в мировых единицах.
axisОсь X/Y/Z; по умолчанию Z, не произвольный Vector3-направление.
Reckfell.Collections.Array<Plane>Array<Plane>: sides боковых и две торцевые плоскости.
ClipPolygon2 перегрузки
public static Vector3[] ClipPolygon(Vector3[] points, Plane plane);Обрезает упорядоченный плоский полигон плоскостью, сохраняя отрицательную сторону и границу с допуском. Рёбра замыкаются последней и первой вершинами; повторять первую в конце не требуется. Не проверяет самопересечения/планарность и не создаёт крышку объёма. Array/span overload имеют одну семантику, вход не меняется.
| Имя | Тип | По умолчанию |
|---|---|---|
points | Vector3[] | — |
plane | Plane | — |
pointsУпорядоченные вершины плоского полигона без обязательного повтора первой; для обычной области минимум 3.
planeНормализованная Plane; сохраняется normal.Dot(point)-D ≤ допуск.
Vector3[]Новый Vector3[] оставшихся вершин с пересечениями; пустой при полном отсечении.
public static Vector3[] ClipPolygon(ReadOnlySpan<Vector3> points, Plane plane);Обрезает упорядоченный плоский полигон плоскостью, сохраняя отрицательную сторону и границу с допуском. Рёбра замыкаются последней и первой вершинами; повторять первую в конце не требуется. Не проверяет самопересечения/планарность и не создаёт крышку объёма. Array/span overload имеют одну семантику, вход не меняется.
| Имя | Тип | По умолчанию |
|---|---|---|
points | ReadOnlySpan<Vector3> | — |
plane | Plane | — |
pointsУпорядоченные вершины плоского полигона без обязательного повтора первой; для обычной области минимум 3.
planeНормализованная Plane; сохраняется normal.Dot(point)-D ≤ допуск.
Vector3[]Новый Vector3[] оставшихся вершин с пересечениями; пустой при полном отсечении.
ComputeConvexMeshPointsVector3[]
public static Vector3[] ComputeConvexMeshPoints(Reckfell.Collections.Array<Plane> planes);Находит пересечения троек плоскостей, не исключённые остальными полупространствами normal.Dot(point) ≤ D с допуском. Не возвращает грани/индексы и не удаляет все дубликаты. Требуются корректные нормализованные наружные плоскости; это не построение convex hull произвольного облака точек.
| Имя | Тип | По умолчанию |
|---|---|---|
planes | Reckfell.Collections.Array<Plane> | — |
planesКорректные нормализованные наружные Plane замкнутой выпуклой области; все значения в одной системе координат.
Vector3[]Массив Vector3 пересечений; может быть пустым или содержать дубликаты, без топологии граней.
GetClosestPointToSegmentVector3
public static Vector3 GetClosestPointToSegment(Vector3 point, Vector3 s1, Vector3 s2);Проецирует point на отрезок и ограничивает результат его концами. Для почти нулевой длины возвращает s1. Расстояние не возвращает: вычислите его от point к результату.
| Имя | Тип | По умолчанию |
|---|---|---|
point | Vector3 | — |
s1 | Vector3 | — |
s2 | Vector3 | — |
pointТочка для проекции в той же системе координат, что s1/s2.
s1Конец соответствующего отрезка; для Uncapped два конца определяют бесконечную прямую.
s2Конец соответствующего отрезка; для Uncapped два конца определяют бесконечную прямую.
Vector3Точка на конечном отрезке, включая его концы.
GetClosestPointToSegmentUncappedVector3
public static Vector3 GetClosestPointToSegmentUncapped(Vector3 point, Vector3 s1, Vector3 s2);Проецирует на бесконечную прямую через s1/s2, без ограничения концами. Для почти совпадающих концов возвращает s1. Не является поиском ближайшей точки поверхности.
| Имя | Тип | По умолчанию |
|---|---|---|
point | Vector3 | — |
s1 | Vector3 | — |
s2 | Vector3 | — |
pointТочка для проекции в той же системе координат, что s1/s2.
s1Конец соответствующего отрезка; для Uncapped два конца определяют бесконечную прямую.
s2Конец соответствующего отрезка; для Uncapped два конца определяют бесконечную прямую.
Vector3Точка на бесконечной прямой; при вырожденности s1.
GetClosestPointsBetweenSegmentsVector3[]
public static Vector3[] GetClosestPointsBetweenSegments(Vector3 p1, Vector3 p2, Vector3 q1, Vector3 q2);Возвращает по одной ближайшей точке каждого конечного отрезка: сначала p1–p2, затем q1–q2. Не пара пересечений и не скалярное расстояние. При параллельных/совпадающих участках ближайшая пара может быть не единственной.
| Имя | Тип | По умолчанию |
|---|---|---|
p1 | Vector3 | — |
p2 | Vector3 | — |
q1 | Vector3 | — |
q2 | Vector3 | — |
p1Конец соответствующего отрезка; для Uncapped два конца определяют бесконечную прямую.
p2Конец соответствующего отрезка; для Uncapped два конца определяют бесконечную прямую.
q1Конец соответствующего отрезка; для Uncapped два конца определяют бесконечную прямую.
q2Конец соответствующего отрезка; для Uncapped два конца определяют бесконечную прямую.
Vector3[]Два Vector3: точка первого отрезка, затем второго.
GetTriangleBarycentricCoordsVector3
public static Vector3 GetTriangleBarycentricCoords(Vector3 point, Vector3 a, Vector3 b, Vector3 c);Вычисляет веса a/b/c проекции point на плоскость треугольника. Не ограничивает веса диапазоном 0…1 и не проверяет расстояние point до плоскости. При точно нулевом знаменателе возвращает Vector3.Zero; вырожденность проверяйте отдельно.
| Имя | Тип | По умолчанию |
|---|---|---|
point | Vector3 | — |
a | Vector3 | — |
b | Vector3 | — |
c | Vector3 | — |
pointПроверяемая точка; для barycentric отдельно проверьте её расстояние до плоскости треугольника.
aВершина a невырожденного треугольника в общей системе координат.
bВершина b невырожденного треугольника в общей системе координат.
cВершина c невырожденного треугольника в общей системе координат.
Vector3Vector3 весов a/b/c; Vector3.Zero также обозначает вырожденный треугольник.
RayIntersectsTriangleVariant
public static Variant RayIntersectsTriangle(Vector3 from, Vector3 dir, Vector3 a, Vector3 b, Vector3 c);Пересекает бесконечный вперёд луч с обеими сторонами треугольника. dir — направление, не конечная точка. Параллельность проверяется с допуском; попадание принимается только при параметре t > 0.00001. Нормализация направления рекомендуется для понятного масштаба допуска. Возвращает Vector3/Nil в Variant.
| Имя | Тип | По умолчанию |
|---|---|---|
from | Vector3 | — |
dir | Vector3 | — |
a | Vector3 | — |
b | Vector3 | — |
c | Vector3 | — |
fromНачальная точка луча/отрезка в общей системе координат.
dirНенулевое направление луча, не точка to; обычно нормализованное.
aВершина a невырожденного треугольника в общей системе координат.
bВершина b невырожденного треугольника в общей системе координат.
cВершина c невырожденного треугольника в общей системе координат.
VariantПринадлежащий вызывающему Variant с Vector3 либо Nil. После проверки типа освободите Variant.
SegmentIntersectsConvex2 перегрузки
public static Vector3[] SegmentIntersectsConvex(Vector3 from, Vector3 to, Reckfell.Collections.Array planes);Ищет вход отрезка в выпуклую область нормализованных наружных Plane: normal.Dot(point) ≤ D. Старт внутри/нулевой отрезок не дают выход. Результат [точка входа, нормаль входной плоскости] либо пустой массив. Для нетипизированного overload элементы всё равно должны быть Plane; адаптер создаёт Array<Plane>.
| Имя | Тип | По умолчанию |
|---|---|---|
from | Vector3 | — |
to | Vector3 | — |
planes | Reckfell.Collections.Array | — |
fromНачальная точка луча/отрезка в общей системе координат.
toКонечная точка отрезка, не направление.
planesКорректные нормализованные наружные Plane замкнутой выпуклой области; все значения в одной системе координат.
Vector3[]Пустой массив либо [точка входа, нормаль плоскости]; выход не возвращается.
public static Vector3[] SegmentIntersectsConvex(Vector3 from, Vector3 to, Reckfell.Collections.Array<Plane> planes);Ищет вход отрезка в выпуклую область нормализованных наружных Plane: normal.Dot(point) ≤ D. Старт внутри/нулевой отрезок не дают выход. Результат [точка входа, нормаль входной плоскости] либо пустой массив. Для нетипизированного overload элементы всё равно должны быть Plane; адаптер создаёт Array<Plane>.
| Имя | Тип | По умолчанию |
|---|---|---|
from | Vector3 | — |
to | Vector3 | — |
planes | Reckfell.Collections.Array<Plane> | — |
fromНачальная точка луча/отрезка в общей системе координат.
toКонечная точка отрезка, не направление.
planesКорректные нормализованные наружные Plane замкнутой выпуклой области; все значения в одной системе координат.
Vector3[]Пустой массив либо [точка входа, нормаль плоскости]; выход не возвращается.
SegmentIntersectsCylinderVector3[]
public static Vector3[] SegmentIntersectsCylinder(Vector3 from, Vector3 to, float height, float radius);Пересекает конечный отрезок с цилиндром в начале координат вдоль Z; height полная, radius поперечный. Ось/позиция не передаются: преобразуйте точки в локальное пространство сами. При старте внутри может вернуть from с нулевой/неповерхностной нормалью; не считайте это выходным пересечением.
| Имя | Тип | По умолчанию |
|---|---|---|
from | Vector3 | — |
to | Vector3 | — |
height | float | — |
radius | float | — |
fromНачальная точка луча/отрезка в общей системе координат.
toКонечная точка отрезка, не направление.
heightПоложительная полная высота, торцы на ±height/2.
radiusПоложительный конечный радиус в той же системе единиц, что точки.
Vector3[]Пустой массив либо [точка, нормаль]; для старта внутри нормаль может быть нулевой.
SegmentIntersectsSphereVector3[]
public static Vector3[] SegmentIntersectsSphere(Vector3 from, Vector3 to, Vector3 spherePosition, float sphereRadius);Ищет переднее входное пересечение отрезка со сферой. Точное касание и почти нулевой отрезок не принимаются. При старте внутри вход позади начала, поэтому выход не возвращается. При успехе массив [точка, наружная нормаль], иначе пустой.
| Имя | Тип | По умолчанию |
|---|---|---|
from | Vector3 | — |
to | Vector3 | — |
spherePosition | Vector3 | — |
sphereRadius | float | — |
fromНачальная точка луча/отрезка в общей системе координат.
toКонечная точка отрезка, не направление.
spherePositionЦентр сферы в той же системе координат, что from/to.
sphereRadiusПоложительный конечный радиус в той же системе единиц, что точки.
Vector3[]Пустой Vector3[] либо ровно [точка, нормаль]; не две точки поверхности.
SegmentIntersectsTriangleVariant
public static Variant SegmentIntersectsTriangle(Vector3 from, Vector3 to, Vector3 a, Vector3 b, Vector3 c);Пересекает конечный отрезок from→to с обеими сторонами треугольника. Параметр должен быть больше CMP_EPSILON и не больше 1: старт исключён, конец допускается. Не выдаёт нормаль, UV или индекс треугольника; результат Vector3/Nil в Variant.
| Имя | Тип | По умолчанию |
|---|---|---|
from | Vector3 | — |
to | Vector3 | — |
a | Vector3 | — |
b | Vector3 | — |
c | Vector3 | — |
fromНачальная точка луча/отрезка в общей системе координат.
toКонечная точка отрезка, не направление.
aВершина a невырожденного треугольника в общей системе координат.
bВершина b невырожденного треугольника в общей системе координат.
cВершина c невырожденного треугольника в общей системе координат.
VariantVariant с точкой Vector3 либо Nil; вызывающий освобождает Variant.
TetrahedralizeDelaunay2 перегрузки
public static int[] TetrahedralizeDelaunay(Vector3[] points);Строит Delaunay-тетраэдры для объёмного облака точек, возвращая исходные индексы группами по четыре. Это не треугольные грани и не constrained-разбиение меша с отверстиями. Нужны конечные невырожденные 3D-данные; порядок/ориентацию индексов и устойчивость на крайних масштабах не считайте контрактом.
| Имя | Тип | По умолчанию |
|---|---|---|
points | Vector3[] | — |
pointsКонечное объёмное облако Vector3, минимум четыре невырожденные точки; не список индексов меша.
int[]int[] индексов в исходный points; каждая четвёрка описывает тетраэдр. Пустой результат не подтверждает корректность входа.
public static int[] TetrahedralizeDelaunay(ReadOnlySpan<Vector3> points);Строит Delaunay-тетраэдры для объёмного облака точек, возвращая исходные индексы группами по четыре. Это не треугольные грани и не constrained-разбиение меша с отверстиями. Нужны конечные невырожденные 3D-данные; порядок/ориентацию индексов и устойчивость на крайних масштабах не считайте контрактом.
| Имя | Тип | По умолчанию |
|---|---|---|
points | ReadOnlySpan<Vector3> | — |
pointsКонечное объёмное облако Vector3, минимум четыре невырожденные точки; не список индексов меша.
int[]int[] индексов в исходный points; каждая четвёрка описывает тетраэдр. Пустой результат не подтверждает корректность входа.