Complete review of raymath for API consistency

This commit is contained in:
Ray 2018-03-16 13:47:01 +01:00
parent 9318dc98ce
commit 61e0e4b4f3
7 changed files with 310 additions and 280 deletions

View file

@ -1,6 +1,6 @@
/********************************************************************************************** /**********************************************************************************************
* *
* raylib v1.9-dev * raylib v1.9.6-dev
* *
* A simple and easy-to-use library to learn videogames programming (www.raylib.com) * A simple and easy-to-use library to learn videogames programming (www.raylib.com)
* *
@ -103,11 +103,23 @@
#define KEY_SPACE 32 #define KEY_SPACE 32
#define KEY_ESCAPE 256 #define KEY_ESCAPE 256
#define KEY_ENTER 257 #define KEY_ENTER 257
#define KEY_TAB 258
#define KEY_BACKSPACE 259 #define KEY_BACKSPACE 259
#define KEY_INSERT 260
#define KEY_DELETE 261
#define KEY_RIGHT 262 #define KEY_RIGHT 262
#define KEY_LEFT 263 #define KEY_LEFT 263
#define KEY_DOWN 264 #define KEY_DOWN 264
#define KEY_UP 265 #define KEY_UP 265
#define KEY_PAGE_UP 266
#define KEY_PAGE_DOWN 267
#define KEY_HOME 268
#define KEY_END 269
#define KEY_CAPS_LOCK 280
#define KEY_SCROLL_LOCK 281
#define KEY_NUM_LOCK 282
#define KEY_PRINT_SCREEN 283
#define KEY_PAUSE 284
#define KEY_F1 290 #define KEY_F1 290
#define KEY_F2 291 #define KEY_F2 291
#define KEY_F3 292 #define KEY_F3 292
@ -310,6 +322,14 @@ typedef struct Vector3 {
float z; float z;
} Vector3; } Vector3;
// Vector4 type
typedef struct Vector4 {
float x;
float y;
float z;
float w;
} Vector4;
// Matrix type (OpenGL style 4x4 - right handed, column major) // Matrix type (OpenGL style 4x4 - right handed, column major)
typedef struct Matrix { typedef struct Matrix {
float m0, m4, m8, m12; float m0, m4, m8, m12;
@ -410,7 +430,7 @@ typedef struct Mesh {
float *texcoords; // Vertex texture coordinates (UV - 2 components per vertex) (shader-location = 1) float *texcoords; // Vertex texture coordinates (UV - 2 components per vertex) (shader-location = 1)
float *texcoords2; // Vertex second texture coordinates (useful for lightmaps) (shader-location = 5) float *texcoords2; // Vertex second texture coordinates (useful for lightmaps) (shader-location = 5)
float *normals; // Vertex normals (XYZ - 3 components per vertex) (shader-location = 2) float *normals; // Vertex normals (XYZ - 3 components per vertex) (shader-location = 2)
float *tangents; // Vertex tangents (XYZ - 3 components per vertex) (shader-location = 4) float *tangents; // Vertex tangents (XYZW - 4 components per vertex) (shader-location = 4)
unsigned char *colors; // Vertex colors (RGBA - 4 components per vertex) (shader-location = 3) unsigned char *colors; // Vertex colors (RGBA - 4 components per vertex) (shader-location = 3)
unsigned short *indices;// Vertex indices (in case vertex data comes indexed) unsigned short *indices;// Vertex indices (in case vertex data comes indexed)
@ -541,7 +561,7 @@ typedef enum {
LOC_MAP_METALNESS, // LOC_MAP_SPECULAR LOC_MAP_METALNESS, // LOC_MAP_SPECULAR
LOC_MAP_NORMAL, LOC_MAP_NORMAL,
LOC_MAP_ROUGHNESS, LOC_MAP_ROUGHNESS,
LOC_MAP_OCCUSION, LOC_MAP_OCCLUSION,
LOC_MAP_EMISSION, LOC_MAP_EMISSION,
LOC_MAP_HEIGHT, LOC_MAP_HEIGHT,
LOC_MAP_CUBEMAP, LOC_MAP_CUBEMAP,
@ -674,6 +694,7 @@ extern "C" { // Prevents name mangling of functions
// Window-related functions // Window-related functions
RLAPI void InitWindow(int width, int height, void *data); // Initialize window and OpenGL context RLAPI void InitWindow(int width, int height, void *data); // Initialize window and OpenGL context
RLAPI void CloseWindow(void); // Close window and unload OpenGL context RLAPI void CloseWindow(void); // Close window and unload OpenGL context
RLAPI bool IsWindowReady(void); // Check if window has been initialized successfully
RLAPI bool WindowShouldClose(void); // Check if KEY_ESCAPE pressed or Close icon pressed RLAPI bool WindowShouldClose(void); // Check if KEY_ESCAPE pressed or Close icon pressed
RLAPI bool IsWindowMinimized(void); // Check if window has been minimized (or lost focus) RLAPI bool IsWindowMinimized(void); // Check if window has been minimized (or lost focus)
RLAPI void ToggleFullscreen(void); // Toggle fullscreen mode (only PLATFORM_DESKTOP) RLAPI void ToggleFullscreen(void); // Toggle fullscreen mode (only PLATFORM_DESKTOP)
@ -682,6 +703,7 @@ RLAPI void SetWindowTitle(const char *title); // Set title f
RLAPI void SetWindowPosition(int x, int y); // Set window position on screen (only PLATFORM_DESKTOP) RLAPI void SetWindowPosition(int x, int y); // Set window position on screen (only PLATFORM_DESKTOP)
RLAPI void SetWindowMonitor(int monitor); // Set monitor for the current window (fullscreen mode) RLAPI void SetWindowMonitor(int monitor); // Set monitor for the current window (fullscreen mode)
RLAPI void SetWindowMinSize(int width, int height); // Set window minimum dimensions (for FLAG_WINDOW_RESIZABLE) RLAPI void SetWindowMinSize(int width, int height); // Set window minimum dimensions (for FLAG_WINDOW_RESIZABLE)
RLAPI void SetWindowSize(int width, int height); // Set window dimensions
RLAPI int GetScreenWidth(void); // Get current screen width RLAPI int GetScreenWidth(void); // Get current screen width
RLAPI int GetScreenHeight(void); // Get current screen height RLAPI int GetScreenHeight(void); // Get current screen height
@ -715,17 +737,11 @@ RLAPI float GetFrameTime(void); // Returns tim
RLAPI double GetTime(void); // Returns elapsed time in seconds since InitWindow() RLAPI double GetTime(void); // Returns elapsed time in seconds since InitWindow()
// Color-related functions // Color-related functions
RLAPI int GetHexValue(Color color); // Returns hexadecimal value for a Color RLAPI float *ColorToFloat(Color color); // Returns normalized float array for a Color
RLAPI int ColorToInt(Color color); // Returns hexadecimal value for a Color
RLAPI Vector3 ColorToHSV(Color color); // Returns HSV values for a Color
RLAPI Color GetColor(int hexValue); // Returns a Color struct from hexadecimal value RLAPI Color GetColor(int hexValue); // Returns a Color struct from hexadecimal value
RLAPI Color Fade(Color color, float alpha); // Color fade-in or fade-out, alpha goes from 0.0f to 1.0f RLAPI Color Fade(Color color, float alpha); // Color fade-in or fade-out, alpha goes from 0.0f to 1.0f
RLAPI float *ColorToFloat(Color color); // Converts Color to float array and normalizes
// Math useful functions (available from raymath.h)
RLAPI float *Vector3ToFloat(Vector3 vec); // Returns Vector3 as float array
RLAPI float *MatrixToFloat(Matrix mat); // Returns Matrix as float array
RLAPI Vector3 Vector3Zero(void); // Vector with components value 0.0f
RLAPI Vector3 Vector3One(void); // Vector with components value 1.0f
RLAPI Matrix MatrixIdentity(void); // Returns identity matrix
// Misc. functions // Misc. functions
RLAPI void ShowLogo(void); // Activate raylib logo at startup (can be done with flags) RLAPI void ShowLogo(void); // Activate raylib logo at startup (can be done with flags)
@ -783,6 +799,7 @@ RLAPI int GetMouseX(void); // Returns mouse p
RLAPI int GetMouseY(void); // Returns mouse position Y RLAPI int GetMouseY(void); // Returns mouse position Y
RLAPI Vector2 GetMousePosition(void); // Returns mouse position XY RLAPI Vector2 GetMousePosition(void); // Returns mouse position XY
RLAPI void SetMousePosition(Vector2 position); // Set mouse position XY RLAPI void SetMousePosition(Vector2 position); // Set mouse position XY
RLAPI void SetMouseScale(float scale); // Set mouse scaling
RLAPI int GetMouseWheelMove(void); // Returns mouse wheel movement Y RLAPI int GetMouseWheelMove(void); // Returns mouse wheel movement Y
// Input-related functions: touch // Input-related functions: touch
@ -839,6 +856,7 @@ RLAPI void DrawRectangleGradientV(int posX, int posY, int width, int height, Col
RLAPI void DrawRectangleGradientH(int posX, int posY, int width, int height, Color color1, Color color2);// Draw a horizontal-gradient-filled rectangle RLAPI void DrawRectangleGradientH(int posX, int posY, int width, int height, Color color1, Color color2);// Draw a horizontal-gradient-filled rectangle
RLAPI void DrawRectangleGradientEx(Rectangle rec, Color col1, Color col2, Color col3, Color col4); // Draw a gradient-filled rectangle with custom vertex colors RLAPI void DrawRectangleGradientEx(Rectangle rec, Color col1, Color col2, Color col3, Color col4); // Draw a gradient-filled rectangle with custom vertex colors
RLAPI void DrawRectangleLines(int posX, int posY, int width, int height, Color color); // Draw rectangle outline RLAPI void DrawRectangleLines(int posX, int posY, int width, int height, Color color); // Draw rectangle outline
RLAPI void DrawRectangleLinesEx(Rectangle rec, int lineThick, Color color); // Draw rectangle outline with extended parameters
RLAPI void DrawTriangle(Vector2 v1, Vector2 v2, Vector2 v3, Color color); // Draw a color-filled triangle RLAPI void DrawTriangle(Vector2 v1, Vector2 v2, Vector2 v3, Color color); // Draw a color-filled triangle
RLAPI void DrawTriangleLines(Vector2 v1, Vector2 v2, Vector2 v3, Color color); // Draw triangle outline RLAPI void DrawTriangleLines(Vector2 v1, Vector2 v2, Vector2 v3, Color color); // Draw triangle outline
RLAPI void DrawPoly(Vector2 center, int sides, float radius, float rotation, Color color); // Draw a regular polygon (Vector version) RLAPI void DrawPoly(Vector2 center, int sides, float radius, float rotation, Color color); // Draw a regular polygon (Vector version)
@ -886,6 +904,7 @@ RLAPI void ImageAlphaPremultiply(Image *image);
RLAPI void ImageCrop(Image *image, Rectangle crop); // Crop an image to a defined rectangle RLAPI void ImageCrop(Image *image, Rectangle crop); // Crop an image to a defined rectangle
RLAPI void ImageResize(Image *image, int newWidth, int newHeight); // Resize and image (bilinear filtering) RLAPI void ImageResize(Image *image, int newWidth, int newHeight); // Resize and image (bilinear filtering)
RLAPI void ImageResizeNN(Image *image,int newWidth,int newHeight); // Resize and image (Nearest-Neighbor scaling algorithm) RLAPI void ImageResizeNN(Image *image,int newWidth,int newHeight); // Resize and image (Nearest-Neighbor scaling algorithm)
RLAPI void ImageMipmaps(Image *image); // Generate all mipmap levels for a provided image
RLAPI void ImageDither(Image *image, int rBpp, int gBpp, int bBpp, int aBpp); // Dither image data to 16bpp or lower (Floyd-Steinberg dithering) RLAPI void ImageDither(Image *image, int rBpp, int gBpp, int bBpp, int aBpp); // Dither image data to 16bpp or lower (Floyd-Steinberg dithering)
RLAPI Image ImageText(const char *text, int fontSize, Color color); // Create an image from text (default font) RLAPI Image ImageText(const char *text, int fontSize, Color color); // Create an image from text (default font)
RLAPI Image ImageTextEx(SpriteFont font, const char *text, float fontSize, int spacing, Color tint); // Create an image from text (custom sprite font) RLAPI Image ImageTextEx(SpriteFont font, const char *text, float fontSize, int spacing, Color tint); // Create an image from text (custom sprite font)
@ -908,7 +927,7 @@ RLAPI Image GenImageGradientH(int width, int height, Color left, Color right);
RLAPI Image GenImageGradientRadial(int width, int height, float density, Color inner, Color outer); // Generate image: radial gradient RLAPI Image GenImageGradientRadial(int width, int height, float density, Color inner, Color outer); // Generate image: radial gradient
RLAPI Image GenImageChecked(int width, int height, int checksX, int checksY, Color col1, Color col2); // Generate image: checked RLAPI Image GenImageChecked(int width, int height, int checksX, int checksY, Color col1, Color col2); // Generate image: checked
RLAPI Image GenImageWhiteNoise(int width, int height, float factor); // Generate image: white noise RLAPI Image GenImageWhiteNoise(int width, int height, float factor); // Generate image: white noise
RLAPI Image GenImagePerlinNoise(int width, int height, float scale); // Generate image: perlin noise RLAPI Image GenImagePerlinNoise(int width, int height, int offsetX, int offsetY, float scale); // Generate image: perlin noise
RLAPI Image GenImageCellular(int width, int height, int tileSize); // Generate image: cellular algorithm. Bigger tileSize means bigger cells RLAPI Image GenImageCellular(int width, int height, int tileSize); // Generate image: cellular algorithm. Bigger tileSize means bigger cells
// Texture2D configuration functions // Texture2D configuration functions
@ -932,19 +951,20 @@ RLAPI void DrawTexturePro(Texture2D texture, Rectangle sourceRec, Rectangle dest
RLAPI SpriteFont GetDefaultFont(void); // Get the default SpriteFont RLAPI SpriteFont GetDefaultFont(void); // Get the default SpriteFont
RLAPI SpriteFont LoadSpriteFont(const char *fileName); // Load SpriteFont from file into GPU memory (VRAM) RLAPI SpriteFont LoadSpriteFont(const char *fileName); // Load SpriteFont from file into GPU memory (VRAM)
RLAPI SpriteFont LoadSpriteFontEx(const char *fileName, int fontSize, int charsCount, int *fontChars); // Load SpriteFont from file with extended parameters RLAPI SpriteFont LoadSpriteFontEx(const char *fileName, int fontSize, int charsCount, int *fontChars); // Load SpriteFont from file with extended parameters
RLAPI void UnloadSpriteFont(SpriteFont spriteFont); // Unload SpriteFont from GPU memory (VRAM) RLAPI void UnloadSpriteFont(SpriteFont font); // Unload SpriteFont from GPU memory (VRAM)
// Text drawing functions // Text drawing functions
RLAPI void DrawFPS(int posX, int posY); // Shows current FPS RLAPI void DrawFPS(int posX, int posY); // Shows current FPS
RLAPI void DrawText(const char *text, int posX, int posY, int fontSize, Color color); // Draw text (using default font) RLAPI void DrawText(const char *text, int posX, int posY, int fontSize, Color color); // Draw text (using default font)
RLAPI void DrawTextEx(SpriteFont spriteFont, const char* text, Vector2 position, // Draw text using SpriteFont and additional parameters RLAPI void DrawTextEx(SpriteFont font, const char* text, Vector2 position, // Draw text using SpriteFont and additional parameters
float fontSize, int spacing, Color tint); float fontSize, int spacing, Color tint);
// Text misc. functions // Text misc. functions
RLAPI int MeasureText(const char *text, int fontSize); // Measure string width for default font RLAPI int MeasureText(const char *text, int fontSize); // Measure string width for default font
RLAPI Vector2 MeasureTextEx(SpriteFont spriteFont, const char *text, float fontSize, int spacing); // Measure string size for SpriteFont RLAPI Vector2 MeasureTextEx(SpriteFont font, const char *text, float fontSize, int spacing); // Measure string size for SpriteFont
RLAPI const char *FormatText(const char *text, ...); // Formatting of text with variables to 'embed' RLAPI const char *FormatText(const char *text, ...); // Formatting of text with variables to 'embed'
RLAPI const char *SubText(const char *text, int position, int length); // Get a piece of a text string RLAPI const char *SubText(const char *text, int position, int length); // Get a piece of a text string
RLAPI int GetGlyphIndex(SpriteFont font, int character); // Returns index position for a unicode character on sprite font
//------------------------------------------------------------------------------------ //------------------------------------------------------------------------------------
// Basic 3d Shapes Drawing Functions (Module: models) // Basic 3d Shapes Drawing Functions (Module: models)
@ -981,6 +1001,11 @@ RLAPI void UnloadModel(Model model);
RLAPI Mesh LoadMesh(const char *fileName); // Load mesh from file RLAPI Mesh LoadMesh(const char *fileName); // Load mesh from file
RLAPI void UnloadMesh(Mesh *mesh); // Unload mesh from memory (RAM and/or VRAM) RLAPI void UnloadMesh(Mesh *mesh); // Unload mesh from memory (RAM and/or VRAM)
// Mesh manipulation functions
RLAPI BoundingBox MeshBoundingBox(Mesh mesh); // Compute mesh bounding box limits
RLAPI void MeshTangents(Mesh *mesh); // Compute mesh tangents
RLAPI void MeshBinormals(Mesh *mesh); // Compute mesh binormals
// Mesh generation functions // Mesh generation functions
RLAPI Mesh GenMeshPlane(float width, float length, int resX, int resZ); // Generate plane mesh (with subdivisions) RLAPI Mesh GenMeshPlane(float width, float length, int resX, int resZ); // Generate plane mesh (with subdivisions)
RLAPI Mesh GenMeshCube(float width, float height, float length); // Generate cuboid mesh RLAPI Mesh GenMeshCube(float width, float height, float length); // Generate cuboid mesh
@ -1010,7 +1035,6 @@ RLAPI void DrawBillboardRec(Camera camera, Texture2D texture, Rectangle sourceRe
Vector3 center, float size, Color tint); // Draw a billboard texture defined by sourceRec Vector3 center, float size, Color tint); // Draw a billboard texture defined by sourceRec
// Collision detection functions // Collision detection functions
RLAPI BoundingBox CalculateBoundingBox(Mesh mesh); // Calculate mesh bounding box limits
RLAPI bool CheckCollisionSpheres(Vector3 centerA, float radiusA, Vector3 centerB, float radiusB); // Detect collision between two spheres RLAPI bool CheckCollisionSpheres(Vector3 centerA, float radiusA, Vector3 centerB, float radiusB); // Detect collision between two spheres
RLAPI bool CheckCollisionBoxes(BoundingBox box1, BoundingBox box2); // Detect collision between two bounding boxes RLAPI bool CheckCollisionBoxes(BoundingBox box1, BoundingBox box2); // Detect collision between two bounding boxes
RLAPI bool CheckCollisionBoxSphere(BoundingBox box, Vector3 centerSphere, float radiusSphere); // Detect collision between box and sphere RLAPI bool CheckCollisionBoxSphere(BoundingBox box, Vector3 centerSphere, float radiusSphere); // Detect collision between box and sphere
@ -1029,7 +1053,8 @@ RLAPI RayHitInfo GetCollisionRayGround(Ray ray, float groundHeight);
// Shader loading/unloading functions // Shader loading/unloading functions
RLAPI char *LoadText(const char *fileName); // Load chars array from text file RLAPI char *LoadText(const char *fileName); // Load chars array from text file
RLAPI Shader LoadShader(char *vsFileName, char *fsFileName); // Load shader from files and bind default locations RLAPI Shader LoadShader(const char *vsFileName, const char *fsFileName); // Load shader from files and bind default locations
RLAPI Shader LoadShaderCode(char *vsCode, char *fsCode); // Load shader from code strings and bind default locations
RLAPI void UnloadShader(Shader shader); // Unload shader from GPU memory (VRAM) RLAPI void UnloadShader(Shader shader); // Unload shader from GPU memory (VRAM)
RLAPI Shader GetShaderDefault(void); // Get default shader RLAPI Shader GetShaderDefault(void); // Get default shader

View file

@ -432,7 +432,7 @@ static void *GamepadThread(void *arg); // Mouse reading thread
// NOTE: data parameter could be used to pass any kind of required data to the initialization // NOTE: data parameter could be used to pass any kind of required data to the initialization
void InitWindow(int width, int height, void *data) void InitWindow(int width, int height, void *data)
{ {
TraceLog(LOG_INFO, "Initializing raylib (v1.9.5-dev)"); TraceLog(LOG_INFO, "Initializing raylib (v1.9.6-dev)");
#if defined(PLATFORM_DESKTOP) #if defined(PLATFORM_DESKTOP)
windowTitle = (char *)data; windowTitle = (char *)data;
@ -503,7 +503,7 @@ void InitWindow(int width, int height, void *data)
// NOTE: data parameter could be used to pass any kind of required data to the initialization // NOTE: data parameter could be used to pass any kind of required data to the initialization
void InitWindow(int width, int height, void *data) void InitWindow(int width, int height, void *data)
{ {
TraceLog(LOG_INFO, "Initializing raylib (v1.9.5-dev)"); TraceLog(LOG_INFO, "Initializing raylib (v1.9.6-dev)");
screenWidth = width; screenWidth = width;
screenHeight = height; screenHeight = height;
@ -1025,7 +1025,7 @@ Ray GetMouseRay(Vector2 mousePosition, Camera camera)
// Calculate normalized direction vector // Calculate normalized direction vector
Vector3 direction = Vector3Subtract(farPoint, nearPoint); Vector3 direction = Vector3Subtract(farPoint, nearPoint);
Vector3Normalize(&direction); direction = Vector3Normalize(direction);
// Apply calculated vectors to ray // Apply calculated vectors to ray
ray.position = camera.position; ray.position = camera.position;
@ -1047,10 +1047,10 @@ Vector2 GetWorldToScreen(Vector3 position, Camera camera)
Quaternion worldPos = { position.x, position.y, position.z, 1.0f }; Quaternion worldPos = { position.x, position.y, position.z, 1.0f };
// Transform world position to view // Transform world position to view
QuaternionTransform(&worldPos, matView); worldPos = QuaternionTransform(worldPos, matView);
// Transform result to projection (clip space position) // Transform result to projection (clip space position)
QuaternionTransform(&worldPos, matProj); worldPos = QuaternionTransform(worldPos, matProj);
// Calculate normalized device coordinates (inverted y) // Calculate normalized device coordinates (inverted y)
Vector3 ndcPos = { worldPos.x/worldPos.w, -worldPos.y/worldPos.w, worldPos.z/worldPos.w }; Vector3 ndcPos = { worldPos.x/worldPos.w, -worldPos.y/worldPos.w, worldPos.z/worldPos.w };

View file

@ -1759,8 +1759,8 @@ void DrawBillboardRec(Camera camera, Texture2D texture, Rectangle sourceRec, Vec
| | | |
d-------c d-------c
*/ */
Vector3Scale(&right, sizeRatio.x/2); right = Vector3Scale(right, sizeRatio.x/2);
Vector3Scale(&up, sizeRatio.y/2); up = Vector3Scale(up, sizeRatio.y/2);
Vector3 p1 = Vector3Add(right, up); Vector3 p1 = Vector3Add(right, up);
Vector3 p2 = Vector3Subtract(right, up); Vector3 p2 = Vector3Subtract(right, up);
@ -1897,7 +1897,7 @@ bool CheckCollisionRaySphereEx(Ray ray, Vector3 spherePosition, float sphereRadi
if (distance < sphereRadius) collisionDistance = vector + sqrtf(d); if (distance < sphereRadius) collisionDistance = vector + sqrtf(d);
else collisionDistance = vector - sqrtf(d); else collisionDistance = vector - sqrtf(d);
Vector3Scale(&offset, collisionDistance); offset = Vector3Scale(offset, collisionDistance);
Vector3 cPoint = Vector3Add(ray.position, offset); Vector3 cPoint = Vector3Add(ray.position, offset);
collisionPoint->x = cPoint.x; collisionPoint->x = cPoint.x;
@ -2022,9 +2022,9 @@ RayHitInfo GetCollisionRayTriangle(Ray ray, Vector3 p1, Vector3 p2, Vector3 p3)
result.distance = t; result.distance = t;
result.hit = true; result.hit = true;
result.normal = Vector3CrossProduct(edge1, edge2); result.normal = Vector3CrossProduct(edge1, edge2);
Vector3Normalize(&result.normal); result.normal = Vector3Normalize(result.normal);
Vector3 rayDir = ray.direction; Vector3 rayDir = ray.direction;
Vector3Scale(&rayDir, t); rayDir = Vector3Scale(rayDir, t);
result.position = Vector3Add(ray.position, rayDir); result.position = Vector3Add(ray.position, rayDir);
} }
@ -2045,7 +2045,7 @@ RayHitInfo GetCollisionRayGround(Ray ray, float groundHeight)
if (t >= 0.0) if (t >= 0.0)
{ {
Vector3 rayDir = ray.direction; Vector3 rayDir = ray.direction;
Vector3Scale(&rayDir, t); rayDir = Vector3Scale(rayDir, t);
result.hit = true; result.hit = true;
result.distance = t; result.distance = t;
result.normal = (Vector3){ 0.0, 1.0, 0.0 }; result.normal = (Vector3){ 0.0, 1.0, 0.0 };
@ -2300,7 +2300,7 @@ static Mesh LoadOBJ(const char *fileName)
{ {
// If normals not defined, they are calculated from the 3 vertices [N = (V2 - V1) x (V3 - V1)] // If normals not defined, they are calculated from the 3 vertices [N = (V2 - V1) x (V3 - V1)]
Vector3 norm = Vector3CrossProduct(Vector3Subtract(midVertices[vCount[1]-1], midVertices[vCount[0]-1]), Vector3Subtract(midVertices[vCount[2]-1], midVertices[vCount[0]-1])); Vector3 norm = Vector3CrossProduct(Vector3Subtract(midVertices[vCount[1]-1], midVertices[vCount[0]-1]), Vector3Subtract(midVertices[vCount[2]-1], midVertices[vCount[0]-1]));
Vector3Normalize(&norm); norm = Vector3Normalize(norm);
mesh.normals[nCounter] = norm.x; mesh.normals[nCounter] = norm.x;
mesh.normals[nCounter + 1] = norm.y; mesh.normals[nCounter + 1] = norm.y;

View file

@ -1,6 +1,6 @@
/********************************************************************************************** /**********************************************************************************************
* *
* raylib v1.9.5-dev * raylib v1.9.6-dev
* *
* A simple and easy-to-use library to learn videogames programming (www.raylib.com) * A simple and easy-to-use library to learn videogames programming (www.raylib.com)
* *

View file

@ -83,11 +83,16 @@
#define RAD2DEG (180.0f/PI) #define RAD2DEG (180.0f/PI)
#endif #endif
// Return float vector // Return float vector for Matrix
#ifndef MatrixToFloat #ifndef MatrixToFloat
#define MatrixToFloat(mat) (MatrixToFloatV(mat).v) #define MatrixToFloat(mat) (MatrixToFloatV(mat).v)
#endif #endif
// Return float vector for Vector3
#ifndef Vector3ToFloat
#define Vector3ToFloat(vec) (Vector3ToFloatV(vec).v)
#endif
//---------------------------------------------------------------------------------- //----------------------------------------------------------------------------------
// Types and Structures Definition // Types and Structures Definition
//---------------------------------------------------------------------------------- //----------------------------------------------------------------------------------
@ -147,84 +152,86 @@ RMDEF float Clamp(float value, float min, float max)
// Vector with components value 0.0f // Vector with components value 0.0f
RMDEF Vector2 Vector2Zero(void) RMDEF Vector2 Vector2Zero(void)
{ {
Vector2 tmp = {0.0f, 0.0f}; Vector2 result = { 0.0f, 0.0f };
return tmp; return result;
} }
// Vector with components value 1.0f // Vector with components value 1.0f
RMDEF Vector2 Vector2One(void) RMDEF Vector2 Vector2One(void)
{ {
Vector2 tmp = {1.0f, 1.0f}; Vector2 result = { 1.0f, 1.0f };
return tmp; return result;
} }
// Add two vectors (v1 + v2) // Add two vectors (v1 + v2)
RMDEF Vector2 Vector2Add(Vector2 v1, Vector2 v2) RMDEF Vector2 Vector2Add(Vector2 v1, Vector2 v2)
{ {
Vector2 tmp = { v1.x + v2.x, v1.y + v2.y }; Vector2 result = { v1.x + v2.x, v1.y + v2.y };
return tmp; return result;
} }
// Subtract two vectors (v1 - v2) // Subtract two vectors (v1 - v2)
RMDEF Vector2 Vector2Subtract(Vector2 v1, Vector2 v2) RMDEF Vector2 Vector2Subtract(Vector2 v1, Vector2 v2)
{ {
Vector2 tmp = { v1.x - v2.x, v1.y - v2.y }; Vector2 result = { v1.x - v2.x, v1.y - v2.y };
return tmp; return result;
} }
// Calculate vector length // Calculate vector length
RMDEF float Vector2Length(Vector2 v) RMDEF float Vector2Length(Vector2 v)
{ {
return sqrtf((v.x*v.x) + (v.y*v.y)); float result = sqrtf((v.x*v.x) + (v.y*v.y));
return result;
} }
// Calculate two vectors dot product // Calculate two vectors dot product
RMDEF float Vector2DotProduct(Vector2 v1, Vector2 v2) RMDEF float Vector2DotProduct(Vector2 v1, Vector2 v2)
{ {
return (v1.x*v2.x + v1.y*v2.y); float result = (v1.x*v2.x + v1.y*v2.y);
return result;
} }
// Calculate distance between two vectors // Calculate distance between two vectors
RMDEF float Vector2Distance(Vector2 v1, Vector2 v2) RMDEF float Vector2Distance(Vector2 v1, Vector2 v2)
{ {
return sqrtf((v1.x - v2.x)*(v1.x - v2.x) + (v1.y - v2.y)*(v1.y - v2.y)); float result = sqrtf((v1.x - v2.x)*(v1.x - v2.x) + (v1.y - v2.y)*(v1.y - v2.y));
return result;
} }
// Calculate angle from two vectors in X-axis // Calculate angle from two vectors in X-axis
RMDEF float Vector2Angle(Vector2 v1, Vector2 v2) RMDEF float Vector2Angle(Vector2 v1, Vector2 v2)
{ {
float angle = atan2f(v2.y - v1.y, v2.x - v1.x)*(180.0f/PI); float result = atan2f(v2.y - v1.y, v2.x - v1.x)*(180.0f/PI);
if (result < 0) result += 360.0f;
if (angle < 0) angle += 360.0f; return result;
return angle;
} }
// Scale vector (multiply by value) // Scale vector (multiply by value)
RMDEF void Vector2Scale(Vector2 *v, float scale) RMDEF Vector2 Vector2Scale(Vector2 v, float scale)
{ {
v->x *= scale; Vector2 result = { v.x*scale, v.y*scale };
v->y *= scale; return result;
} }
// Negate vector // Negate vector
RMDEF void Vector2Negate(Vector2 *v) RMDEF Vector2 Vector2Negate(Vector2 v)
{ {
v->x = -v->x; Vector2 result = { -v.x, -v.y };
v->y = -v->y; return result;
} }
// Divide vector by a float value // Divide vector by a float value
RMDEF void Vector2Divide(Vector2 *v, float div) RMDEF Vector2 Vector2Divide(Vector2 v, float div)
{ {
Vector2 tmp = {v->x/div, v->y/div}; Vector2 result = { v.x/div, v.y/div };
*v = tmp; return result;
} }
// Normalize provided vector // Normalize provided vector
RMDEF void Vector2Normalize(Vector2 *v) RMDEF Vector2 Vector2Normalize(Vector2 v)
{ {
Vector2Divide(v, Vector2Length(*v)); Vector2 result = Vector2Divide(v, Vector2Length(v));
return result;
} }
//---------------------------------------------------------------------------------- //----------------------------------------------------------------------------------
@ -234,69 +241,56 @@ RMDEF void Vector2Normalize(Vector2 *v)
// Vector with components value 0.0f // Vector with components value 0.0f
RMDEF Vector3 Vector3Zero(void) RMDEF Vector3 Vector3Zero(void)
{ {
Vector3 tmp = { 0.0f, 0.0f, 0.0f }; Vector3 result = { 0.0f, 0.0f, 0.0f };
return tmp; return result;
} }
// Vector with components value 1.0f // Vector with components value 1.0f
RMDEF Vector3 Vector3One(void) RMDEF Vector3 Vector3One(void)
{ {
Vector3 tmp = { 1.0f, 1.0f, 1.0f }; Vector3 result = { 1.0f, 1.0f, 1.0f };
return tmp; return result;
} }
// Add two vectors // Add two vectors
RMDEF Vector3 Vector3Add(Vector3 v1, Vector3 v2) RMDEF Vector3 Vector3Add(Vector3 v1, Vector3 v2)
{ {
Vector3 tmp = { v1.x + v2.x, v1.y + v2.y, v1.z + v2.z }; Vector3 result = { v1.x + v2.x, v1.y + v2.y, v1.z + v2.z };
return tmp; return result;
} }
// Substract two vectors // Substract two vectors
RMDEF Vector3 Vector3Subtract(Vector3 v1, Vector3 v2) RMDEF Vector3 Vector3Subtract(Vector3 v1, Vector3 v2)
{ {
Vector3 tmp = { v1.x - v2.x, v1.y - v2.y, v1.z - v2.z }; Vector3 result = { v1.x - v2.x, v1.y - v2.y, v1.z - v2.z };
return tmp; return result;
} }
// Multiply vector by scalar // Multiply vector by scalar
RMDEF Vector3 Vector3Multiply(Vector3 v, float scalar) RMDEF Vector3 Vector3Multiply(Vector3 v, float scalar)
{ {
v.x *= scalar; Vector3 result = { v.x*scalar, v.y*scalar, v.z*scalar };
v.y *= scalar; return result;
v.z *= scalar;
return v;
} }
// Multiply vector by vector // Multiply vector by vector
RMDEF Vector3 Vector3MultiplyV(Vector3 v1, Vector3 v2) RMDEF Vector3 Vector3MultiplyV(Vector3 v1, Vector3 v2)
{ {
Vector3 result; Vector3 result = { v1.x*v2.x, v1.y*v2.y, v1.z*v2.z };
result.x = v1.x * v2.x;
result.y = v1.y * v2.y;
result.z = v1.z * v2.z;
return result; return result;
} }
// Calculate two vectors cross product // Calculate two vectors cross product
RMDEF Vector3 Vector3CrossProduct(Vector3 v1, Vector3 v2) RMDEF Vector3 Vector3CrossProduct(Vector3 v1, Vector3 v2)
{ {
Vector3 result; Vector3 result = { v1.y*v2.z - v1.z*v2.y, v1.z*v2.x - v1.x*v2.z, v1.x*v2.y - v1.y*v2.x };
result.x = v1.y*v2.z - v1.z*v2.y;
result.y = v1.z*v2.x - v1.x*v2.z;
result.z = v1.x*v2.y - v1.y*v2.x;
return result; return result;
} }
// Calculate one vector perpendicular vector // Calculate one vector perpendicular vector
RMDEF Vector3 Vector3Perpendicular(Vector3 v) RMDEF Vector3 Vector3Perpendicular(Vector3 v)
{ {
Vector3 result; Vector3 result = { 0 };
float min = fabsf(v.x); float min = fabsf(v.x);
Vector3 cardinalAxis = {1.0f, 0.0f, 0.0f}; Vector3 cardinalAxis = {1.0f, 0.0f, 0.0f};
@ -322,13 +316,15 @@ RMDEF Vector3 Vector3Perpendicular(Vector3 v)
// Calculate vector length // Calculate vector length
RMDEF float Vector3Length(const Vector3 v) RMDEF float Vector3Length(const Vector3 v)
{ {
return sqrtf(v.x*v.x + v.y*v.y + v.z*v.z); float result = sqrtf(v.x*v.x + v.y*v.y + v.z*v.z);
return result;
} }
// Calculate two vectors dot product // Calculate two vectors dot product
RMDEF float Vector3DotProduct(Vector3 v1, Vector3 v2) RMDEF float Vector3DotProduct(Vector3 v1, Vector3 v2)
{ {
return (v1.x*v2.x + v1.y*v2.y + v1.z*v2.z); float result = (v1.x*v2.x + v1.y*v2.y + v1.z*v2.z);
return result;
} }
// Calculate distance between two vectors // Calculate distance between two vectors
@ -337,58 +333,60 @@ RMDEF float Vector3Distance(Vector3 v1, Vector3 v2)
float dx = v2.x - v1.x; float dx = v2.x - v1.x;
float dy = v2.y - v1.y; float dy = v2.y - v1.y;
float dz = v2.z - v1.z; float dz = v2.z - v1.z;
float result = sqrtf(dx*dx + dy*dy + dz*dz);
return sqrtf(dx*dx + dy*dy + dz*dz); return result;
} }
// Scale provided vector // Scale provided vector
RMDEF void Vector3Scale(Vector3 *v, float scale) RMDEF Vector3 Vector3Scale(Vector3 v, float scale)
{ {
v->x *= scale; Vector3 result = { v.x*scale, v.y*scale, v.z*scale };
v->y *= scale; return result;
v->z *= scale;
} }
// Negate provided vector (invert direction) // Negate provided vector (invert direction)
RMDEF void Vector3Negate(Vector3 *v) RMDEF Vector3 Vector3Negate(Vector3 v)
{ {
v->x = -v->x; Vector3 result = { -v.x, -v.y, -v.z };
v->y = -v->y; return result;
v->z = -v->z;
} }
// Normalize provided vector // Normalize provided vector
RMDEF void Vector3Normalize(Vector3 *v) RMDEF Vector3 Vector3Normalize(Vector3 v)
{ {
Vector3 result = v;
float length, ilength; float length, ilength;
length = Vector3Length(v);
length = Vector3Length(*v);
if (length == 0.0f) length = 1.0f; if (length == 0.0f) length = 1.0f;
ilength = 1.0f/length; ilength = 1.0f/length;
v->x *= ilength; result.x *= ilength;
v->y *= ilength; result.y *= ilength;
v->z *= ilength; result.z *= ilength;
return result;
} }
// Transforms a Vector3 by a given Matrix // Transforms a Vector3 by a given Matrix
RMDEF void Vector3Transform(Vector3 *v, Matrix mat) RMDEF Vector3 Vector3Transform(Vector3 v, Matrix mat)
{ {
float x = v->x; Vector3 result = { 0 };
float y = v->y; float x = v.x;
float z = v->z; float y = v.y;
float z = v.z;
v->x = mat.m0*x + mat.m4*y + mat.m8*z + mat.m12; result.x = mat.m0*x + mat.m4*y + mat.m8*z + mat.m12;
v->y = mat.m1*x + mat.m5*y + mat.m9*z + mat.m13; result.y = mat.m1*x + mat.m5*y + mat.m9*z + mat.m13;
v->z = mat.m2*x + mat.m6*y + mat.m10*z + mat.m14; result.z = mat.m2*x + mat.m6*y + mat.m10*z + mat.m14;
return result;
}; };
// Calculate linear interpolation between two vectors // Calculate linear interpolation between two vectors
RMDEF Vector3 Vector3Lerp(Vector3 v1, Vector3 v2, float amount) RMDEF Vector3 Vector3Lerp(Vector3 v1, Vector3 v2, float amount)
{ {
Vector3 result; Vector3 result = { 0 };
result.x = v1.x + amount*(v2.x - v1.x); result.x = v1.x + amount*(v2.x - v1.x);
result.y = v1.y + amount*(v2.y - v1.y); result.y = v1.y + amount*(v2.y - v1.y);
@ -398,43 +396,43 @@ RMDEF Vector3 Vector3Lerp(Vector3 v1, Vector3 v2, float amount)
} }
// Calculate reflected vector to normal // Calculate reflected vector to normal
RMDEF Vector3 Vector3Reflect(Vector3 vector, Vector3 normal) RMDEF Vector3 Vector3Reflect(Vector3 v, Vector3 normal)
{ {
// I is the original vector // I is the original vector
// N is the normal of the incident plane // N is the normal of the incident plane
// R = I - (2*N*( DotProduct[ I,N] )) // R = I - (2*N*( DotProduct[ I,N] ))
Vector3 result; Vector3 result = { 0 };
float dotProduct = Vector3DotProduct(vector, normal); float dotProduct = Vector3DotProduct(v, normal);
result.x = vector.x - (2.0f*normal.x)*dotProduct; result.x = v.x - (2.0f*normal.x)*dotProduct;
result.y = vector.y - (2.0f*normal.y)*dotProduct; result.y = v.y - (2.0f*normal.y)*dotProduct;
result.z = vector.z - (2.0f*normal.z)*dotProduct; result.z = v.z - (2.0f*normal.z)*dotProduct;
return result; return result;
} }
// Return min value for each pair of components // Return min value for each pair of components
RMDEF Vector3 Vector3Min(Vector3 vec1, Vector3 vec2) RMDEF Vector3 Vector3Min(Vector3 v1, Vector3 v2)
{ {
Vector3 result; Vector3 result = { 0 };
result.x = fminf(vec1.x, vec2.x); result.x = fminf(v1.x, v2.x);
result.y = fminf(vec1.y, vec2.y); result.y = fminf(v1.y, v2.y);
result.z = fminf(vec1.z, vec2.z); result.z = fminf(v1.z, v2.z);
return result; return result;
} }
// Return max value for each pair of components // Return max value for each pair of components
RMDEF Vector3 Vector3Max(Vector3 vec1, Vector3 vec2) RMDEF Vector3 Vector3Max(Vector3 v1, Vector3 v2)
{ {
Vector3 result; Vector3 result = { 0 };
result.x = fmaxf(vec1.x, vec2.x); result.x = fmaxf(v1.x, v2.x);
result.y = fmaxf(vec1.y, vec2.y); result.y = fmaxf(v1.y, v2.y);
result.z = fmaxf(vec1.z, vec2.z); result.z = fmaxf(v1.z, v2.z);
return result; return result;
} }
@ -456,7 +454,7 @@ RMDEF Vector3 Vector3Barycenter(Vector3 p, Vector3 a, Vector3 b, Vector3 c)
float denom = d00*d11 - d01*d01; float denom = d00*d11 - d01*d01;
Vector3 result; Vector3 result = { 0 };
result.y = (d11*d20 - d01*d21)/denom; result.y = (d11*d20 - d01*d21)/denom;
result.z = (d00*d21 - d01*d20)/denom; result.z = (d00*d21 - d01*d20)/denom;
@ -466,19 +464,16 @@ RMDEF Vector3 Vector3Barycenter(Vector3 p, Vector3 a, Vector3 b, Vector3 c)
} }
// Returns Vector3 as float array // Returns Vector3 as float array
RMDEF float3 Vector3ToFloat_(Vector3 vec) RMDEF float3 Vector3ToFloatV(Vector3 v)
{ {
float3 buffer; float3 buffer = { 0 };
buffer.v[0] = vec.x; buffer.v[0] = v.x;
buffer.v[1] = vec.y; buffer.v[1] = v.y;
buffer.v[2] = vec.z; buffer.v[2] = v.z;
return buffer; return buffer;
} }
#ifndef Vector3ToFloat
#define Vector3ToFloat(vec) (Vector3ToFloat_(vec).v)
#endif
//---------------------------------------------------------------------------------- //----------------------------------------------------------------------------------
// Module Functions Definition - Matrix math // Module Functions Definition - Matrix math
@ -487,7 +482,7 @@ RMDEF float3 Vector3ToFloat_(Vector3 vec)
// Compute matrix determinant // Compute matrix determinant
RMDEF float MatrixDeterminant(Matrix mat) RMDEF float MatrixDeterminant(Matrix mat)
{ {
float result; float result = { 0 };
// Cache the matrix values (speed optimization) // Cache the matrix values (speed optimization)
float a00 = mat.m0, a01 = mat.m1, a02 = mat.m2, a03 = mat.m3; float a00 = mat.m0, a01 = mat.m1, a02 = mat.m2, a03 = mat.m3;
@ -508,44 +503,45 @@ RMDEF float MatrixDeterminant(Matrix mat)
// Returns the trace of the matrix (sum of the values along the diagonal) // Returns the trace of the matrix (sum of the values along the diagonal)
RMDEF float MatrixTrace(Matrix mat) RMDEF float MatrixTrace(Matrix mat)
{ {
return (mat.m0 + mat.m5 + mat.m10 + mat.m15); float result = (mat.m0 + mat.m5 + mat.m10 + mat.m15);
return result;
} }
// Transposes provided matrix // Transposes provided matrix
RMDEF void MatrixTranspose(Matrix *mat) RMDEF Matrix MatrixTranspose(Matrix mat)
{ {
Matrix temp; Matrix result = { 0 };
temp.m0 = mat->m0; result.m0 = mat.m0;
temp.m1 = mat->m4; result.m1 = mat.m4;
temp.m2 = mat->m8; result.m2 = mat.m8;
temp.m3 = mat->m12; result.m3 = mat.m12;
temp.m4 = mat->m1; result.m4 = mat.m1;
temp.m5 = mat->m5; result.m5 = mat.m5;
temp.m6 = mat->m9; result.m6 = mat.m9;
temp.m7 = mat->m13; result.m7 = mat.m13;
temp.m8 = mat->m2; result.m8 = mat.m2;
temp.m9 = mat->m6; result.m9 = mat.m6;
temp.m10 = mat->m10; result.m10 = mat.m10;
temp.m11 = mat->m14; result.m11 = mat.m14;
temp.m12 = mat->m3; result.m12 = mat.m3;
temp.m13 = mat->m7; result.m13 = mat.m7;
temp.m14 = mat->m11; result.m14 = mat.m11;
temp.m15 = mat->m15; result.m15 = mat.m15;
*mat = temp; return result;
} }
// Invert provided matrix // Invert provided matrix
RMDEF void MatrixInvert(Matrix *mat) RMDEF Matrix MatrixInvert(Matrix mat)
{ {
Matrix temp; Matrix result = { 0 };
// Cache the matrix values (speed optimization) // Cache the matrix values (speed optimization)
float a00 = mat->m0, a01 = mat->m1, a02 = mat->m2, a03 = mat->m3; float a00 = mat.m0, a01 = mat.m1, a02 = mat.m2, a03 = mat.m3;
float a10 = mat->m4, a11 = mat->m5, a12 = mat->m6, a13 = mat->m7; float a10 = mat.m4, a11 = mat.m5, a12 = mat.m6, a13 = mat.m7;
float a20 = mat->m8, a21 = mat->m9, a22 = mat->m10, a23 = mat->m11; float a20 = mat.m8, a21 = mat.m9, a22 = mat.m10, a23 = mat.m11;
float a30 = mat->m12, a31 = mat->m13, a32 = mat->m14, a33 = mat->m15; float a30 = mat.m12, a31 = mat.m13, a32 = mat.m14, a33 = mat.m15;
float b00 = a00*a11 - a01*a10; float b00 = a00*a11 - a01*a10;
float b01 = a00*a12 - a02*a10; float b01 = a00*a12 - a02*a10;
@ -563,47 +559,51 @@ RMDEF void MatrixInvert(Matrix *mat)
// Calculate the invert determinant (inlined to avoid double-caching) // Calculate the invert determinant (inlined to avoid double-caching)
float invDet = 1.0f/(b00*b11 - b01*b10 + b02*b09 + b03*b08 - b04*b07 + b05*b06); float invDet = 1.0f/(b00*b11 - b01*b10 + b02*b09 + b03*b08 - b04*b07 + b05*b06);
temp.m0 = (a11*b11 - a12*b10 + a13*b09)*invDet; result.m0 = (a11*b11 - a12*b10 + a13*b09)*invDet;
temp.m1 = (-a01*b11 + a02*b10 - a03*b09)*invDet; result.m1 = (-a01*b11 + a02*b10 - a03*b09)*invDet;
temp.m2 = (a31*b05 - a32*b04 + a33*b03)*invDet; result.m2 = (a31*b05 - a32*b04 + a33*b03)*invDet;
temp.m3 = (-a21*b05 + a22*b04 - a23*b03)*invDet; result.m3 = (-a21*b05 + a22*b04 - a23*b03)*invDet;
temp.m4 = (-a10*b11 + a12*b08 - a13*b07)*invDet; result.m4 = (-a10*b11 + a12*b08 - a13*b07)*invDet;
temp.m5 = (a00*b11 - a02*b08 + a03*b07)*invDet; result.m5 = (a00*b11 - a02*b08 + a03*b07)*invDet;
temp.m6 = (-a30*b05 + a32*b02 - a33*b01)*invDet; result.m6 = (-a30*b05 + a32*b02 - a33*b01)*invDet;
temp.m7 = (a20*b05 - a22*b02 + a23*b01)*invDet; result.m7 = (a20*b05 - a22*b02 + a23*b01)*invDet;
temp.m8 = (a10*b10 - a11*b08 + a13*b06)*invDet; result.m8 = (a10*b10 - a11*b08 + a13*b06)*invDet;
temp.m9 = (-a00*b10 + a01*b08 - a03*b06)*invDet; result.m9 = (-a00*b10 + a01*b08 - a03*b06)*invDet;
temp.m10 = (a30*b04 - a31*b02 + a33*b00)*invDet; result.m10 = (a30*b04 - a31*b02 + a33*b00)*invDet;
temp.m11 = (-a20*b04 + a21*b02 - a23*b00)*invDet; result.m11 = (-a20*b04 + a21*b02 - a23*b00)*invDet;
temp.m12 = (-a10*b09 + a11*b07 - a12*b06)*invDet; result.m12 = (-a10*b09 + a11*b07 - a12*b06)*invDet;
temp.m13 = (a00*b09 - a01*b07 + a02*b06)*invDet; result.m13 = (a00*b09 - a01*b07 + a02*b06)*invDet;
temp.m14 = (-a30*b03 + a31*b01 - a32*b00)*invDet; result.m14 = (-a30*b03 + a31*b01 - a32*b00)*invDet;
temp.m15 = (a20*b03 - a21*b01 + a22*b00)*invDet; result.m15 = (a20*b03 - a21*b01 + a22*b00)*invDet;
*mat = temp; return result;
} }
// Normalize provided matrix // Normalize provided matrix
RMDEF void MatrixNormalize(Matrix *mat) RMDEF Matrix MatrixNormalize(Matrix mat)
{ {
float det = MatrixDeterminant(*mat); Matrix result = { 0 };
float det = MatrixDeterminant(mat);
mat->m0 /= det; result.m0 = mat.m0/det;
mat->m1 /= det; result.m1 = mat.m1/det;
mat->m2 /= det; result.m2 = mat.m2/det;
mat->m3 /= det; result.m3 = mat.m3/det;
mat->m4 /= det; result.m4 = mat.m4/det;
mat->m5 /= det; result.m5 = mat.m5/det;
mat->m6 /= det; result.m6 = mat.m6/det;
mat->m7 /= det; result.m7 = mat.m7/det;
mat->m8 /= det; result.m8 = mat.m8/det;
mat->m9 /= det; result.m9 = mat.m9/det;
mat->m10 /= det; result.m10 = mat.m10/det;
mat->m11 /= det; result.m11 = mat.m11/det;
mat->m12 /= det; result.m12 = mat.m12/det;
mat->m13 /= det; result.m13 = mat.m13/det;
mat->m14 /= det; result.m14 = mat.m14/det;
mat->m15 /= det; result.m15 = mat.m15/det;
return result;
} }
// Returns identity matrix // Returns identity matrix
@ -682,7 +682,7 @@ RMDEF Matrix MatrixTranslate(float x, float y, float z)
// NOTE: Angle should be provided in radians // NOTE: Angle should be provided in radians
RMDEF Matrix MatrixRotate(Vector3 axis, float angle) RMDEF Matrix MatrixRotate(Vector3 axis, float angle)
{ {
Matrix result; Matrix result = { 0 };
float x = axis.x, y = axis.y, z = axis.z; float x = axis.x, y = axis.y, z = axis.z;
@ -786,7 +786,7 @@ RMDEF Matrix MatrixScale(float x, float y, float z)
// NOTE: When multiplying matrices... the order matters! // NOTE: When multiplying matrices... the order matters!
RMDEF Matrix MatrixMultiply(Matrix left, Matrix right) RMDEF Matrix MatrixMultiply(Matrix left, Matrix right)
{ {
Matrix result; Matrix result = { 0 };
result.m0 = left.m0*right.m0 + left.m1*right.m4 + left.m2*right.m8 + left.m3*right.m12; result.m0 = left.m0*right.m0 + left.m1*right.m4 + left.m2*right.m8 + left.m3*right.m12;
result.m1 = left.m0*right.m1 + left.m1*right.m5 + left.m2*right.m9 + left.m3*right.m13; result.m1 = left.m0*right.m1 + left.m1*right.m5 + left.m2*right.m9 + left.m3*right.m13;
@ -811,7 +811,7 @@ RMDEF Matrix MatrixMultiply(Matrix left, Matrix right)
// Returns perspective projection matrix // Returns perspective projection matrix
RMDEF Matrix MatrixFrustum(double left, double right, double bottom, double top, double near, double far) RMDEF Matrix MatrixFrustum(double left, double right, double bottom, double top, double near, double far)
{ {
Matrix result; Matrix result = { 0 };
float rl = (right - left); float rl = (right - left);
float tb = (top - bottom); float tb = (top - bottom);
@ -846,14 +846,15 @@ RMDEF Matrix MatrixPerspective(double fovy, double aspect, double near, double f
{ {
double top = near*tan(fovy*0.5); double top = near*tan(fovy*0.5);
double right = top*aspect; double right = top*aspect;
Matrix result = MatrixFrustum(-right, right, -top, top, near, far);
return MatrixFrustum(-right, right, -top, top, near, far); return result;
} }
// Returns orthographic projection matrix // Returns orthographic projection matrix
RMDEF Matrix MatrixOrtho(double left, double right, double bottom, double top, double near, double far) RMDEF Matrix MatrixOrtho(double left, double right, double bottom, double top, double near, double far)
{ {
Matrix result; Matrix result = { 0 };
float rl = (right - left); float rl = (right - left);
float tb = (top - bottom); float tb = (top - bottom);
@ -882,14 +883,14 @@ RMDEF Matrix MatrixOrtho(double left, double right, double bottom, double top, d
// Returns camera look-at matrix (view matrix) // Returns camera look-at matrix (view matrix)
RMDEF Matrix MatrixLookAt(Vector3 eye, Vector3 target, Vector3 up) RMDEF Matrix MatrixLookAt(Vector3 eye, Vector3 target, Vector3 up)
{ {
Matrix result; Matrix result = { 0 };
Vector3 z = Vector3Subtract(eye, target); Vector3 z = Vector3Subtract(eye, target);
Vector3Normalize(&z); z = Vector3Normalize(z);
Vector3 x = Vector3CrossProduct(up, z); Vector3 x = Vector3CrossProduct(up, z);
Vector3Normalize(&x); x = Vector3Normalize(x);
Vector3 y = Vector3CrossProduct(z, x); Vector3 y = Vector3CrossProduct(z, x);
Vector3Normalize(&y); y = Vector3Normalize(y);
result.m0 = x.x; result.m0 = x.x;
result.m1 = x.y; result.m1 = x.y;
@ -908,7 +909,7 @@ RMDEF Matrix MatrixLookAt(Vector3 eye, Vector3 target, Vector3 up)
result.m14 = eye.z; result.m14 = eye.z;
result.m15 = 1.0f; result.m15 = 1.0f;
MatrixInvert(&result); result = MatrixInvert(result);
return result; return result;
} }
@ -916,7 +917,7 @@ RMDEF Matrix MatrixLookAt(Vector3 eye, Vector3 target, Vector3 up)
// Returns float array of matrix data // Returns float array of matrix data
RMDEF float16 MatrixToFloatV(Matrix mat) RMDEF float16 MatrixToFloatV(Matrix mat)
{ {
float16 buffer; float16 buffer = { 0 };
buffer.v[0] = mat.m0; buffer.v[0] = mat.m0;
buffer.v[1] = mat.m1; buffer.v[1] = mat.m1;
@ -945,54 +946,59 @@ RMDEF float16 MatrixToFloatV(Matrix mat)
// Returns identity quaternion // Returns identity quaternion
RMDEF Quaternion QuaternionIdentity(void) RMDEF Quaternion QuaternionIdentity(void)
{ {
Quaternion q = { 0.0f, 0.0f, 0.0f, 1.0f }; Quaternion result = { 0.0f, 0.0f, 0.0f, 1.0f };
return q; return result;
} }
// Computes the length of a quaternion // Computes the length of a quaternion
RMDEF float QuaternionLength(Quaternion quat) RMDEF float QuaternionLength(Quaternion q)
{ {
return sqrt(quat.x*quat.x + quat.y*quat.y + quat.z*quat.z + quat.w*quat.w); float result = sqrt(q.x*q.x + q.y*q.y + q.z*q.z + q.w*q.w);
return result;
} }
// Normalize provided quaternion // Normalize provided quaternion
RMDEF void QuaternionNormalize(Quaternion *q) RMDEF Quaternion QuaternionNormalize(Quaternion q)
{ {
Quaternion result = { 0 };
float length, ilength; float length, ilength;
length = QuaternionLength(q);
length = QuaternionLength(*q);
if (length == 0.0f) length = 1.0f; if (length == 0.0f) length = 1.0f;
ilength = 1.0f/length; ilength = 1.0f/length;
q->x *= ilength; result.x = q.x*ilength;
q->y *= ilength; result.y = q.y*ilength;
q->z *= ilength; result.z = q.z*ilength;
q->w *= ilength; result.w = q.w*ilength;
return result;
} }
// Invert provided quaternion // Invert provided quaternion
RMDEF void QuaternionInvert(Quaternion *quat) RMDEF Quaternion QuaternionInvert(Quaternion q)
{ {
float length = QuaternionLength(*quat); Quaternion result = q;
float length = QuaternionLength(q);
float lengthSq = length*length; float lengthSq = length*length;
if (lengthSq != 0.0) if (lengthSq != 0.0)
{ {
float i = 1.0f/lengthSq; float i = 1.0f/lengthSq;
quat->x *= -i; result.x *= -i;
quat->y *= -i; result.y *= -i;
quat->z *= -i; result.z *= -i;
quat->w *= i; result.w *= i;
} }
return result;
} }
// Calculate two quaternion multiplication // Calculate two quaternion multiplication
RMDEF Quaternion QuaternionMultiply(Quaternion q1, Quaternion q2) RMDEF Quaternion QuaternionMultiply(Quaternion q1, Quaternion q2)
{ {
Quaternion result; Quaternion result = { 0 };
float qax = q1.x, qay = q1.y, qaz = q1.z, qaw = q1.w; float qax = q1.x, qay = q1.y, qaz = q1.z, qaw = q1.w;
float qbx = q2.x, qby = q2.y, qbz = q2.z, qbw = q2.w; float qbx = q2.x, qby = q2.y, qbz = q2.z, qbw = q2.w;
@ -1008,7 +1014,7 @@ RMDEF Quaternion QuaternionMultiply(Quaternion q1, Quaternion q2)
// Calculate linear interpolation between two quaternions // Calculate linear interpolation between two quaternions
RMDEF Quaternion QuaternionLerp(Quaternion q1, Quaternion q2, float amount) RMDEF Quaternion QuaternionLerp(Quaternion q1, Quaternion q2, float amount)
{ {
Quaternion result; Quaternion result = { 0 };
result.x = q1.x + amount*(q2.x - q1.x); result.x = q1.x + amount*(q2.x - q1.x);
result.y = q1.y + amount*(q2.y - q1.y); result.y = q1.y + amount*(q2.y - q1.y);
@ -1022,7 +1028,7 @@ RMDEF Quaternion QuaternionLerp(Quaternion q1, Quaternion q2, float amount)
RMDEF Quaternion QuaternionNlerp(Quaternion q1, Quaternion q2, float amount) RMDEF Quaternion QuaternionNlerp(Quaternion q1, Quaternion q2, float amount)
{ {
Quaternion result = QuaternionLerp(q1, q2, amount); Quaternion result = QuaternionLerp(q1, q2, amount);
QuaternionNormalize(&result); result = QuaternionNormalize(result);
return result; return result;
} }
@ -1030,7 +1036,7 @@ RMDEF Quaternion QuaternionNlerp(Quaternion q1, Quaternion q2, float amount)
// Calculates spherical linear interpolation between two quaternions // Calculates spherical linear interpolation between two quaternions
RMDEF Quaternion QuaternionSlerp(Quaternion q1, Quaternion q2, float amount) RMDEF Quaternion QuaternionSlerp(Quaternion q1, Quaternion q2, float amount)
{ {
Quaternion result; Quaternion result = { 0 };
float cosHalfTheta = q1.x*q2.x + q1.y*q2.y + q1.z*q2.z + q1.w*q2.w; float cosHalfTheta = q1.x*q2.x + q1.y*q2.y + q1.z*q2.z + q1.w*q2.w;
@ -1066,31 +1072,31 @@ RMDEF Quaternion QuaternionSlerp(Quaternion q1, Quaternion q2, float amount)
// Calculate quaternion based on the rotation from one vector to another // Calculate quaternion based on the rotation from one vector to another
RMDEF Quaternion QuaternionFromVector3ToVector3(Vector3 from, Vector3 to) RMDEF Quaternion QuaternionFromVector3ToVector3(Vector3 from, Vector3 to)
{ {
Quaternion q = { 0 }; Quaternion result = { 0 };
float cos2Theta = Vector3DotProduct(from, to); float cos2Theta = Vector3DotProduct(from, to);
Vector3 cross = Vector3CrossProduct(from, to); Vector3 cross = Vector3CrossProduct(from, to);
q.x = cross.x; result.x = cross.x;
q.y = cross.y; result.y = cross.y;
q.z = cross.y; result.z = cross.y;
q.w = 1.0f + cos2Theta; // NOTE: Added QuaternioIdentity() result.w = 1.0f + cos2Theta; // NOTE: Added QuaternioIdentity()
// Normalize to essentially nlerp the original and identity to 0.5 // Normalize to essentially nlerp the original and identity to 0.5
QuaternionNormalize(&q); result = QuaternionNormalize(result);
// Above lines are equivalent to: // Above lines are equivalent to:
//Quaternion result = QuaternionNlerp(q, QuaternionIdentity(), 0.5f); //Quaternion result = QuaternionNlerp(q, QuaternionIdentity(), 0.5f);
return q; return result;
} }
// Returns a quaternion for a given rotation matrix // Returns a quaternion for a given rotation matrix
RMDEF Quaternion QuaternionFromMatrix(Matrix matrix) RMDEF Quaternion QuaternionFromMatrix(Matrix mat)
{ {
Quaternion result; Quaternion result = { 0 };
float trace = MatrixTrace(matrix); float trace = MatrixTrace(mat);
if (trace > 0.0f) if (trace > 0.0f)
{ {
@ -1098,42 +1104,42 @@ RMDEF Quaternion QuaternionFromMatrix(Matrix matrix)
float invS = 1.0f/s; float invS = 1.0f/s;
result.w = s*0.25f; result.w = s*0.25f;
result.x = (matrix.m6 - matrix.m9)*invS; result.x = (mat.m6 - mat.m9)*invS;
result.y = (matrix.m8 - matrix.m2)*invS; result.y = (mat.m8 - mat.m2)*invS;
result.z = (matrix.m1 - matrix.m4)*invS; result.z = (mat.m1 - mat.m4)*invS;
} }
else else
{ {
float m00 = matrix.m0, m11 = matrix.m5, m22 = matrix.m10; float m00 = mat.m0, m11 = mat.m5, m22 = mat.m10;
if (m00 > m11 && m00 > m22) if (m00 > m11 && m00 > m22)
{ {
float s = (float)sqrt(1.0f + m00 - m11 - m22)*2.0f; float s = (float)sqrt(1.0f + m00 - m11 - m22)*2.0f;
float invS = 1.0f/s; float invS = 1.0f/s;
result.w = (matrix.m6 - matrix.m9)*invS; result.w = (mat.m6 - mat.m9)*invS;
result.x = s*0.25f; result.x = s*0.25f;
result.y = (matrix.m4 + matrix.m1)*invS; result.y = (mat.m4 + mat.m1)*invS;
result.z = (matrix.m8 + matrix.m2)*invS; result.z = (mat.m8 + mat.m2)*invS;
} }
else if (m11 > m22) else if (m11 > m22)
{ {
float s = (float)sqrt(1.0f + m11 - m00 - m22)*2.0f; float s = (float)sqrt(1.0f + m11 - m00 - m22)*2.0f;
float invS = 1.0f/s; float invS = 1.0f/s;
result.w = (matrix.m8 - matrix.m2)*invS; result.w = (mat.m8 - mat.m2)*invS;
result.x = (matrix.m4 + matrix.m1)*invS; result.x = (mat.m4 + mat.m1)*invS;
result.y = s*0.25f; result.y = s*0.25f;
result.z = (matrix.m9 + matrix.m6)*invS; result.z = (mat.m9 + mat.m6)*invS;
} }
else else
{ {
float s = (float)sqrt(1.0f + m22 - m00 - m11)*2.0f; float s = (float)sqrt(1.0f + m22 - m00 - m11)*2.0f;
float invS = 1.0f/s; float invS = 1.0f/s;
result.w = (matrix.m1 - matrix.m4)*invS; result.w = (mat.m1 - mat.m4)*invS;
result.x = (matrix.m8 + matrix.m2)*invS; result.x = (mat.m8 + mat.m2)*invS;
result.y = (matrix.m9 + matrix.m6)*invS; result.y = (mat.m9 + mat.m6)*invS;
result.z = s*0.25f; result.z = s*0.25f;
} }
} }
@ -1144,7 +1150,7 @@ RMDEF Quaternion QuaternionFromMatrix(Matrix matrix)
// Returns a matrix for a given quaternion // Returns a matrix for a given quaternion
RMDEF Matrix QuaternionToMatrix(Quaternion q) RMDEF Matrix QuaternionToMatrix(Quaternion q)
{ {
Matrix result; Matrix result = { 0 };
float x = q.x, y = q.y, z = q.z, w = q.w; float x = q.x, y = q.y, z = q.z, w = q.w;
@ -1197,7 +1203,7 @@ RMDEF Quaternion QuaternionFromAxisAngle(Vector3 axis, float angle)
angle *= 0.5f; angle *= 0.5f;
Vector3Normalize(&axis); axis = Vector3Normalize(axis);
float sinres = sinf(angle); float sinres = sinf(angle);
float cosres = cosf(angle); float cosres = cosf(angle);
@ -1207,7 +1213,7 @@ RMDEF Quaternion QuaternionFromAxisAngle(Vector3 axis, float angle)
result.z = axis.z*sinres; result.z = axis.z*sinres;
result.w = cosres; result.w = cosres;
QuaternionNormalize(&result); result = QuaternionNormalize(result);
return result; return result;
} }
@ -1215,7 +1221,7 @@ RMDEF Quaternion QuaternionFromAxisAngle(Vector3 axis, float angle)
// Returns the rotation angle and axis for a given quaternion // Returns the rotation angle and axis for a given quaternion
RMDEF void QuaternionToAxisAngle(Quaternion q, Vector3 *outAxis, float *outAngle) RMDEF void QuaternionToAxisAngle(Quaternion q, Vector3 *outAxis, float *outAngle)
{ {
if (fabs(q.w) > 1.0f) QuaternionNormalize(&q); if (fabs(q.w) > 1.0f) q = QuaternionNormalize(q);
Vector3 resAxis = { 0.0f, 0.0f, 0.0f }; Vector3 resAxis = { 0.0f, 0.0f, 0.0f };
float resAngle = 0.0f; float resAngle = 0.0f;
@ -1264,39 +1270,38 @@ RMDEF Quaternion QuaternionFromEuler(float roll, float pitch, float yaw)
// NOTE: Angles are returned in a Vector3 struct in degrees // NOTE: Angles are returned in a Vector3 struct in degrees
RMDEF Vector3 QuaternionToEuler(Quaternion q) RMDEF Vector3 QuaternionToEuler(Quaternion q)
{ {
Vector3 v = { 0 }; Vector3 result = { 0 };
// roll (x-axis rotation) // roll (x-axis rotation)
float x0 = 2.0f*(q.w*q.x + q.y*q.z); float x0 = 2.0f*(q.w*q.x + q.y*q.z);
float x1 = 1.0f - 2.0f*(q.x*q.x + q.y*q.y); float x1 = 1.0f - 2.0f*(q.x*q.x + q.y*q.y);
v.x = atan2f(x0, x1)*RAD2DEG; result.x = atan2f(x0, x1)*RAD2DEG;
// pitch (y-axis rotation) // pitch (y-axis rotation)
float y0 = 2.0f*(q.w*q.y - q.z*q.x); float y0 = 2.0f*(q.w*q.y - q.z*q.x);
y0 = y0 > 1.0f ? 1.0f : y0; y0 = y0 > 1.0f ? 1.0f : y0;
y0 = y0 < -1.0f ? -1.0f : y0; y0 = y0 < -1.0f ? -1.0f : y0;
v.y = asinf(y0)*RAD2DEG; result.y = asinf(y0)*RAD2DEG;
// yaw (z-axis rotation) // yaw (z-axis rotation)
float z0 = 2.0f*(q.w*q.z + q.x*q.y); float z0 = 2.0f*(q.w*q.z + q.x*q.y);
float z1 = 1.0f - 2.0f*(q.y*q.y + q.z*q.z); float z1 = 1.0f - 2.0f*(q.y*q.y + q.z*q.z);
v.z = atan2f(z0, z1)*RAD2DEG; result.z = atan2f(z0, z1)*RAD2DEG;
return v; return result;
} }
// Transform a quaternion given a transformation matrix // Transform a quaternion given a transformation matrix
RMDEF void QuaternionTransform(Quaternion *q, Matrix mat) RMDEF Quaternion QuaternionTransform(Quaternion q, Matrix mat)
{ {
float x = q->x; Quaternion result = { 0 };
float y = q->y;
float z = q->z;
float w = q->w;
q->x = mat.m0*x + mat.m4*y + mat.m8*z + mat.m12*w; result.x = mat.m0*q.x + mat.m4*q.y + mat.m8*q.z + mat.m12*q.w;
q->y = mat.m1*x + mat.m5*y + mat.m9*z + mat.m13*w; result.y = mat.m1*q.x + mat.m5*q.y + mat.m9*q.z + mat.m13*q.w;
q->z = mat.m2*x + mat.m6*y + mat.m10*z + mat.m14*w; result.z = mat.m2*q.x + mat.m6*q.y + mat.m10*q.z + mat.m14*q.w;
q->w = mat.m3*x + mat.m7*y + mat.m11*z + mat.m15*w; result.w = mat.m3*q.x + mat.m7*q.y + mat.m11*q.z + mat.m15*q.w;
return result;
} }
#endif // RAYMATH_H #endif // RAYMATH_H

View file

@ -470,7 +470,7 @@ void rlRotatef(float angleDeg, float x, float y, float z)
Matrix matRotation = MatrixIdentity(); Matrix matRotation = MatrixIdentity();
Vector3 axis = (Vector3){ x, y, z }; Vector3 axis = (Vector3){ x, y, z };
Vector3Normalize(&axis); axis = Vector3Normalize(axis);
matRotation = MatrixRotate(axis, angleDeg*DEG2RAD); matRotation = MatrixRotate(axis, angleDeg*DEG2RAD);
// NOTE: We transpose matrix with multiplication order // NOTE: We transpose matrix with multiplication order
@ -570,7 +570,7 @@ void rlEnd(void)
// This way, rlTranslatef(), rlRotatef()... behaviour is the same than OpenGL 1.1 // This way, rlTranslatef(), rlRotatef()... behaviour is the same than OpenGL 1.1
// Apply transformation matrix to all temp vertices // Apply transformation matrix to all temp vertices
for (int i = 0; i < tempBufferCount; i++) Vector3Transform(&tempBuffer[i], *currentMatrix); for (int i = 0; i < tempBufferCount; i++) tempBuffer[i] = Vector3Transform(tempBuffer[i], *currentMatrix);
// Deactivate tempBuffer usage to allow rlVertex3f do its job // Deactivate tempBuffer usage to allow rlVertex3f do its job
useTempBuffer = false; useTempBuffer = false;
@ -1356,13 +1356,13 @@ Vector3 rlUnproject(Vector3 source, Matrix proj, Matrix view)
// Calculate unproject matrix (multiply view patrix by projection matrix) and invert it // Calculate unproject matrix (multiply view patrix by projection matrix) and invert it
Matrix matViewProj = MatrixMultiply(view, proj); Matrix matViewProj = MatrixMultiply(view, proj);
MatrixInvert(&matViewProj); matViewProj= MatrixInvert(matViewProj);
// Create quaternion from source point // Create quaternion from source point
Quaternion quat = { source.x, source.y, source.z, 1.0f }; Quaternion quat = { source.x, source.y, source.z, 1.0f };
// Multiply quat point by unproject matrix // Multiply quat point by unproject matrix
QuaternionTransform(&quat, matViewProj); quat = QuaternionTransform(quat, matViewProj);
// Normalized world points in vectors // Normalized world points in vectors
result.x = quat.x/quat.w; result.x = quat.x/quat.w;