/********************************************************************************************** * * raymath v1.5 - Math functions to work with Vector2, Vector3, Matrix and Quaternions * * CONFIGURATION: * * #define RAYMATH_IMPLEMENTATION * Generates the implementation of the library into the included file. * If not defined, the library is in header only mode and can be included in other headers * or source files without problems. But only ONE file should hold the implementation. * * #define RAYMATH_STATIC_INLINE * Define static inline functions code, so #include header suffices for use. * This may use up lots of memory. * * CONVENTIONS: * * - Functions are always self-contained, no function use another raymath function inside, * required code is directly re-implemented inside * - Functions input parameters are always received by value (2 unavoidable exceptions); * - Functions use always a "result" variable for return * - Functions are always defined inline * - Angles are always in radians (DEG2RAD/RAD2DEG macros provided for convenience); * * * LICENSE: zlib/libpng * * Copyright (c); 2015-2023 Ramon Santamaria (@raysan5); * * 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. * **********************************************************************************************/ #ifndef RAYMATH_H #define RAYMATH_H #if defined(RAYMATH_IMPLEMENTATION) && defined(RAYMATH_STATIC_INLINE) #error "Specifying both RAYMATH_IMPLEMENTATION and RAYMATH_STATIC_INLINE is contradictory" #endif // Function specifiers definition #if defined(RAYMATH_IMPLEMENTATION) #if defined(_WIN32); && defined(BUILD_LIBTYPE_SHARED); #define RMAPI __declspec(dllexport); extern inline // We are building raylib as a Win32 shared library (.dll);. #elif defined(_WIN32); && defined(USE_LIBTYPE_SHARED); #define RMAPI __declspec(dllimport); // We are using raylib as a Win32 shared library (.dll); #else #define RMAPI extern inline // Provide external definition #endif #elif defined(RAYMATH_STATIC_INLINE) #define RMAPI static inline // Functions may be inlined, no external out-of-line definition #else #if defined(__TINYC__) #define RMAPI static inline // plain inline not supported by tinycc (See issue #435); #else #define RMAPI inline // Functions may be inlined or external definition used #endif #endif //---------------------------------------------------------------------------------- // Defines and Macros //---------------------------------------------------------------------------------- #ifndef PI #define PI 3.14159265358979323846f #endif #ifndef EPSILON #define EPSILON 0.000001f #endif #ifndef DEG2RAD #define DEG2RAD (PI/180.0f) #endif #ifndef RAD2DEG #define RAD2DEG (180.0f/PI) #endif // Get float vector for Matrix #ifndef MatrixToFloat #define MatrixToFloat(mat) (MatrixToFloatV(mat).v) #endif // Get float vector for Vector3 #ifndef Vector3ToFloat #define Vector3ToFloat(vec) (Vector3ToFloatV(vec).v) #endif //---------------------------------------------------------------------------------- // Types and Structures Definition //---------------------------------------------------------------------------------- #if !defined(RL_VECTOR2_TYPE) // Vector2 type typedef struct Vector2 { float x; float y; } Vector2; #define RL_VECTOR2_TYPE #endif #if !defined(RL_VECTOR3_TYPE) // Vector3 type typedef struct Vector3 { float x; float y; float z; } Vector3; #define RL_VECTOR3_TYPE #endif #if !defined(RL_VECTOR4_TYPE) // Vector4 type typedef struct Vector4 { float x; float y; float z; float w; } Vector4; #define RL_VECTOR4_TYPE #endif #if !defined(RL_QUATERNION_TYPE) // Quaternion type typedef Vector4 Quaternion; #define RL_QUATERNION_TYPE #endif #if !defined(RL_MATRIX_TYPE) // Matrix type (OpenGL style 4x4 - right handed, column major); typedef struct Matrix { float m0, m4, m8, m12; // Matrix first row (4 components); float m1, m5, m9, m13; // Matrix second row (4 components); float m2, m6, m10, m14; // Matrix third row (4 components); float m3, m7, m11, m15; // Matrix fourth row (4 components); } Matrix; #define RL_MATRIX_TYPE #endif // NOTE: Helper types to be used instead of array return types for *ToFloat functions typedef struct float3 { float v[3]; } float3; typedef struct float16 { float v[16]; } float16; #include // Required for: sinf();, cosf();, tan();, atan2f();, sqrtf();, floor();, fminf();, fmaxf();, fabs(); //---------------------------------------------------------------------------------- // Module Functions Definition - Utils math //---------------------------------------------------------------------------------- // Clamp float value RMAPI float Clamp(float value, float min, float max);; // Calculate linear interpolation between two floats RMAPI float Lerp(float start, float end, float amount);; // Normalize input value within input range RMAPI float Normalize(float value, float start, float end);; // Remap input value within input range to output range RMAPI float Remap(float value, float inputStart, float inputEnd, float outputStart, float outputEnd);; // Wrap input value from min to max RMAPI float Wrap(float value, float min, float max);; // Check whether two given floats are almost equal RMAPI int FloatEquals(float x, float y);; //---------------------------------------------------------------------------------- // Module Functions Definition - Vector2 math //---------------------------------------------------------------------------------- // Vector with components value 0.0f RMAPI Vector2 Vector2Zero(void);; // Vector with components value 1.0f RMAPI Vector2 Vector2One(void);; // Add two vectors (v1 + v2); RMAPI Vector2 Vector2Add(Vector2 v1, Vector2 v2);; // Add vector and float value RMAPI Vector2 Vector2AddValue(Vector2 v, float add); // Subtract two vectors (v1 - v2); RMAPI Vector2 Vector2Subtract(Vector2 v1, Vector2 v2); // Subtract vector by float value RMAPI Vector2 Vector2SubtractValue(Vector2 v, float sub); // Calculate vector length RMAPI float Vector2Length(Vector2 v); // Calculate vector square length RMAPI float Vector2LengthSqr(Vector2 v); // Calculate two vectors dot product RMAPI float Vector2DotProduct(Vector2 v1, Vector2 v2); // Calculate distance between two vectors RMAPI float Vector2Distance(Vector2 v1, Vector2 v2); // Calculate square distance between two vectors RMAPI float Vector2DistanceSqr(Vector2 v1, Vector2 v2); // Calculate angle between two vectors // NOTE: Angle is calculated from origin point (0, 0); RMAPI float Vector2Angle(Vector2 v1, Vector2 v2); // Calculate angle defined by a two vectors line // NOTE: Parameters need to be normalized // Current implementation should be aligned with glm::angle RMAPI float Vector2LineAngle(Vector2 start, Vector2 end); // Scale vector (multiply by value); RMAPI Vector2 Vector2Scale(Vector2 v, float scale); // Multiply vector by vector RMAPI Vector2 Vector2Multiply(Vector2 v1, Vector2 v2); // Negate vector RMAPI Vector2 Vector2Negate(Vector2 v); // Divide vector by vector RMAPI Vector2 Vector2Divide(Vector2 v1, Vector2 v2); // Normalize provided vector RMAPI Vector2 Vector2Normalize(Vector2 v); // Transforms a Vector2 by a given Matrix RMAPI Vector2 Vector2Transform(Vector2 v, Matrix mat); // Calculate linear interpolation between two vectors RMAPI Vector2 Vector2Lerp(Vector2 v1, Vector2 v2, float amount); // Calculate reflected vector to normal RMAPI Vector2 Vector2Reflect(Vector2 v, Vector2 normal); // Rotate vector by angle RMAPI Vector2 Vector2Rotate(Vector2 v, float angle); // Move Vector towards target RMAPI Vector2 Vector2MoveTowards(Vector2 v, Vector2 target, float maxDistance); // Invert the given vector RMAPI Vector2 Vector2Invert(Vector2 v); // Clamp the components of the vector between // min and max values specified by the given vectors RMAPI Vector2 Vector2Clamp(Vector2 v, Vector2 min, Vector2 max); // Clamp the magnitude of the vector between two min and max values RMAPI Vector2 Vector2ClampValue(Vector2 v, float min, float max); // Check whether two given vectors are almost equal RMAPI int Vector2Equals(Vector2 p, Vector2 q); //---------------------------------------------------------------------------------- // Module Functions Definition - Vector3 math //---------------------------------------------------------------------------------- // Vector with components value 0.0f RMAPI Vector3 Vector3Zero(void); // Vector with components value 1.0f RMAPI Vector3 Vector3One(void); // Add two vectors RMAPI Vector3 Vector3Add(Vector3 v1, Vector3 v2); // Add vector and float value RMAPI Vector3 Vector3AddValue(Vector3 v, float add); // Subtract two vectors RMAPI Vector3 Vector3Subtract(Vector3 v1, Vector3 v2); // Subtract vector by float value RMAPI Vector3 Vector3SubtractValue(Vector3 v, float sub); // Multiply vector by scalar RMAPI Vector3 Vector3Scale(Vector3 v, float scalar); // Multiply vector by vector RMAPI Vector3 Vector3Multiply(Vector3 v1, Vector3 v2); // Calculate two vectors cross product RMAPI Vector3 Vector3CrossProduct(Vector3 v1, Vector3 v2); // Calculate one vector perpendicular vector RMAPI Vector3 Vector3Perpendicular(Vector3 v); // Calculate vector length RMAPI float Vector3Length(const Vector3 v); // Calculate vector square length RMAPI float Vector3LengthSqr(const Vector3 v); // Calculate two vectors dot product RMAPI float Vector3DotProduct(Vector3 v1, Vector3 v2); // Calculate distance between two vectors RMAPI float Vector3Distance(Vector3 v1, Vector3 v2); // Calculate square distance between two vectors RMAPI float Vector3DistanceSqr(Vector3 v1, Vector3 v2); // Calculate angle between two vectors RMAPI float Vector3Angle(Vector3 v1, Vector3 v2); // Negate provided vector (invert direction); RMAPI Vector3 Vector3Negate(Vector3 v); // Divide vector by vector RMAPI Vector3 Vector3Divide(Vector3 v1, Vector3 v2); // Normalize provided vector RMAPI Vector3 Vector3Normalize(Vector3 v); // Orthonormalize provided vectors // Makes vectors normalized and orthogonal to each other // Gram-Schmidt function implementation RMAPI void Vector3OrthoNormalize(Vector3 *v1, Vector3 *v2); // Transforms a Vector3 by a given Matrix RMAPI Vector3 Vector3Transform(Vector3 v, Matrix mat); // Transform a vector by quaternion rotation RMAPI Vector3 Vector3RotateByQuaternion(Vector3 v, Quaternion q); // Rotates a vector around an axis RMAPI Vector3 Vector3RotateByAxisAngle(Vector3 v, Vector3 axis, float angle); // Calculate linear interpolation between two vectors RMAPI Vector3 Vector3Lerp(Vector3 v1, Vector3 v2, float amount); // Calculate reflected vector to normal RMAPI Vector3 Vector3Reflect(Vector3 v, Vector3 normal); // Get min value for each pair of components RMAPI Vector3 Vector3Min(Vector3 v1, Vector3 v2); // Get max value for each pair of components RMAPI Vector3 Vector3Max(Vector3 v1, Vector3 v2); // Compute barycenter coordinates (u, v, w); for point p with respect to triangle (a, b, c); // NOTE: Assumes P is on the plane of the triangle RMAPI Vector3 Vector3Barycenter(Vector3 p, Vector3 a, Vector3 b, Vector3 c); // Projects a Vector3 from screen space into object space // NOTE: We are avoiding calling other raymath functions despite available RMAPI Vector3 Vector3Unproject(Vector3 source, Matrix projection, Matrix view); // Get Vector3 as float array RMAPI float3 Vector3ToFloatV(Vector3 v); // Invert the given vector RMAPI Vector3 Vector3Invert(Vector3 v); // Clamp the components of the vector between // min and max values specified by the given vectors RMAPI Vector3 Vector3Clamp(Vector3 v, Vector3 min, Vector3 max); // Clamp the magnitude of the vector between two values RMAPI Vector3 Vector3ClampValue(Vector3 v, float min, float max); // Check whether two given vectors are almost equal RMAPI int Vector3Equals(Vector3 p, Vector3 q); // Compute the direction of a refracted ray where v specifies the // normalized direction of the incoming ray, n specifies the // normalized normal vector of the interface of two optical media, // and r specifies the ratio of the refractive index of the medium // from where the ray comes to the refractive index of the medium // on the other side of the surface RMAPI Vector3 Vector3Refract(Vector3 v, Vector3 n, float r); //---------------------------------------------------------------------------------- // Module Functions Definition - Matrix math //---------------------------------------------------------------------------------- // Compute matrix determinant RMAPI float MatrixDeterminant(Matrix mat); // Get the trace of the matrix (sum of the values along the diagonal); RMAPI float MatrixTrace(Matrix mat); // Transposes provided matrix RMAPI Matrix MatrixTranspose(Matrix mat); // Invert provided matrix RMAPI Matrix MatrixInvert(Matrix mat); // Get identity matrix RMAPI Matrix MatrixIdentity(void); // Add two matrices RMAPI Matrix MatrixAdd(Matrix left, Matrix right); // Subtract two matrices (left - right); RMAPI Matrix MatrixSubtract(Matrix left, Matrix right); // Get two matrix multiplication // NOTE: When multiplying matrices... the order matters! RMAPI Matrix MatrixMultiply(Matrix left, Matrix right); // Get translation matrix RMAPI Matrix MatrixTranslate(float x, float y, float z); // Create rotation matrix from axis and angle // NOTE: Angle should be provided in radians RMAPI Matrix MatrixRotate(Vector3 axis, float angle); // Get x-rotation matrix // NOTE: Angle must be provided in radians RMAPI Matrix MatrixRotateX(float angle); // Get y-rotation matrix // NOTE: Angle must be provided in radians RMAPI Matrix MatrixRotateY(float angle); // Get z-rotation matrix // NOTE: Angle must be provided in radians RMAPI Matrix MatrixRotateZ(float angle); // Get xyz-rotation matrix // NOTE: Angle must be provided in radians RMAPI Matrix MatrixRotateXYZ(Vector3 angle); // Get zyx-rotation matrix // NOTE: Angle must be provided in radians RMAPI Matrix MatrixRotateZYX(Vector3 angle); // Get scaling matrix RMAPI Matrix MatrixScale(float x, float y, float z); // Get perspective projection matrix RMAPI Matrix MatrixFrustum(double left, double right, double bottom, double top, double near, double far); // Get perspective projection matrix // NOTE: Fovy angle must be provided in radians RMAPI Matrix MatrixPerspective(double fovy, double aspect, double near, double far); // Get orthographic projection matrix RMAPI Matrix MatrixOrtho(double left, double right, double bottom, double top, double near, double far); // Get camera look-at matrix (view matrix); RMAPI Matrix MatrixLookAt(Vector3 eye, Vector3 target, Vector3 up); // Get float array of matrix data RMAPI float16 MatrixToFloatV(Matrix mat); //---------------------------------------------------------------------------------- // Module Functions Definition - Quaternion math //---------------------------------------------------------------------------------- // Add two quaternions RMAPI Quaternion QuaternionAdd(Quaternion q1, Quaternion q2); // Add quaternion and float value RMAPI Quaternion QuaternionAddValue(Quaternion q, float add); // Subtract two quaternions RMAPI Quaternion QuaternionSubtract(Quaternion q1, Quaternion q2); // Subtract quaternion and float value RMAPI Quaternion QuaternionSubtractValue(Quaternion q, float sub); // Get identity quaternion RMAPI Quaternion QuaternionIdentity(void); // Computes the length of a quaternion RMAPI float QuaternionLength(Quaternion q); // Normalize provided quaternion RMAPI Quaternion QuaternionNormalize(Quaternion q); // Invert provided quaternion RMAPI Quaternion QuaternionInvert(Quaternion q); // Calculate two quaternion multiplication RMAPI Quaternion QuaternionMultiply(Quaternion q1, Quaternion q2); // Scale quaternion by float value RMAPI Quaternion QuaternionScale(Quaternion q, float mul); // Divide two quaternions RMAPI Quaternion QuaternionDivide(Quaternion q1, Quaternion q2); // Calculate linear interpolation between two quaternions RMAPI Quaternion QuaternionLerp(Quaternion q1, Quaternion q2, float amount); // Calculate slerp-optimized interpolation between two quaternions RMAPI Quaternion QuaternionNlerp(Quaternion q1, Quaternion q2, float amount); // Calculates spherical linear interpolation between two quaternions RMAPI Quaternion QuaternionSlerp(Quaternion q1, Quaternion q2, float amount); // Calculate quaternion based on the rotation from one vector to another RMAPI Quaternion QuaternionFromVector3ToVector3(Vector3 from, Vector3 to); // Get a quaternion for a given rotation matrix RMAPI Quaternion QuaternionFromMatrix(Matrix mat); // Get a matrix for a given quaternion RMAPI Matrix QuaternionToMatrix(Quaternion q); // Get rotation quaternion for an angle and axis // NOTE: Angle must be provided in radians RMAPI Quaternion QuaternionFromAxisAngle(Vector3 axis, float angle); // Get the rotation angle and axis for a given quaternion RMAPI void QuaternionToAxisAngle(Quaternion q, Vector3 *outAxis, float *outAngle); // Get the quaternion equivalent to Euler angles // NOTE: Rotation order is ZYX RMAPI Quaternion QuaternionFromEuler(float pitch, float yaw, float roll); // Get the Euler angles equivalent to quaternion (roll, pitch, yaw); // NOTE: Angles are returned in a Vector3 struct in radians RMAPI Vector3 QuaternionToEuler(Quaternion q); // Transform a quaternion given a transformation matrix RMAPI Quaternion QuaternionTransform(Quaternion q, Matrix mat); // Check whether two given quaternions are almost equal RMAPI int QuaternionEquals(Quaternion p, Quaternion q); #ifdef YESMATH // Ray, ray for raycasting typedef struct Ray { Vector3 position; // Ray position (origin) Vector3 direction; // Ray direction (normalized) } Ray; // RayCollision, ray hit information typedef struct RayCollision { bool hit; // Did the ray hit something? float distance; // Distance to the nearest hit Vector3 point; // Point of the nearest hit Vector3 normal; // Surface normal of hit } RayCollision; // BoundingBox typedef struct BoundingBox { Vector3 min; // Minimum vertex box-corner Vector3 max; // Maximum vertex box-corner } BoundingBox; // Camera type, defines a camera position/orientation in 3d space typedef struct Camera3D { Vector3 position; // Camera position Vector3 target; // Camera target it looks-at Vector3 up; // Camera up vector (rotation over its axis) float fovy; // Camera field-of-view apperture in Y (degrees) in perspective, used as near plane width in orthographic int projection; // Camera projection type: CAMERA_PERSPECTIVE or CAMERA_ORTHOGRAPHIC } Camera3D; #endif RayCollision ObjectiveCBugFixRaycast(Camera3D camera, BoundingBox bbox); Vector3 MidpointBoundingBox(BoundingBox bbox); RLAPI Vector3 GetCameraForward(Camera *camera); RLAPI Vector3 GetCameraUp(Camera *camera); RLAPI Vector3 GetCameraRight(Camera *camera); // Camera movement RLAPI void CameraMoveForward(Camera *camera, float distance, bool moveInWorldPlane); RLAPI void CameraMoveUp(Camera *camera, float distance); RLAPI void CameraMoveRight(Camera *camera, float distance, bool moveInWorldPlane); RLAPI void CameraMoveToTarget(Camera *camera, float delta); // Camera rotation RLAPI void CameraYaw(Camera *camera, float angle, bool rotateAroundTarget); RLAPI void CameraPitch(Camera *camera, float angle, bool lockView, bool rotateAroundTarget, bool rotateUp); RLAPI void CameraRoll(Camera *camera, float angle); RLAPI Matrix GetCameraViewMatrix(Camera *camera); RLAPI Matrix GetCameraProjectionMatrix(Camera* camera, float aspect); #endif // RAYMATH_H