A .NET Standard 2.0 library for simple and efficient 3D math that is a feature-rich replacement for System.Numerics https://vimaec.github.io/Math3D
MIT License
This repository is a public mirror of the Math3D code being maintained within the vim-format repository.
Read the API Documentation | Browse the Source | Get the Nuget
Vim.Math3D is a portable, safe, and efficient 3D math library from VIM written in C# targeting .NET Standard 2.0 without any dependencies.
It is intended primarily as a feature rich drop-in replacement for System.Numerics that assures consistent serialization across platforms, enforces immutability, and offers many additional structures and functionality.
Math3D is compatible with Unity and has been used in production on many different platforms including Windows, Android, iOS, WebGL, and Magic Leap.
In rough order, the Math3D design goals are:
VIM is a company that develops high-performance 3D applications for multiple platforms. Our core development language is C#, so we had a need for a robust, efficient, and productive 3D library. We originally started using System.Numerics, but we ran into some problems. The first issue was that with System.Numerics different implementations could have different binary layouts of the structures. For example a Vector3 might be aligned on either 12 or 16 byte boundaries depending on the platform.
Microsoft's recommendations around struct design are to make structs immutable. Oddly enough this is violated by the System.Numerics library.
By opting to make data types immutable by default eliminates large categories of bugs like race conditions, invariant violations after construction. This is another reason we decided to fork the System.Numerics library.
So we decided to start Math3D by forking from the core classes provided in the CoreFX implementation of System.Numerics with additional algorithms and structures taken from MonoGame, an open-source cross platform port of the XNA game development framework.
The following is a list of data structures provided by Vim.Math.
Vector2
- Single precision X, YVector3
- Single precision X, Y, ZVector4
- Single precision X, Y, Z, WDVector2
- Double precision X, YDVector3
- Double precision X, Y, ZDVector4
- Double precision X, Y, Z, WInt2
- Integer X, YInt3
- Integer X, Y, ZInt4
- Integer X, Y, Z, WComplex
- Double precision Imaginary, RealByte2
- Byte X, YByte3
- Byte X, Y, ZByte4
- Byte X, Y, Z, WColorRGB
- Byte representation of color R, G, BColorRGBA
- Byte representation of color with Alpha R, G, B, AColorHDR
- High Defintion Range color representation, 4 floats, R, G, B, AQuaternion
- Single precision quaternion rotation X, Y, Z, WDQuaternion
- Single precision quaternion rotation X, Y, Z, WAxisAngle
- Single precison rotation as Axis (Vector3) and Angle in radiansMatrix4x4
- 4 x 4 Single Precision matrix in Row-Column - corderTransform
- Single precision Position (Vector3) and Orientation (Quaternion)Euler
- Single precision Euler engle rotation as Yaw (Z rotation), Pitch (X rotation), Roll (y rotation)Plane
- Single precision plane stored Normal (Vector3) and D (distance along normal from Origin)DPlane
- Double precision plane stored Normal (Vector3) and D (distance along normal from Origin)Triangle
- Single precision representation of triangle in 3 dimension as 3 Vector3 Points, A, B, and CTriangle2
- Single precision representation of triangle in 3 dimension as 3 Vector3 Points, A, B, and CQuad
- Single precision representation of quadrilateral in 3 dimension as 4 Vector3 Points, A, B, C, and DDQuad
- Double precision representation of quadrilateral in 3 dimension as 4 Vector3 Points, A, B, C, and DLine
- Single precision line segment A and BRay
- Single precision Point and Direction in 3 dimensional spaceDRay
- Double precision Point and Direction in 3 dimensional spaceInterval
- Single precision float interval (float Min, float Max)AABox
- Single precision 3 dimensional axis-aligned bouncing box (Vector3 Min, Vector3 Max)AABox2D
- Single precision 2 dimensional axis-aligned bouncing box (Vector2 Min, Vector2 Max)AABox4D
- Single precision 4 dimensional axis-aligned bouncing box (Vector4 Min, Vector4 Max)DInterval
- Double precision float interval (double Min, double Max)DAABox
- Double precision 3 dimensional axis-aligned bouncing box (DVector3 Min, DVector3 Max)DAABox2D
- Double precision 2 dimensional axis-aligned bouncing box (DVector2 Min, DVector2 Max)DAABox4D
- Double precision 4 dimensional axis-aligned bouncing box (DVector4 Min, DVector4 Max)Sphere
- Bounding sphere (Vector3 Center, float Radius)DSphere
- Double precision bounding spehere (DVector3 Center, double Radius)SphericalCoordinate
- Radius, Azimuth (bearing), and Inclination (elevation angle)PolarCoordinate
- Radius and Azimuth (bearing)LogPolarCoordinate
- Rho (log of radial distance) and AzimuthCylindricalCoordinate
- Radius, Azimuth (bearing) and HeightHorizontalCoordinate
- Azimuth (bearing) and InclinationGeoCoordinate
- Latitude and LongitudeLinearMotion
- Velocity, Acceleration, and Scalar FrictionAngularMotion
- Velocity, Acceleration, and Scalar FrictionMotion
- LinearMotion and AngularMotionIn addition to many specialized functions for the various data types all structs provide the following functionality:
bool Equals(object other)
bool AlmostEquals(T other, float tolerance)
int GetHashCode()
string ToString()
static T Create(...)
Deconstruct()
==
and !=
operator implementationstatic T Zero
propertystatic T MinValue
propertystatic T MaxValue
propertyEvery vector struct also provides the additional functionality:
+
, -
, *
, /
<
, <=
, >=
, >
,Dot(T x)
AlmostZero()
AnyComponentNegative()
MinComponent()
MaxComponent()
SumComponents()
SumSqrComponents()
ProductComponents()
GetComponent(int n)
double MagnitudeSquared()
double Magnitude()
int NumComponents
CompareTo(T x)
Every interval struct contains the following:
T Extent()
Merge()
Intersection()
In addition All of the System.Math
routines are implemented as static extension functions
for float
, double
, Vector2
,Vector3
, Vector4
, DVector2
,DVector3
,
and DVector4
. This provides a convenient fluent syntax on all variables making the Vim.Math3D API
easily discoverable using auto-complete.
Vim.Math3D
leverages the T4 text template engine
to auto-generate efficient boilerplate code for the different types of
structs. This has proven for us to be an effective way to create generic code that is also very efficient for numerical types and
reduce the overhead of maintainance.
Vim.Math3D uses NUnit for the tests, which many were ported from the CoreFX Numerics implementation of System.Numerics. At last measure we have approximately 50% code coverage, with most of the uncovered functions having trivial implementations that are auto-generated using the T4 templating engine.