A RPG I'm messing with made in Raylib.

init

Clay 81f1da76

+14
.clang-format
··· 1 + BasedOnStyle: GNU 2 + IndentWidth: 4 3 + TabWidth: 4 4 + UseTab: Never 5 + AlignAfterOpenBracket: BlockIndent 6 + ColumnLimit: 0 7 + PenaltyReturnTypeOnItsOwnLine: 0 8 + BreakAfterReturnType: Automatic 9 + SpaceBeforeParens: Custom 10 + BreakBeforeBraces: Custom 11 + BraceWrapping: 12 + AfterEnum: true 13 + AfterStruct: false 14 + SplitEmptyFunction: false
+1
.gitignore
··· 1 + rpg
+9
Makefile
··· 1 + SRC_FILES := $(shell find src -name '*.c') 2 + 3 + all: default 4 + 5 + default: $(SRC_FILES) 6 + gcc -o rpg $(SRC_FILES) -L/usr/local/lib -lraylib -lGL -lm -lpthread -ldl -lrt -lX11 7 + 8 + debug: $(SRC_FILES) 9 + gcc -o rpg $(SRC_FILES) -DDEBUG -L/usr/local/lib -lraylib -lGL -lm -lpthread -ldl -lrt -lX11
assets/textures/player/falling.png

This is a binary file and will not be displayed.

assets/textures/player/stand-forward.png

This is a binary file and will not be displayed.

assets/textures/player/walk-backward.png

This is a binary file and will not be displayed.

assets/textures/player/walk-forward.png

This is a binary file and will not be displayed.

assets/textures/player/walk-left.png

This is a binary file and will not be displayed.

assets/textures/player/walk-right.png

This is a binary file and will not be displayed.

+22
include/animated_texture.h
··· 1 + #ifndef ANIMATED_TEXURE_H 2 + #define ANIMATED_TEXURE_H 3 + #include "raylib.h" 4 + #include "raymath.h" 5 + 6 + typedef struct { 7 + unsigned int number_of_frames; 8 + Rectangle current_frame; 9 + int step; 10 + 11 + float speed; 12 + float duration_left; 13 + 14 + Texture2D texture; 15 + } AnimatedTexture; 16 + 17 + AnimatedTexture animated_texture_create(const char *file_path, int number_of_frames, float speed); 18 + int animated_texture_delete(AnimatedTexture animated_texture); 19 + void animated_texture_update(AnimatedTexture *animated_texture); 20 + void animated_texture_draw(AnimatedTexture *animated_texture, Vector2 position, Color tint); 21 + 22 + #endif
+11
include/config.h
··· 1 + #ifndef CONFIG_H 2 + #define CONFIG_H 3 + 4 + #include "raylib.h" 5 + 6 + #define WINDOW_WIDTH 1920.0f 7 + #define WINDOW_HEIGHT 1080.0f 8 + #define WINDOW_SIZE \ 9 + (Vector2) { WINDOW_WIDTH, WINDOW_HEIGHT } 10 + 11 + #endif
+40
include/player.h
··· 1 + #ifndef PLAYER_H 2 + #define PLAYER_H 3 + 4 + #include "animated_texture.h" 5 + #include "player_state/player_state.h" 6 + #include "raylib.h" 7 + 8 + typedef enum 9 + { 10 + PLAYER_TEXTURE_FORWARD, 11 + PLAYER_TEXTURE_WALK_FORWARD, 12 + PLAYER_TEXTURE_BACKWARD, 13 + PLAYER_TEXTURE_WALK_BACKWARD, 14 + PLAYER_TEXTURE_LEFT, 15 + PLAYER_TEXTURE_WALK_LEFT, 16 + PLAYER_TEXTURE_RIGHT, 17 + PLAYER_TEXTURE_WALK_RIGHT, 18 + PLAYER_TEXTURE_FALLING, 19 + _PLAYER_TEXTURE_LENGTH 20 + } PlayerTexture; 21 + 22 + typedef struct Player { 23 + Camera2D camera; 24 + Vector2 position; 25 + Vector2 velocity; 26 + Vector2 control; 27 + float speed; 28 + float friction; 29 + AnimatedTexture texture; 30 + AnimatedTexture textures[_PLAYER_TEXTURE_LENGTH]; 31 + PlayerState state; 32 + Color color; 33 + } Player; 34 + 35 + Player *player_create(float x, float y); 36 + int player_destroy(Player *player); 37 + void player_draw(Player *player); 38 + void player_update(Player *player); 39 + 40 + #endif
+4
include/player_state/default.h
··· 1 + #include "../player.h" 2 + #include "player_state.h" 3 + 4 + void player_state_transition_to_default(PlayerState *state, Player *player);
+4
include/player_state/fall.h
··· 1 + #include "../player.h" 2 + #include "player_state.h" 3 + 4 + void player_state_transition_to_fall(PlayerState *state, Player *player);
+15
include/player_state/player_state.h
··· 1 + #ifndef PLAYER_STATE_H 2 + #define PLAYER_STATE_H 3 + 4 + typedef struct PlayerState PlayerState; 5 + 6 + typedef struct Player Player; 7 + 8 + typedef void (*PlayerEventUpdate)(PlayerState *, Player *); 9 + 10 + struct PlayerState { 11 + const char *name; 12 + PlayerEventUpdate update; 13 + }; 14 + 15 + #endif
+4
include/player_state/run.h
··· 1 + #include "../player.h" 2 + #include "player_state.h" 3 + 4 + void player_state_transition_to_run(PlayerState *state, Player *player);
+4
include/player_state/walk.h
··· 1 + #include "../player.h" 2 + #include "player_state.h" 3 + 4 + void player_state_transition_to_walk(PlayerState *state, Player *player);
+1727
include/raylib.h
··· 1 + /********************************************************************************************** 2 + * 3 + * raylib v5.6-dev - A simple and easy-to-use library to enjoy videogames programming (www.raylib.com) 4 + * 5 + * FEATURES: 6 + * - NO external dependencies, all required libraries included with raylib 7 + * - Multiplatform: Windows, Linux, FreeBSD, OpenBSD, NetBSD, DragonFly, 8 + * MacOS, Haiku, Android, Raspberry Pi, DRM native, HTML5 9 + * - Written in plain C code (C99) in PascalCase/camelCase notation 10 + * - Hardware accelerated with OpenGL (1.1, 2.1, 3.3, 4.3, ES2, ES3 - choose at compile) 11 + * - Unique OpenGL abstraction layer (usable as standalone module): [rlgl] 12 + * - Multiple Fonts formats supported (TTF, OTF, FNT, BDF, Sprite fonts) 13 + * - Outstanding texture formats support, including compressed formats (DXT, ETC, ASTC) 14 + * - Full 3d support for 3d Shapes, Models, Billboards, Heightmaps and more! 15 + * - Flexible Materials system, supporting classic maps and PBR maps 16 + * - Animated 3D models supported (skeletal bones animation) (IQM, M3D, GLTF) 17 + * - Shaders support, including Model shaders and Postprocessing shaders 18 + * - Powerful math module for Vector, Matrix and Quaternion operations: [raymath] 19 + * - Audio loading and playing with streaming support (WAV, OGG, MP3, FLAC, QOA, XM, MOD) 20 + * - VR stereo rendering with configurable HMD device parameters 21 + * - Bindings to multiple programming languages available! 22 + * 23 + * NOTES: 24 + * - One default Font is loaded on InitWindow()->LoadFontDefault() [core, text] 25 + * - One default Texture2D is loaded on rlglInit(), 1x1 white pixel R8G8B8A8 [rlgl] (OpenGL 3.3 or ES2) 26 + * - One default Shader is loaded on rlglInit()->rlLoadShaderDefault() [rlgl] (OpenGL 3.3 or ES2) 27 + * - One default RenderBatch is loaded on rlglInit()->rlLoadRenderBatch() [rlgl] (OpenGL 3.3 or ES2) 28 + * 29 + * DEPENDENCIES (included): 30 + * [rcore][GLFW] rglfw (Camilla Löwy - github.com/glfw/glfw) for window/context management and input 31 + * [rcore][RGFW] rgfw (ColleagueRiley - github.com/ColleagueRiley/RGFW) for window/context management and input 32 + * [rlgl] glad/glad_gles2 (David Herberth - github.com/Dav1dde/glad) for OpenGL 3.3 extensions loading 33 + * [raudio] miniaudio (David Reid - github.com/mackron/miniaudio) for audio device/context management 34 + * 35 + * OPTIONAL DEPENDENCIES (included): 36 + * [rcore] msf_gif (Miles Fogle) for GIF recording 37 + * [rcore] sinfl (Micha Mettke) for DEFLATE decompression algorithm 38 + * [rcore] sdefl (Micha Mettke) for DEFLATE compression algorithm 39 + * [rcore] rprand (Ramon Santamaria) for pseudo-random numbers generation 40 + * [rtextures] qoi (Dominic Szablewski - https://phoboslab.org) for QOI image manage 41 + * [rtextures] stb_image (Sean Barret) for images loading (BMP, TGA, PNG, JPEG, HDR...) 42 + * [rtextures] stb_image_write (Sean Barret) for image writing (BMP, TGA, PNG, JPG) 43 + * [rtextures] stb_image_resize2 (Sean Barret) for image resizing algorithms 44 + * [rtextures] stb_perlin (Sean Barret) for Perlin Noise image generation 45 + * [rtext] stb_truetype (Sean Barret) for ttf fonts loading 46 + * [rtext] stb_rect_pack (Sean Barret) for rectangles packing 47 + * [rmodels] par_shapes (Philip Rideout) for parametric 3d shapes generation 48 + * [rmodels] tinyobj_loader_c (Syoyo Fujita) for models loading (OBJ, MTL) 49 + * [rmodels] cgltf (Johannes Kuhlmann) for models loading (glTF) 50 + * [rmodels] m3d (bzt) for models loading (M3D, https://bztsrc.gitlab.io/model3d) 51 + * [rmodels] vox_loader (Johann Nadalutti) for models loading (VOX) 52 + * [raudio] dr_wav (David Reid) for WAV audio file loading 53 + * [raudio] dr_flac (David Reid) for FLAC audio file loading 54 + * [raudio] dr_mp3 (David Reid) for MP3 audio file loading 55 + * [raudio] stb_vorbis (Sean Barret) for OGG audio loading 56 + * [raudio] jar_xm (Joshua Reisenauer) for XM audio module loading 57 + * [raudio] jar_mod (Joshua Reisenauer) for MOD audio module loading 58 + * [raudio] qoa (Dominic Szablewski - https://phoboslab.org) for QOA audio manage 59 + * 60 + * 61 + * LICENSE: zlib/libpng 62 + * 63 + * raylib is licensed under an unmodified zlib/libpng license, which is an OSI-certified, 64 + * BSD-like license that allows static linking with closed source software: 65 + * 66 + * Copyright (c) 2013-2025 Ramon Santamaria (@raysan5) 67 + * 68 + * This software is provided "as-is", without any express or implied warranty. In no event 69 + * will the authors be held liable for any damages arising from the use of this software. 70 + * 71 + * Permission is granted to anyone to use this software for any purpose, including commercial 72 + * applications, and to alter it and redistribute it freely, subject to the following restrictions: 73 + * 74 + * 1. The origin of this software must not be misrepresented; you must not claim that you 75 + * wrote the original software. If you use this software in a product, an acknowledgment 76 + * in the product documentation would be appreciated but is not required. 77 + * 78 + * 2. Altered source versions must be plainly marked as such, and must not be misrepresented 79 + * as being the original software. 80 + * 81 + * 3. This notice may not be removed or altered from any source distribution. 82 + * 83 + **********************************************************************************************/ 84 + 85 + #ifndef RAYLIB_H 86 + #define RAYLIB_H 87 + 88 + #include <stdarg.h> // Required for: va_list - Only used by TraceLogCallback 89 + 90 + #define RAYLIB_VERSION_MAJOR 5 91 + #define RAYLIB_VERSION_MINOR 6 92 + #define RAYLIB_VERSION_PATCH 0 93 + #define RAYLIB_VERSION "5.6-dev" 94 + 95 + // Function specifiers in case library is build/used as a shared library 96 + // NOTE: Microsoft specifiers to tell compiler that symbols are imported/exported from a .dll 97 + // NOTE: visibility("default") attribute makes symbols "visible" when compiled with -fvisibility=hidden 98 + #if defined(_WIN32) 99 + #if defined(__TINYC__) 100 + #define __declspec(x) __attribute__((x)) 101 + #endif 102 + #if defined(BUILD_LIBTYPE_SHARED) 103 + #define RLAPI __declspec(dllexport) // We are building the library as a Win32 shared library (.dll) 104 + #elif defined(USE_LIBTYPE_SHARED) 105 + #define RLAPI __declspec(dllimport) // We are using the library as a Win32 shared library (.dll) 106 + #endif 107 + #else 108 + #if defined(BUILD_LIBTYPE_SHARED) 109 + #define RLAPI __attribute__((visibility("default"))) // We are building as a Unix shared library (.so/.dylib) 110 + #endif 111 + #endif 112 + 113 + #ifndef RLAPI 114 + #define RLAPI // Functions defined as 'extern' by default (implicit specifiers) 115 + #endif 116 + 117 + //---------------------------------------------------------------------------------- 118 + // Defines and Macros 119 + //---------------------------------------------------------------------------------- 120 + #ifndef PI 121 + #define PI 3.14159265358979323846f 122 + #endif 123 + #ifndef DEG2RAD 124 + #define DEG2RAD (PI/180.0f) 125 + #endif 126 + #ifndef RAD2DEG 127 + #define RAD2DEG (180.0f/PI) 128 + #endif 129 + 130 + // Allow custom memory allocators 131 + // NOTE: Require recompiling raylib sources 132 + #ifndef RL_MALLOC 133 + #define RL_MALLOC(sz) malloc(sz) 134 + #endif 135 + #ifndef RL_CALLOC 136 + #define RL_CALLOC(n,sz) calloc(n,sz) 137 + #endif 138 + #ifndef RL_REALLOC 139 + #define RL_REALLOC(ptr,sz) realloc(ptr,sz) 140 + #endif 141 + #ifndef RL_FREE 142 + #define RL_FREE(ptr) free(ptr) 143 + #endif 144 + 145 + // NOTE: MSVC C++ compiler does not support compound literals (C99 feature) 146 + // Plain structures in C++ (without constructors) can be initialized with { } 147 + // This is called aggregate initialization (C++11 feature) 148 + #if defined(__cplusplus) 149 + #define CLITERAL(type) type 150 + #else 151 + #define CLITERAL(type) (type) 152 + #endif 153 + 154 + // Some compilers (mostly macos clang) default to C++98, 155 + // where aggregate initialization can't be used 156 + // So, give a more clear error stating how to fix this 157 + #if !defined(_MSC_VER) && (defined(__cplusplus) && __cplusplus < 201103L) 158 + #error "C++11 or later is required. Add -std=c++11" 159 + #endif 160 + 161 + // NOTE: We set some defines with some data types declared by raylib 162 + // Other modules (raymath, rlgl) also require some of those types, so, 163 + // to be able to use those other modules as standalone (not depending on raylib) 164 + // this defines are very useful for internal check and avoid type (re)definitions 165 + #define RL_COLOR_TYPE 166 + #define RL_RECTANGLE_TYPE 167 + #define RL_VECTOR2_TYPE 168 + #define RL_VECTOR3_TYPE 169 + #define RL_VECTOR4_TYPE 170 + #define RL_QUATERNION_TYPE 171 + #define RL_MATRIX_TYPE 172 + 173 + // Some Basic Colors 174 + // NOTE: Custom raylib color palette for amazing visuals on WHITE background 175 + #define LIGHTGRAY CLITERAL(Color){ 200, 200, 200, 255 } // Light Gray 176 + #define GRAY CLITERAL(Color){ 130, 130, 130, 255 } // Gray 177 + #define DARKGRAY CLITERAL(Color){ 80, 80, 80, 255 } // Dark Gray 178 + #define YELLOW CLITERAL(Color){ 253, 249, 0, 255 } // Yellow 179 + #define GOLD CLITERAL(Color){ 255, 203, 0, 255 } // Gold 180 + #define ORANGE CLITERAL(Color){ 255, 161, 0, 255 } // Orange 181 + #define PINK CLITERAL(Color){ 255, 109, 194, 255 } // Pink 182 + #define RED CLITERAL(Color){ 230, 41, 55, 255 } // Red 183 + #define MAROON CLITERAL(Color){ 190, 33, 55, 255 } // Maroon 184 + #define GREEN CLITERAL(Color){ 0, 228, 48, 255 } // Green 185 + #define LIME CLITERAL(Color){ 0, 158, 47, 255 } // Lime 186 + #define DARKGREEN CLITERAL(Color){ 0, 117, 44, 255 } // Dark Green 187 + #define SKYBLUE CLITERAL(Color){ 102, 191, 255, 255 } // Sky Blue 188 + #define BLUE CLITERAL(Color){ 0, 121, 241, 255 } // Blue 189 + #define DARKBLUE CLITERAL(Color){ 0, 82, 172, 255 } // Dark Blue 190 + #define PURPLE CLITERAL(Color){ 200, 122, 255, 255 } // Purple 191 + #define VIOLET CLITERAL(Color){ 135, 60, 190, 255 } // Violet 192 + #define DARKPURPLE CLITERAL(Color){ 112, 31, 126, 255 } // Dark Purple 193 + #define BEIGE CLITERAL(Color){ 211, 176, 131, 255 } // Beige 194 + #define BROWN CLITERAL(Color){ 127, 106, 79, 255 } // Brown 195 + #define DARKBROWN CLITERAL(Color){ 76, 63, 47, 255 } // Dark Brown 196 + 197 + #define WHITE CLITERAL(Color){ 255, 255, 255, 255 } // White 198 + #define BLACK CLITERAL(Color){ 0, 0, 0, 255 } // Black 199 + #define BLANK CLITERAL(Color){ 0, 0, 0, 0 } // Blank (Transparent) 200 + #define MAGENTA CLITERAL(Color){ 255, 0, 255, 255 } // Magenta 201 + #define RAYWHITE CLITERAL(Color){ 245, 245, 245, 255 } // My own White (raylib logo) 202 + 203 + //---------------------------------------------------------------------------------- 204 + // Types and Structures Definition 205 + //---------------------------------------------------------------------------------- 206 + // Boolean type 207 + #if (defined(__STDC__) && __STDC_VERSION__ >= 199901L) || (defined(_MSC_VER) && _MSC_VER >= 1800) 208 + #include <stdbool.h> 209 + #elif !defined(__cplusplus) && !defined(bool) 210 + typedef enum bool { false = 0, true = !false } bool; 211 + #define RL_BOOL_TYPE 212 + #endif 213 + 214 + // Vector2, 2 components 215 + typedef struct Vector2 { 216 + float x; // Vector x component 217 + float y; // Vector y component 218 + } Vector2; 219 + 220 + // Vector3, 3 components 221 + typedef struct Vector3 { 222 + float x; // Vector x component 223 + float y; // Vector y component 224 + float z; // Vector z component 225 + } Vector3; 226 + 227 + // Vector4, 4 components 228 + typedef struct Vector4 { 229 + float x; // Vector x component 230 + float y; // Vector y component 231 + float z; // Vector z component 232 + float w; // Vector w component 233 + } Vector4; 234 + 235 + // Quaternion, 4 components (Vector4 alias) 236 + typedef Vector4 Quaternion; 237 + 238 + // Matrix, 4x4 components, column major, OpenGL style, right-handed 239 + typedef struct Matrix { 240 + float m0, m4, m8, m12; // Matrix first row (4 components) 241 + float m1, m5, m9, m13; // Matrix second row (4 components) 242 + float m2, m6, m10, m14; // Matrix third row (4 components) 243 + float m3, m7, m11, m15; // Matrix fourth row (4 components) 244 + } Matrix; 245 + 246 + // Color, 4 components, R8G8B8A8 (32bit) 247 + typedef struct Color { 248 + unsigned char r; // Color red value 249 + unsigned char g; // Color green value 250 + unsigned char b; // Color blue value 251 + unsigned char a; // Color alpha value 252 + } Color; 253 + 254 + // Rectangle, 4 components 255 + typedef struct Rectangle { 256 + float x; // Rectangle top-left corner position x 257 + float y; // Rectangle top-left corner position y 258 + float width; // Rectangle width 259 + float height; // Rectangle height 260 + } Rectangle; 261 + 262 + // Image, pixel data stored in CPU memory (RAM) 263 + typedef struct Image { 264 + void *data; // Image raw data 265 + int width; // Image base width 266 + int height; // Image base height 267 + int mipmaps; // Mipmap levels, 1 by default 268 + int format; // Data format (PixelFormat type) 269 + } Image; 270 + 271 + // Texture, tex data stored in GPU memory (VRAM) 272 + typedef struct Texture { 273 + unsigned int id; // OpenGL texture id 274 + int width; // Texture base width 275 + int height; // Texture base height 276 + int mipmaps; // Mipmap levels, 1 by default 277 + int format; // Data format (PixelFormat type) 278 + } Texture; 279 + 280 + // Texture2D, same as Texture 281 + typedef Texture Texture2D; 282 + 283 + // TextureCubemap, same as Texture 284 + typedef Texture TextureCubemap; 285 + 286 + // RenderTexture, fbo for texture rendering 287 + typedef struct RenderTexture { 288 + unsigned int id; // OpenGL framebuffer object id 289 + Texture texture; // Color buffer attachment texture 290 + Texture depth; // Depth buffer attachment texture 291 + } RenderTexture; 292 + 293 + // RenderTexture2D, same as RenderTexture 294 + typedef RenderTexture RenderTexture2D; 295 + 296 + // NPatchInfo, n-patch layout info 297 + typedef struct NPatchInfo { 298 + Rectangle source; // Texture source rectangle 299 + int left; // Left border offset 300 + int top; // Top border offset 301 + int right; // Right border offset 302 + int bottom; // Bottom border offset 303 + int layout; // Layout of the n-patch: 3x3, 1x3 or 3x1 304 + } NPatchInfo; 305 + 306 + // GlyphInfo, font characters glyphs info 307 + typedef struct GlyphInfo { 308 + int value; // Character value (Unicode) 309 + int offsetX; // Character offset X when drawing 310 + int offsetY; // Character offset Y when drawing 311 + int advanceX; // Character advance position X 312 + Image image; // Character image data 313 + } GlyphInfo; 314 + 315 + // Font, font texture and GlyphInfo array data 316 + typedef struct Font { 317 + int baseSize; // Base size (default chars height) 318 + int glyphCount; // Number of glyph characters 319 + int glyphPadding; // Padding around the glyph characters 320 + Texture2D texture; // Texture atlas containing the glyphs 321 + Rectangle *recs; // Rectangles in texture for the glyphs 322 + GlyphInfo *glyphs; // Glyphs info data 323 + } Font; 324 + 325 + // Camera, defines position/orientation in 3d space 326 + typedef struct Camera3D { 327 + Vector3 position; // Camera position 328 + Vector3 target; // Camera target it looks-at 329 + Vector3 up; // Camera up vector (rotation over its axis) 330 + float fovy; // Camera field-of-view aperture in Y (degrees) in perspective, used as near plane height in world units in orthographic 331 + int projection; // Camera projection: CAMERA_PERSPECTIVE or CAMERA_ORTHOGRAPHIC 332 + } Camera3D; 333 + 334 + typedef Camera3D Camera; // Camera type fallback, defaults to Camera3D 335 + 336 + // Camera2D, defines position/orientation in 2d space 337 + typedef struct Camera2D { 338 + Vector2 offset; // Camera offset (displacement from target) 339 + Vector2 target; // Camera target (rotation and zoom origin) 340 + float rotation; // Camera rotation in degrees 341 + float zoom; // Camera zoom (scaling), should be 1.0f by default 342 + } Camera2D; 343 + 344 + // Mesh, vertex data and vao/vbo 345 + typedef struct Mesh { 346 + int vertexCount; // Number of vertices stored in arrays 347 + int triangleCount; // Number of triangles stored (indexed or not) 348 + 349 + // Vertex attributes data 350 + float *vertices; // Vertex position (XYZ - 3 components per vertex) (shader-location = 0) 351 + float *texcoords; // Vertex texture coordinates (UV - 2 components per vertex) (shader-location = 1) 352 + float *texcoords2; // Vertex texture second coordinates (UV - 2 components per vertex) (shader-location = 5) 353 + float *normals; // Vertex normals (XYZ - 3 components per vertex) (shader-location = 2) 354 + float *tangents; // Vertex tangents (XYZW - 4 components per vertex) (shader-location = 4) 355 + unsigned char *colors; // Vertex colors (RGBA - 4 components per vertex) (shader-location = 3) 356 + unsigned short *indices; // Vertex indices (in case vertex data comes indexed) 357 + 358 + // Animation vertex data 359 + float *animVertices; // Animated vertex positions (after bones transformations) 360 + float *animNormals; // Animated normals (after bones transformations) 361 + unsigned char *boneIds; // Vertex bone ids, max 255 bone ids, up to 4 bones influence by vertex (skinning) (shader-location = 6) 362 + float *boneWeights; // Vertex bone weight, up to 4 bones influence by vertex (skinning) (shader-location = 7) 363 + Matrix *boneMatrices; // Bones animated transformation matrices 364 + int boneCount; // Number of bones 365 + 366 + // OpenGL identifiers 367 + unsigned int vaoId; // OpenGL Vertex Array Object id 368 + unsigned int *vboId; // OpenGL Vertex Buffer Objects id (default vertex data) 369 + } Mesh; 370 + 371 + // Shader 372 + typedef struct Shader { 373 + unsigned int id; // Shader program id 374 + int *locs; // Shader locations array (RL_MAX_SHADER_LOCATIONS) 375 + } Shader; 376 + 377 + // MaterialMap 378 + typedef struct MaterialMap { 379 + Texture2D texture; // Material map texture 380 + Color color; // Material map color 381 + float value; // Material map value 382 + } MaterialMap; 383 + 384 + // Material, includes shader and maps 385 + typedef struct Material { 386 + Shader shader; // Material shader 387 + MaterialMap *maps; // Material maps array (MAX_MATERIAL_MAPS) 388 + float params[4]; // Material generic parameters (if required) 389 + } Material; 390 + 391 + // Transform, vertex transformation data 392 + typedef struct Transform { 393 + Vector3 translation; // Translation 394 + Quaternion rotation; // Rotation 395 + Vector3 scale; // Scale 396 + } Transform; 397 + 398 + // Bone, skeletal animation bone 399 + typedef struct BoneInfo { 400 + char name[32]; // Bone name 401 + int parent; // Bone parent 402 + } BoneInfo; 403 + 404 + // Model, meshes, materials and animation data 405 + typedef struct Model { 406 + Matrix transform; // Local transform matrix 407 + 408 + int meshCount; // Number of meshes 409 + int materialCount; // Number of materials 410 + Mesh *meshes; // Meshes array 411 + Material *materials; // Materials array 412 + int *meshMaterial; // Mesh material number 413 + 414 + // Animation data 415 + int boneCount; // Number of bones 416 + BoneInfo *bones; // Bones information (skeleton) 417 + Transform *bindPose; // Bones base transformation (pose) 418 + } Model; 419 + 420 + // ModelAnimation 421 + typedef struct ModelAnimation { 422 + int boneCount; // Number of bones 423 + int frameCount; // Number of animation frames 424 + BoneInfo *bones; // Bones information (skeleton) 425 + Transform **framePoses; // Poses array by frame 426 + char name[32]; // Animation name 427 + } ModelAnimation; 428 + 429 + // Ray, ray for raycasting 430 + typedef struct Ray { 431 + Vector3 position; // Ray position (origin) 432 + Vector3 direction; // Ray direction (normalized) 433 + } Ray; 434 + 435 + // RayCollision, ray hit information 436 + typedef struct RayCollision { 437 + bool hit; // Did the ray hit something? 438 + float distance; // Distance to the nearest hit 439 + Vector3 point; // Point of the nearest hit 440 + Vector3 normal; // Surface normal of hit 441 + } RayCollision; 442 + 443 + // BoundingBox 444 + typedef struct BoundingBox { 445 + Vector3 min; // Minimum vertex box-corner 446 + Vector3 max; // Maximum vertex box-corner 447 + } BoundingBox; 448 + 449 + // Wave, audio wave data 450 + typedef struct Wave { 451 + unsigned int frameCount; // Total number of frames (considering channels) 452 + unsigned int sampleRate; // Frequency (samples per second) 453 + unsigned int sampleSize; // Bit depth (bits per sample): 8, 16, 32 (24 not supported) 454 + unsigned int channels; // Number of channels (1-mono, 2-stereo, ...) 455 + void *data; // Buffer data pointer 456 + } Wave; 457 + 458 + // Opaque structs declaration 459 + // NOTE: Actual structs are defined internally in raudio module 460 + typedef struct rAudioBuffer rAudioBuffer; 461 + typedef struct rAudioProcessor rAudioProcessor; 462 + 463 + // AudioStream, custom audio stream 464 + typedef struct AudioStream { 465 + rAudioBuffer *buffer; // Pointer to internal data used by the audio system 466 + rAudioProcessor *processor; // Pointer to internal data processor, useful for audio effects 467 + 468 + unsigned int sampleRate; // Frequency (samples per second) 469 + unsigned int sampleSize; // Bit depth (bits per sample): 8, 16, 32 (24 not supported) 470 + unsigned int channels; // Number of channels (1-mono, 2-stereo, ...) 471 + } AudioStream; 472 + 473 + // Sound 474 + typedef struct Sound { 475 + AudioStream stream; // Audio stream 476 + unsigned int frameCount; // Total number of frames (considering channels) 477 + } Sound; 478 + 479 + // Music, audio stream, anything longer than ~10 seconds should be streamed 480 + typedef struct Music { 481 + AudioStream stream; // Audio stream 482 + unsigned int frameCount; // Total number of frames (considering channels) 483 + bool looping; // Music looping enable 484 + 485 + int ctxType; // Type of music context (audio filetype) 486 + void *ctxData; // Audio context data, depends on type 487 + } Music; 488 + 489 + // VrDeviceInfo, Head-Mounted-Display device parameters 490 + typedef struct VrDeviceInfo { 491 + int hResolution; // Horizontal resolution in pixels 492 + int vResolution; // Vertical resolution in pixels 493 + float hScreenSize; // Horizontal size in meters 494 + float vScreenSize; // Vertical size in meters 495 + float eyeToScreenDistance; // Distance between eye and display in meters 496 + float lensSeparationDistance; // Lens separation distance in meters 497 + float interpupillaryDistance; // IPD (distance between pupils) in meters 498 + float lensDistortionValues[4]; // Lens distortion constant parameters 499 + float chromaAbCorrection[4]; // Chromatic aberration correction parameters 500 + } VrDeviceInfo; 501 + 502 + // VrStereoConfig, VR stereo rendering configuration for simulator 503 + typedef struct VrStereoConfig { 504 + Matrix projection[2]; // VR projection matrices (per eye) 505 + Matrix viewOffset[2]; // VR view offset matrices (per eye) 506 + float leftLensCenter[2]; // VR left lens center 507 + float rightLensCenter[2]; // VR right lens center 508 + float leftScreenCenter[2]; // VR left screen center 509 + float rightScreenCenter[2]; // VR right screen center 510 + float scale[2]; // VR distortion scale 511 + float scaleIn[2]; // VR distortion scale in 512 + } VrStereoConfig; 513 + 514 + // File path list 515 + typedef struct FilePathList { 516 + unsigned int capacity; // Filepaths max entries 517 + unsigned int count; // Filepaths entries count 518 + char **paths; // Filepaths entries 519 + } FilePathList; 520 + 521 + // Automation event 522 + typedef struct AutomationEvent { 523 + unsigned int frame; // Event frame 524 + unsigned int type; // Event type (AutomationEventType) 525 + int params[4]; // Event parameters (if required) 526 + } AutomationEvent; 527 + 528 + // Automation event list 529 + typedef struct AutomationEventList { 530 + unsigned int capacity; // Events max entries (MAX_AUTOMATION_EVENTS) 531 + unsigned int count; // Events entries count 532 + AutomationEvent *events; // Events entries 533 + } AutomationEventList; 534 + 535 + //---------------------------------------------------------------------------------- 536 + // Enumerators Definition 537 + //---------------------------------------------------------------------------------- 538 + // System/Window config flags 539 + // NOTE: Every bit registers one state (use it with bit masks) 540 + // By default all flags are set to 0 541 + typedef enum { 542 + FLAG_VSYNC_HINT = 0x00000040, // Set to try enabling V-Sync on GPU 543 + FLAG_FULLSCREEN_MODE = 0x00000002, // Set to run program in fullscreen 544 + FLAG_WINDOW_RESIZABLE = 0x00000004, // Set to allow resizable window 545 + FLAG_WINDOW_UNDECORATED = 0x00000008, // Set to disable window decoration (frame and buttons) 546 + FLAG_WINDOW_HIDDEN = 0x00000080, // Set to hide window 547 + FLAG_WINDOW_MINIMIZED = 0x00000200, // Set to minimize window (iconify) 548 + FLAG_WINDOW_MAXIMIZED = 0x00000400, // Set to maximize window (expanded to monitor) 549 + FLAG_WINDOW_UNFOCUSED = 0x00000800, // Set to window non focused 550 + FLAG_WINDOW_TOPMOST = 0x00001000, // Set to window always on top 551 + FLAG_WINDOW_ALWAYS_RUN = 0x00000100, // Set to allow windows running while minimized 552 + FLAG_WINDOW_TRANSPARENT = 0x00000010, // Set to allow transparent framebuffer 553 + FLAG_WINDOW_HIGHDPI = 0x00002000, // Set to support HighDPI 554 + FLAG_WINDOW_MOUSE_PASSTHROUGH = 0x00004000, // Set to support mouse passthrough, only supported when FLAG_WINDOW_UNDECORATED 555 + FLAG_BORDERLESS_WINDOWED_MODE = 0x00008000, // Set to run program in borderless windowed mode 556 + FLAG_MSAA_4X_HINT = 0x00000020, // Set to try enabling MSAA 4X 557 + FLAG_INTERLACED_HINT = 0x00010000 // Set to try enabling interlaced video format (for V3D) 558 + } ConfigFlags; 559 + 560 + // Trace log level 561 + // NOTE: Organized by priority level 562 + typedef enum { 563 + LOG_ALL = 0, // Display all logs 564 + LOG_TRACE, // Trace logging, intended for internal use only 565 + LOG_DEBUG, // Debug logging, used for internal debugging, it should be disabled on release builds 566 + LOG_INFO, // Info logging, used for program execution info 567 + LOG_WARNING, // Warning logging, used on recoverable failures 568 + LOG_ERROR, // Error logging, used on unrecoverable failures 569 + LOG_FATAL, // Fatal logging, used to abort program: exit(EXIT_FAILURE) 570 + LOG_NONE // Disable logging 571 + } TraceLogLevel; 572 + 573 + // Keyboard keys (US keyboard layout) 574 + // NOTE: Use GetKeyPressed() to allow redefining 575 + // required keys for alternative layouts 576 + typedef enum { 577 + KEY_NULL = 0, // Key: NULL, used for no key pressed 578 + // Alphanumeric keys 579 + KEY_APOSTROPHE = 39, // Key: ' 580 + KEY_COMMA = 44, // Key: , 581 + KEY_MINUS = 45, // Key: - 582 + KEY_PERIOD = 46, // Key: . 583 + KEY_SLASH = 47, // Key: / 584 + KEY_ZERO = 48, // Key: 0 585 + KEY_ONE = 49, // Key: 1 586 + KEY_TWO = 50, // Key: 2 587 + KEY_THREE = 51, // Key: 3 588 + KEY_FOUR = 52, // Key: 4 589 + KEY_FIVE = 53, // Key: 5 590 + KEY_SIX = 54, // Key: 6 591 + KEY_SEVEN = 55, // Key: 7 592 + KEY_EIGHT = 56, // Key: 8 593 + KEY_NINE = 57, // Key: 9 594 + KEY_SEMICOLON = 59, // Key: ; 595 + KEY_EQUAL = 61, // Key: = 596 + KEY_A = 65, // Key: A | a 597 + KEY_B = 66, // Key: B | b 598 + KEY_C = 67, // Key: C | c 599 + KEY_D = 68, // Key: D | d 600 + KEY_E = 69, // Key: E | e 601 + KEY_F = 70, // Key: F | f 602 + KEY_G = 71, // Key: G | g 603 + KEY_H = 72, // Key: H | h 604 + KEY_I = 73, // Key: I | i 605 + KEY_J = 74, // Key: J | j 606 + KEY_K = 75, // Key: K | k 607 + KEY_L = 76, // Key: L | l 608 + KEY_M = 77, // Key: M | m 609 + KEY_N = 78, // Key: N | n 610 + KEY_O = 79, // Key: O | o 611 + KEY_P = 80, // Key: P | p 612 + KEY_Q = 81, // Key: Q | q 613 + KEY_R = 82, // Key: R | r 614 + KEY_S = 83, // Key: S | s 615 + KEY_T = 84, // Key: T | t 616 + KEY_U = 85, // Key: U | u 617 + KEY_V = 86, // Key: V | v 618 + KEY_W = 87, // Key: W | w 619 + KEY_X = 88, // Key: X | x 620 + KEY_Y = 89, // Key: Y | y 621 + KEY_Z = 90, // Key: Z | z 622 + KEY_LEFT_BRACKET = 91, // Key: [ 623 + KEY_BACKSLASH = 92, // Key: '\' 624 + KEY_RIGHT_BRACKET = 93, // Key: ] 625 + KEY_GRAVE = 96, // Key: ` 626 + // Function keys 627 + KEY_SPACE = 32, // Key: Space 628 + KEY_ESCAPE = 256, // Key: Esc 629 + KEY_ENTER = 257, // Key: Enter 630 + KEY_TAB = 258, // Key: Tab 631 + KEY_BACKSPACE = 259, // Key: Backspace 632 + KEY_INSERT = 260, // Key: Ins 633 + KEY_DELETE = 261, // Key: Del 634 + KEY_RIGHT = 262, // Key: Cursor right 635 + KEY_LEFT = 263, // Key: Cursor left 636 + KEY_DOWN = 264, // Key: Cursor down 637 + KEY_UP = 265, // Key: Cursor up 638 + KEY_PAGE_UP = 266, // Key: Page up 639 + KEY_PAGE_DOWN = 267, // Key: Page down 640 + KEY_HOME = 268, // Key: Home 641 + KEY_END = 269, // Key: End 642 + KEY_CAPS_LOCK = 280, // Key: Caps lock 643 + KEY_SCROLL_LOCK = 281, // Key: Scroll down 644 + KEY_NUM_LOCK = 282, // Key: Num lock 645 + KEY_PRINT_SCREEN = 283, // Key: Print screen 646 + KEY_PAUSE = 284, // Key: Pause 647 + KEY_F1 = 290, // Key: F1 648 + KEY_F2 = 291, // Key: F2 649 + KEY_F3 = 292, // Key: F3 650 + KEY_F4 = 293, // Key: F4 651 + KEY_F5 = 294, // Key: F5 652 + KEY_F6 = 295, // Key: F6 653 + KEY_F7 = 296, // Key: F7 654 + KEY_F8 = 297, // Key: F8 655 + KEY_F9 = 298, // Key: F9 656 + KEY_F10 = 299, // Key: F10 657 + KEY_F11 = 300, // Key: F11 658 + KEY_F12 = 301, // Key: F12 659 + KEY_LEFT_SHIFT = 340, // Key: Shift left 660 + KEY_LEFT_CONTROL = 341, // Key: Control left 661 + KEY_LEFT_ALT = 342, // Key: Alt left 662 + KEY_LEFT_SUPER = 343, // Key: Super left 663 + KEY_RIGHT_SHIFT = 344, // Key: Shift right 664 + KEY_RIGHT_CONTROL = 345, // Key: Control right 665 + KEY_RIGHT_ALT = 346, // Key: Alt right 666 + KEY_RIGHT_SUPER = 347, // Key: Super right 667 + KEY_KB_MENU = 348, // Key: KB menu 668 + // Keypad keys 669 + KEY_KP_0 = 320, // Key: Keypad 0 670 + KEY_KP_1 = 321, // Key: Keypad 1 671 + KEY_KP_2 = 322, // Key: Keypad 2 672 + KEY_KP_3 = 323, // Key: Keypad 3 673 + KEY_KP_4 = 324, // Key: Keypad 4 674 + KEY_KP_5 = 325, // Key: Keypad 5 675 + KEY_KP_6 = 326, // Key: Keypad 6 676 + KEY_KP_7 = 327, // Key: Keypad 7 677 + KEY_KP_8 = 328, // Key: Keypad 8 678 + KEY_KP_9 = 329, // Key: Keypad 9 679 + KEY_KP_DECIMAL = 330, // Key: Keypad . 680 + KEY_KP_DIVIDE = 331, // Key: Keypad / 681 + KEY_KP_MULTIPLY = 332, // Key: Keypad * 682 + KEY_KP_SUBTRACT = 333, // Key: Keypad - 683 + KEY_KP_ADD = 334, // Key: Keypad + 684 + KEY_KP_ENTER = 335, // Key: Keypad Enter 685 + KEY_KP_EQUAL = 336, // Key: Keypad = 686 + // Android key buttons 687 + KEY_BACK = 4, // Key: Android back button 688 + KEY_MENU = 5, // Key: Android menu button 689 + KEY_VOLUME_UP = 24, // Key: Android volume up button 690 + KEY_VOLUME_DOWN = 25 // Key: Android volume down button 691 + } KeyboardKey; 692 + 693 + // Add backwards compatibility support for deprecated names 694 + #define MOUSE_LEFT_BUTTON MOUSE_BUTTON_LEFT 695 + #define MOUSE_RIGHT_BUTTON MOUSE_BUTTON_RIGHT 696 + #define MOUSE_MIDDLE_BUTTON MOUSE_BUTTON_MIDDLE 697 + 698 + // Mouse buttons 699 + typedef enum { 700 + MOUSE_BUTTON_LEFT = 0, // Mouse button left 701 + MOUSE_BUTTON_RIGHT = 1, // Mouse button right 702 + MOUSE_BUTTON_MIDDLE = 2, // Mouse button middle (pressed wheel) 703 + MOUSE_BUTTON_SIDE = 3, // Mouse button side (advanced mouse device) 704 + MOUSE_BUTTON_EXTRA = 4, // Mouse button extra (advanced mouse device) 705 + MOUSE_BUTTON_FORWARD = 5, // Mouse button forward (advanced mouse device) 706 + MOUSE_BUTTON_BACK = 6, // Mouse button back (advanced mouse device) 707 + } MouseButton; 708 + 709 + // Mouse cursor 710 + typedef enum { 711 + MOUSE_CURSOR_DEFAULT = 0, // Default pointer shape 712 + MOUSE_CURSOR_ARROW = 1, // Arrow shape 713 + MOUSE_CURSOR_IBEAM = 2, // Text writing cursor shape 714 + MOUSE_CURSOR_CROSSHAIR = 3, // Cross shape 715 + MOUSE_CURSOR_POINTING_HAND = 4, // Pointing hand cursor 716 + MOUSE_CURSOR_RESIZE_EW = 5, // Horizontal resize/move arrow shape 717 + MOUSE_CURSOR_RESIZE_NS = 6, // Vertical resize/move arrow shape 718 + MOUSE_CURSOR_RESIZE_NWSE = 7, // Top-left to bottom-right diagonal resize/move arrow shape 719 + MOUSE_CURSOR_RESIZE_NESW = 8, // The top-right to bottom-left diagonal resize/move arrow shape 720 + MOUSE_CURSOR_RESIZE_ALL = 9, // The omnidirectional resize/move cursor shape 721 + MOUSE_CURSOR_NOT_ALLOWED = 10 // The operation-not-allowed shape 722 + } MouseCursor; 723 + 724 + // Gamepad buttons 725 + typedef enum { 726 + GAMEPAD_BUTTON_UNKNOWN = 0, // Unknown button, just for error checking 727 + GAMEPAD_BUTTON_LEFT_FACE_UP, // Gamepad left DPAD up button 728 + GAMEPAD_BUTTON_LEFT_FACE_RIGHT, // Gamepad left DPAD right button 729 + GAMEPAD_BUTTON_LEFT_FACE_DOWN, // Gamepad left DPAD down button 730 + GAMEPAD_BUTTON_LEFT_FACE_LEFT, // Gamepad left DPAD left button 731 + GAMEPAD_BUTTON_RIGHT_FACE_UP, // Gamepad right button up (i.e. PS3: Triangle, Xbox: Y) 732 + GAMEPAD_BUTTON_RIGHT_FACE_RIGHT, // Gamepad right button right (i.e. PS3: Circle, Xbox: B) 733 + GAMEPAD_BUTTON_RIGHT_FACE_DOWN, // Gamepad right button down (i.e. PS3: Cross, Xbox: A) 734 + GAMEPAD_BUTTON_RIGHT_FACE_LEFT, // Gamepad right button left (i.e. PS3: Square, Xbox: X) 735 + GAMEPAD_BUTTON_LEFT_TRIGGER_1, // Gamepad top/back trigger left (first), it could be a trailing button 736 + GAMEPAD_BUTTON_LEFT_TRIGGER_2, // Gamepad top/back trigger left (second), it could be a trailing button 737 + GAMEPAD_BUTTON_RIGHT_TRIGGER_1, // Gamepad top/back trigger right (first), it could be a trailing button 738 + GAMEPAD_BUTTON_RIGHT_TRIGGER_2, // Gamepad top/back trigger right (second), it could be a trailing button 739 + GAMEPAD_BUTTON_MIDDLE_LEFT, // Gamepad center buttons, left one (i.e. PS3: Select) 740 + GAMEPAD_BUTTON_MIDDLE, // Gamepad center buttons, middle one (i.e. PS3: PS, Xbox: XBOX) 741 + GAMEPAD_BUTTON_MIDDLE_RIGHT, // Gamepad center buttons, right one (i.e. PS3: Start) 742 + GAMEPAD_BUTTON_LEFT_THUMB, // Gamepad joystick pressed button left 743 + GAMEPAD_BUTTON_RIGHT_THUMB // Gamepad joystick pressed button right 744 + } GamepadButton; 745 + 746 + // Gamepad axes 747 + typedef enum { 748 + GAMEPAD_AXIS_LEFT_X = 0, // Gamepad left stick X axis 749 + GAMEPAD_AXIS_LEFT_Y = 1, // Gamepad left stick Y axis 750 + GAMEPAD_AXIS_RIGHT_X = 2, // Gamepad right stick X axis 751 + GAMEPAD_AXIS_RIGHT_Y = 3, // Gamepad right stick Y axis 752 + GAMEPAD_AXIS_LEFT_TRIGGER = 4, // Gamepad back trigger left, pressure level: [1..-1] 753 + GAMEPAD_AXIS_RIGHT_TRIGGER = 5 // Gamepad back trigger right, pressure level: [1..-1] 754 + } GamepadAxis; 755 + 756 + // Material map index 757 + typedef enum { 758 + MATERIAL_MAP_ALBEDO = 0, // Albedo material (same as: MATERIAL_MAP_DIFFUSE) 759 + MATERIAL_MAP_METALNESS, // Metalness material (same as: MATERIAL_MAP_SPECULAR) 760 + MATERIAL_MAP_NORMAL, // Normal material 761 + MATERIAL_MAP_ROUGHNESS, // Roughness material 762 + MATERIAL_MAP_OCCLUSION, // Ambient occlusion material 763 + MATERIAL_MAP_EMISSION, // Emission material 764 + MATERIAL_MAP_HEIGHT, // Heightmap material 765 + MATERIAL_MAP_CUBEMAP, // Cubemap material (NOTE: Uses GL_TEXTURE_CUBE_MAP) 766 + MATERIAL_MAP_IRRADIANCE, // Irradiance material (NOTE: Uses GL_TEXTURE_CUBE_MAP) 767 + MATERIAL_MAP_PREFILTER, // Prefilter material (NOTE: Uses GL_TEXTURE_CUBE_MAP) 768 + MATERIAL_MAP_BRDF // Brdf material 769 + } MaterialMapIndex; 770 + 771 + #define MATERIAL_MAP_DIFFUSE MATERIAL_MAP_ALBEDO 772 + #define MATERIAL_MAP_SPECULAR MATERIAL_MAP_METALNESS 773 + 774 + // Shader location index 775 + typedef enum { 776 + SHADER_LOC_VERTEX_POSITION = 0, // Shader location: vertex attribute: position 777 + SHADER_LOC_VERTEX_TEXCOORD01, // Shader location: vertex attribute: texcoord01 778 + SHADER_LOC_VERTEX_TEXCOORD02, // Shader location: vertex attribute: texcoord02 779 + SHADER_LOC_VERTEX_NORMAL, // Shader location: vertex attribute: normal 780 + SHADER_LOC_VERTEX_TANGENT, // Shader location: vertex attribute: tangent 781 + SHADER_LOC_VERTEX_COLOR, // Shader location: vertex attribute: color 782 + SHADER_LOC_MATRIX_MVP, // Shader location: matrix uniform: model-view-projection 783 + SHADER_LOC_MATRIX_VIEW, // Shader location: matrix uniform: view (camera transform) 784 + SHADER_LOC_MATRIX_PROJECTION, // Shader location: matrix uniform: projection 785 + SHADER_LOC_MATRIX_MODEL, // Shader location: matrix uniform: model (transform) 786 + SHADER_LOC_MATRIX_NORMAL, // Shader location: matrix uniform: normal 787 + SHADER_LOC_VECTOR_VIEW, // Shader location: vector uniform: view 788 + SHADER_LOC_COLOR_DIFFUSE, // Shader location: vector uniform: diffuse color 789 + SHADER_LOC_COLOR_SPECULAR, // Shader location: vector uniform: specular color 790 + SHADER_LOC_COLOR_AMBIENT, // Shader location: vector uniform: ambient color 791 + SHADER_LOC_MAP_ALBEDO, // Shader location: sampler2d texture: albedo (same as: SHADER_LOC_MAP_DIFFUSE) 792 + SHADER_LOC_MAP_METALNESS, // Shader location: sampler2d texture: metalness (same as: SHADER_LOC_MAP_SPECULAR) 793 + SHADER_LOC_MAP_NORMAL, // Shader location: sampler2d texture: normal 794 + SHADER_LOC_MAP_ROUGHNESS, // Shader location: sampler2d texture: roughness 795 + SHADER_LOC_MAP_OCCLUSION, // Shader location: sampler2d texture: occlusion 796 + SHADER_LOC_MAP_EMISSION, // Shader location: sampler2d texture: emission 797 + SHADER_LOC_MAP_HEIGHT, // Shader location: sampler2d texture: height 798 + SHADER_LOC_MAP_CUBEMAP, // Shader location: samplerCube texture: cubemap 799 + SHADER_LOC_MAP_IRRADIANCE, // Shader location: samplerCube texture: irradiance 800 + SHADER_LOC_MAP_PREFILTER, // Shader location: samplerCube texture: prefilter 801 + SHADER_LOC_MAP_BRDF, // Shader location: sampler2d texture: brdf 802 + SHADER_LOC_VERTEX_BONEIDS, // Shader location: vertex attribute: boneIds 803 + SHADER_LOC_VERTEX_BONEWEIGHTS, // Shader location: vertex attribute: boneWeights 804 + SHADER_LOC_BONE_MATRICES, // Shader location: array of matrices uniform: boneMatrices 805 + SHADER_LOC_VERTEX_INSTANCE_TX // Shader location: vertex attribute: instanceTransform 806 + } ShaderLocationIndex; 807 + 808 + #define SHADER_LOC_MAP_DIFFUSE SHADER_LOC_MAP_ALBEDO 809 + #define SHADER_LOC_MAP_SPECULAR SHADER_LOC_MAP_METALNESS 810 + 811 + // Shader uniform data type 812 + typedef enum { 813 + SHADER_UNIFORM_FLOAT = 0, // Shader uniform type: float 814 + SHADER_UNIFORM_VEC2, // Shader uniform type: vec2 (2 float) 815 + SHADER_UNIFORM_VEC3, // Shader uniform type: vec3 (3 float) 816 + SHADER_UNIFORM_VEC4, // Shader uniform type: vec4 (4 float) 817 + SHADER_UNIFORM_INT, // Shader uniform type: int 818 + SHADER_UNIFORM_IVEC2, // Shader uniform type: ivec2 (2 int) 819 + SHADER_UNIFORM_IVEC3, // Shader uniform type: ivec3 (3 int) 820 + SHADER_UNIFORM_IVEC4, // Shader uniform type: ivec4 (4 int) 821 + SHADER_UNIFORM_UINT, // Shader uniform type: unsigned int 822 + SHADER_UNIFORM_UIVEC2, // Shader uniform type: uivec2 (2 unsigned int) 823 + SHADER_UNIFORM_UIVEC3, // Shader uniform type: uivec3 (3 unsigned int) 824 + SHADER_UNIFORM_UIVEC4, // Shader uniform type: uivec4 (4 unsigned int) 825 + SHADER_UNIFORM_SAMPLER2D // Shader uniform type: sampler2d 826 + } ShaderUniformDataType; 827 + 828 + // Shader attribute data types 829 + typedef enum { 830 + SHADER_ATTRIB_FLOAT = 0, // Shader attribute type: float 831 + SHADER_ATTRIB_VEC2, // Shader attribute type: vec2 (2 float) 832 + SHADER_ATTRIB_VEC3, // Shader attribute type: vec3 (3 float) 833 + SHADER_ATTRIB_VEC4 // Shader attribute type: vec4 (4 float) 834 + } ShaderAttributeDataType; 835 + 836 + // Pixel formats 837 + // NOTE: Support depends on OpenGL version and platform 838 + typedef enum { 839 + PIXELFORMAT_UNCOMPRESSED_GRAYSCALE = 1, // 8 bit per pixel (no alpha) 840 + PIXELFORMAT_UNCOMPRESSED_GRAY_ALPHA, // 8*2 bpp (2 channels) 841 + PIXELFORMAT_UNCOMPRESSED_R5G6B5, // 16 bpp 842 + PIXELFORMAT_UNCOMPRESSED_R8G8B8, // 24 bpp 843 + PIXELFORMAT_UNCOMPRESSED_R5G5B5A1, // 16 bpp (1 bit alpha) 844 + PIXELFORMAT_UNCOMPRESSED_R4G4B4A4, // 16 bpp (4 bit alpha) 845 + PIXELFORMAT_UNCOMPRESSED_R8G8B8A8, // 32 bpp 846 + PIXELFORMAT_UNCOMPRESSED_R32, // 32 bpp (1 channel - float) 847 + PIXELFORMAT_UNCOMPRESSED_R32G32B32, // 32*3 bpp (3 channels - float) 848 + PIXELFORMAT_UNCOMPRESSED_R32G32B32A32, // 32*4 bpp (4 channels - float) 849 + PIXELFORMAT_UNCOMPRESSED_R16, // 16 bpp (1 channel - half float) 850 + PIXELFORMAT_UNCOMPRESSED_R16G16B16, // 16*3 bpp (3 channels - half float) 851 + PIXELFORMAT_UNCOMPRESSED_R16G16B16A16, // 16*4 bpp (4 channels - half float) 852 + PIXELFORMAT_COMPRESSED_DXT1_RGB, // 4 bpp (no alpha) 853 + PIXELFORMAT_COMPRESSED_DXT1_RGBA, // 4 bpp (1 bit alpha) 854 + PIXELFORMAT_COMPRESSED_DXT3_RGBA, // 8 bpp 855 + PIXELFORMAT_COMPRESSED_DXT5_RGBA, // 8 bpp 856 + PIXELFORMAT_COMPRESSED_ETC1_RGB, // 4 bpp 857 + PIXELFORMAT_COMPRESSED_ETC2_RGB, // 4 bpp 858 + PIXELFORMAT_COMPRESSED_ETC2_EAC_RGBA, // 8 bpp 859 + PIXELFORMAT_COMPRESSED_PVRT_RGB, // 4 bpp 860 + PIXELFORMAT_COMPRESSED_PVRT_RGBA, // 4 bpp 861 + PIXELFORMAT_COMPRESSED_ASTC_4x4_RGBA, // 8 bpp 862 + PIXELFORMAT_COMPRESSED_ASTC_8x8_RGBA // 2 bpp 863 + } PixelFormat; 864 + 865 + // Texture parameters: filter mode 866 + // NOTE 1: Filtering considers mipmaps if available in the texture 867 + // NOTE 2: Filter is accordingly set for minification and magnification 868 + typedef enum { 869 + TEXTURE_FILTER_POINT = 0, // No filter, just pixel approximation 870 + TEXTURE_FILTER_BILINEAR, // Linear filtering 871 + TEXTURE_FILTER_TRILINEAR, // Trilinear filtering (linear with mipmaps) 872 + TEXTURE_FILTER_ANISOTROPIC_4X, // Anisotropic filtering 4x 873 + TEXTURE_FILTER_ANISOTROPIC_8X, // Anisotropic filtering 8x 874 + TEXTURE_FILTER_ANISOTROPIC_16X, // Anisotropic filtering 16x 875 + } TextureFilter; 876 + 877 + // Texture parameters: wrap mode 878 + typedef enum { 879 + TEXTURE_WRAP_REPEAT = 0, // Repeats texture in tiled mode 880 + TEXTURE_WRAP_CLAMP, // Clamps texture to edge pixel in tiled mode 881 + TEXTURE_WRAP_MIRROR_REPEAT, // Mirrors and repeats the texture in tiled mode 882 + TEXTURE_WRAP_MIRROR_CLAMP // Mirrors and clamps to border the texture in tiled mode 883 + } TextureWrap; 884 + 885 + // Cubemap layouts 886 + typedef enum { 887 + CUBEMAP_LAYOUT_AUTO_DETECT = 0, // Automatically detect layout type 888 + CUBEMAP_LAYOUT_LINE_VERTICAL, // Layout is defined by a vertical line with faces 889 + CUBEMAP_LAYOUT_LINE_HORIZONTAL, // Layout is defined by a horizontal line with faces 890 + CUBEMAP_LAYOUT_CROSS_THREE_BY_FOUR, // Layout is defined by a 3x4 cross with cubemap faces 891 + CUBEMAP_LAYOUT_CROSS_FOUR_BY_THREE // Layout is defined by a 4x3 cross with cubemap faces 892 + } CubemapLayout; 893 + 894 + // Font type, defines generation method 895 + typedef enum { 896 + FONT_DEFAULT = 0, // Default font generation, anti-aliased 897 + FONT_BITMAP, // Bitmap font generation, no anti-aliasing 898 + FONT_SDF // SDF font generation, requires external shader 899 + } FontType; 900 + 901 + // Color blending modes (pre-defined) 902 + typedef enum { 903 + BLEND_ALPHA = 0, // Blend textures considering alpha (default) 904 + BLEND_ADDITIVE, // Blend textures adding colors 905 + BLEND_MULTIPLIED, // Blend textures multiplying colors 906 + BLEND_ADD_COLORS, // Blend textures adding colors (alternative) 907 + BLEND_SUBTRACT_COLORS, // Blend textures subtracting colors (alternative) 908 + BLEND_ALPHA_PREMULTIPLY, // Blend premultiplied textures considering alpha 909 + BLEND_CUSTOM, // Blend textures using custom src/dst factors (use rlSetBlendFactors()) 910 + BLEND_CUSTOM_SEPARATE // Blend textures using custom rgb/alpha separate src/dst factors (use rlSetBlendFactorsSeparate()) 911 + } BlendMode; 912 + 913 + // Gesture 914 + // NOTE: Provided as bit-wise flags to enable only desired gestures 915 + typedef enum { 916 + GESTURE_NONE = 0, // No gesture 917 + GESTURE_TAP = 1, // Tap gesture 918 + GESTURE_DOUBLETAP = 2, // Double tap gesture 919 + GESTURE_HOLD = 4, // Hold gesture 920 + GESTURE_DRAG = 8, // Drag gesture 921 + GESTURE_SWIPE_RIGHT = 16, // Swipe right gesture 922 + GESTURE_SWIPE_LEFT = 32, // Swipe left gesture 923 + GESTURE_SWIPE_UP = 64, // Swipe up gesture 924 + GESTURE_SWIPE_DOWN = 128, // Swipe down gesture 925 + GESTURE_PINCH_IN = 256, // Pinch in gesture 926 + GESTURE_PINCH_OUT = 512 // Pinch out gesture 927 + } Gesture; 928 + 929 + // Camera system modes 930 + typedef enum { 931 + CAMERA_CUSTOM = 0, // Camera custom, controlled by user (UpdateCamera() does nothing) 932 + CAMERA_FREE, // Camera free mode 933 + CAMERA_ORBITAL, // Camera orbital, around target, zoom supported 934 + CAMERA_FIRST_PERSON, // Camera first person 935 + CAMERA_THIRD_PERSON // Camera third person 936 + } CameraMode; 937 + 938 + // Camera projection 939 + typedef enum { 940 + CAMERA_PERSPECTIVE = 0, // Perspective projection 941 + CAMERA_ORTHOGRAPHIC // Orthographic projection 942 + } CameraProjection; 943 + 944 + // N-patch layout 945 + typedef enum { 946 + NPATCH_NINE_PATCH = 0, // Npatch layout: 3x3 tiles 947 + NPATCH_THREE_PATCH_VERTICAL, // Npatch layout: 1x3 tiles 948 + NPATCH_THREE_PATCH_HORIZONTAL // Npatch layout: 3x1 tiles 949 + } NPatchLayout; 950 + 951 + // Callbacks to hook some internal functions 952 + // WARNING: These callbacks are intended for advanced users 953 + typedef void (*TraceLogCallback)(int logLevel, const char *text, va_list args); // Logging: Redirect trace log messages 954 + typedef unsigned char *(*LoadFileDataCallback)(const char *fileName, int *dataSize); // FileIO: Load binary data 955 + typedef bool (*SaveFileDataCallback)(const char *fileName, void *data, int dataSize); // FileIO: Save binary data 956 + typedef char *(*LoadFileTextCallback)(const char *fileName); // FileIO: Load text data 957 + typedef bool (*SaveFileTextCallback)(const char *fileName, const char *text); // FileIO: Save text data 958 + 959 + //------------------------------------------------------------------------------------ 960 + // Global Variables Definition 961 + //------------------------------------------------------------------------------------ 962 + // It's lonely here... 963 + 964 + //------------------------------------------------------------------------------------ 965 + // Window and Graphics Device Functions (Module: core) 966 + //------------------------------------------------------------------------------------ 967 + 968 + #if defined(__cplusplus) 969 + extern "C" { // Prevents name mangling of functions 970 + #endif 971 + 972 + // Window-related functions 973 + RLAPI void InitWindow(int width, int height, const char *title); // Initialize window and OpenGL context 974 + RLAPI void CloseWindow(void); // Close window and unload OpenGL context 975 + RLAPI bool WindowShouldClose(void); // Check if application should close (KEY_ESCAPE pressed or windows close icon clicked) 976 + RLAPI bool IsWindowReady(void); // Check if window has been initialized successfully 977 + RLAPI bool IsWindowFullscreen(void); // Check if window is currently fullscreen 978 + RLAPI bool IsWindowHidden(void); // Check if window is currently hidden 979 + RLAPI bool IsWindowMinimized(void); // Check if window is currently minimized 980 + RLAPI bool IsWindowMaximized(void); // Check if window is currently maximized 981 + RLAPI bool IsWindowFocused(void); // Check if window is currently focused 982 + RLAPI bool IsWindowResized(void); // Check if window has been resized last frame 983 + RLAPI bool IsWindowState(unsigned int flag); // Check if one specific window flag is enabled 984 + RLAPI void SetWindowState(unsigned int flags); // Set window configuration state using flags 985 + RLAPI void ClearWindowState(unsigned int flags); // Clear window configuration state flags 986 + RLAPI void ToggleFullscreen(void); // Toggle window state: fullscreen/windowed, resizes monitor to match window resolution 987 + RLAPI void ToggleBorderlessWindowed(void); // Toggle window state: borderless windowed, resizes window to match monitor resolution 988 + RLAPI void MaximizeWindow(void); // Set window state: maximized, if resizable 989 + RLAPI void MinimizeWindow(void); // Set window state: minimized, if resizable 990 + RLAPI void RestoreWindow(void); // Restore window from being minimized/maximized 991 + RLAPI void SetWindowIcon(Image image); // Set icon for window (single image, RGBA 32bit) 992 + RLAPI void SetWindowIcons(Image *images, int count); // Set icon for window (multiple images, RGBA 32bit) 993 + RLAPI void SetWindowTitle(const char *title); // Set title for window 994 + RLAPI void SetWindowPosition(int x, int y); // Set window position on screen 995 + RLAPI void SetWindowMonitor(int monitor); // Set monitor for the current window 996 + RLAPI void SetWindowMinSize(int width, int height); // Set window minimum dimensions (for FLAG_WINDOW_RESIZABLE) 997 + RLAPI void SetWindowMaxSize(int width, int height); // Set window maximum dimensions (for FLAG_WINDOW_RESIZABLE) 998 + RLAPI void SetWindowSize(int width, int height); // Set window dimensions 999 + RLAPI void SetWindowOpacity(float opacity); // Set window opacity [0.0f..1.0f] 1000 + RLAPI void SetWindowFocused(void); // Set window focused 1001 + RLAPI void *GetWindowHandle(void); // Get native window handle 1002 + RLAPI int GetScreenWidth(void); // Get current screen width 1003 + RLAPI int GetScreenHeight(void); // Get current screen height 1004 + RLAPI int GetRenderWidth(void); // Get current render width (it considers HiDPI) 1005 + RLAPI int GetRenderHeight(void); // Get current render height (it considers HiDPI) 1006 + RLAPI int GetMonitorCount(void); // Get number of connected monitors 1007 + RLAPI int GetCurrentMonitor(void); // Get current monitor where window is placed 1008 + RLAPI Vector2 GetMonitorPosition(int monitor); // Get specified monitor position 1009 + RLAPI int GetMonitorWidth(int monitor); // Get specified monitor width (current video mode used by monitor) 1010 + RLAPI int GetMonitorHeight(int monitor); // Get specified monitor height (current video mode used by monitor) 1011 + RLAPI int GetMonitorPhysicalWidth(int monitor); // Get specified monitor physical width in millimetres 1012 + RLAPI int GetMonitorPhysicalHeight(int monitor); // Get specified monitor physical height in millimetres 1013 + RLAPI int GetMonitorRefreshRate(int monitor); // Get specified monitor refresh rate 1014 + RLAPI Vector2 GetWindowPosition(void); // Get window position XY on monitor 1015 + RLAPI Vector2 GetWindowScaleDPI(void); // Get window scale DPI factor 1016 + RLAPI const char *GetMonitorName(int monitor); // Get the human-readable, UTF-8 encoded name of the specified monitor 1017 + RLAPI void SetClipboardText(const char *text); // Set clipboard text content 1018 + RLAPI const char *GetClipboardText(void); // Get clipboard text content 1019 + RLAPI Image GetClipboardImage(void); // Get clipboard image content 1020 + RLAPI void EnableEventWaiting(void); // Enable waiting for events on EndDrawing(), no automatic event polling 1021 + RLAPI void DisableEventWaiting(void); // Disable waiting for events on EndDrawing(), automatic events polling 1022 + 1023 + // Cursor-related functions 1024 + RLAPI void ShowCursor(void); // Shows cursor 1025 + RLAPI void HideCursor(void); // Hides cursor 1026 + RLAPI bool IsCursorHidden(void); // Check if cursor is not visible 1027 + RLAPI void EnableCursor(void); // Enables cursor (unlock cursor) 1028 + RLAPI void DisableCursor(void); // Disables cursor (lock cursor) 1029 + RLAPI bool IsCursorOnScreen(void); // Check if cursor is on the screen 1030 + 1031 + // Drawing-related functions 1032 + RLAPI void ClearBackground(Color color); // Set background color (framebuffer clear color) 1033 + RLAPI void BeginDrawing(void); // Setup canvas (framebuffer) to start drawing 1034 + RLAPI void EndDrawing(void); // End canvas drawing and swap buffers (double buffering) 1035 + RLAPI void BeginMode2D(Camera2D camera); // Begin 2D mode with custom camera (2D) 1036 + RLAPI void EndMode2D(void); // Ends 2D mode with custom camera 1037 + RLAPI void BeginMode3D(Camera3D camera); // Begin 3D mode with custom camera (3D) 1038 + RLAPI void EndMode3D(void); // Ends 3D mode and returns to default 2D orthographic mode 1039 + RLAPI void BeginTextureMode(RenderTexture2D target); // Begin drawing to render texture 1040 + RLAPI void EndTextureMode(void); // Ends drawing to render texture 1041 + RLAPI void BeginShaderMode(Shader shader); // Begin custom shader drawing 1042 + RLAPI void EndShaderMode(void); // End custom shader drawing (use default shader) 1043 + RLAPI void BeginBlendMode(int mode); // Begin blending mode (alpha, additive, multiplied, subtract, custom) 1044 + RLAPI void EndBlendMode(void); // End blending mode (reset to default: alpha blending) 1045 + RLAPI void BeginScissorMode(int x, int y, int width, int height); // Begin scissor mode (define screen area for following drawing) 1046 + RLAPI void EndScissorMode(void); // End scissor mode 1047 + RLAPI void BeginVrStereoMode(VrStereoConfig config); // Begin stereo rendering (requires VR simulator) 1048 + RLAPI void EndVrStereoMode(void); // End stereo rendering (requires VR simulator) 1049 + 1050 + // VR stereo config functions for VR simulator 1051 + RLAPI VrStereoConfig LoadVrStereoConfig(VrDeviceInfo device); // Load VR stereo config for VR simulator device parameters 1052 + RLAPI void UnloadVrStereoConfig(VrStereoConfig config); // Unload VR stereo config 1053 + 1054 + // Shader management functions 1055 + // NOTE: Shader functionality is not available on OpenGL 1.1 1056 + RLAPI Shader LoadShader(const char *vsFileName, const char *fsFileName); // Load shader from files and bind default locations 1057 + RLAPI Shader LoadShaderFromMemory(const char *vsCode, const char *fsCode); // Load shader from code strings and bind default locations 1058 + RLAPI bool IsShaderValid(Shader shader); // Check if a shader is valid (loaded on GPU) 1059 + RLAPI int GetShaderLocation(Shader shader, const char *uniformName); // Get shader uniform location 1060 + RLAPI int GetShaderLocationAttrib(Shader shader, const char *attribName); // Get shader attribute location 1061 + RLAPI void SetShaderValue(Shader shader, int locIndex, const void *value, int uniformType); // Set shader uniform value 1062 + RLAPI void SetShaderValueV(Shader shader, int locIndex, const void *value, int uniformType, int count); // Set shader uniform value vector 1063 + RLAPI void SetShaderValueMatrix(Shader shader, int locIndex, Matrix mat); // Set shader uniform value (matrix 4x4) 1064 + RLAPI void SetShaderValueTexture(Shader shader, int locIndex, Texture2D texture); // Set shader uniform value and bind the texture (sampler2d) 1065 + RLAPI void UnloadShader(Shader shader); // Unload shader from GPU memory (VRAM) 1066 + 1067 + // Screen-space-related functions 1068 + #define GetMouseRay GetScreenToWorldRay // Compatibility hack for previous raylib versions 1069 + RLAPI Ray GetScreenToWorldRay(Vector2 position, Camera camera); // Get a ray trace from screen position (i.e mouse) 1070 + RLAPI Ray GetScreenToWorldRayEx(Vector2 position, Camera camera, int width, int height); // Get a ray trace from screen position (i.e mouse) in a viewport 1071 + RLAPI Vector2 GetWorldToScreen(Vector3 position, Camera camera); // Get the screen space position for a 3d world space position 1072 + RLAPI Vector2 GetWorldToScreenEx(Vector3 position, Camera camera, int width, int height); // Get size position for a 3d world space position 1073 + RLAPI Vector2 GetWorldToScreen2D(Vector2 position, Camera2D camera); // Get the screen space position for a 2d camera world space position 1074 + RLAPI Vector2 GetScreenToWorld2D(Vector2 position, Camera2D camera); // Get the world space position for a 2d camera screen space position 1075 + RLAPI Matrix GetCameraMatrix(Camera camera); // Get camera transform matrix (view matrix) 1076 + RLAPI Matrix GetCameraMatrix2D(Camera2D camera); // Get camera 2d transform matrix 1077 + 1078 + // Timing-related functions 1079 + RLAPI void SetTargetFPS(int fps); // Set target FPS (maximum) 1080 + RLAPI float GetFrameTime(void); // Get time in seconds for last frame drawn (delta time) 1081 + RLAPI double GetTime(void); // Get elapsed time in seconds since InitWindow() 1082 + RLAPI int GetFPS(void); // Get current FPS 1083 + 1084 + // Custom frame control functions 1085 + // NOTE: Those functions are intended for advanced users that want full control over the frame processing 1086 + // By default EndDrawing() does this job: draws everything + SwapScreenBuffer() + manage frame timing + PollInputEvents() 1087 + // To avoid that behaviour and control frame processes manually, enable in config.h: SUPPORT_CUSTOM_FRAME_CONTROL 1088 + RLAPI void SwapScreenBuffer(void); // Swap back buffer with front buffer (screen drawing) 1089 + RLAPI void PollInputEvents(void); // Register all input events 1090 + RLAPI void WaitTime(double seconds); // Wait for some time (halt program execution) 1091 + 1092 + // Random values generation functions 1093 + RLAPI void SetRandomSeed(unsigned int seed); // Set the seed for the random number generator 1094 + RLAPI int GetRandomValue(int min, int max); // Get a random value between min and max (both included) 1095 + RLAPI int *LoadRandomSequence(unsigned int count, int min, int max); // Load random values sequence, no values repeated 1096 + RLAPI void UnloadRandomSequence(int *sequence); // Unload random values sequence 1097 + 1098 + // Misc. functions 1099 + RLAPI void TakeScreenshot(const char *fileName); // Takes a screenshot of current screen (filename extension defines format) 1100 + RLAPI void SetConfigFlags(unsigned int flags); // Setup init configuration flags (view FLAGS) 1101 + RLAPI void OpenURL(const char *url); // Open URL with default system browser (if available) 1102 + 1103 + // NOTE: Following functions implemented in module [utils] 1104 + //------------------------------------------------------------------ 1105 + RLAPI void TraceLog(int logLevel, const char *text, ...); // Show trace log messages (LOG_DEBUG, LOG_INFO, LOG_WARNING, LOG_ERROR...) 1106 + RLAPI void SetTraceLogLevel(int logLevel); // Set the current threshold (minimum) log level 1107 + RLAPI void *MemAlloc(unsigned int size); // Internal memory allocator 1108 + RLAPI void *MemRealloc(void *ptr, unsigned int size); // Internal memory reallocator 1109 + RLAPI void MemFree(void *ptr); // Internal memory free 1110 + 1111 + // Set custom callbacks 1112 + // WARNING: Callbacks setup is intended for advanced users 1113 + RLAPI void SetTraceLogCallback(TraceLogCallback callback); // Set custom trace log 1114 + RLAPI void SetLoadFileDataCallback(LoadFileDataCallback callback); // Set custom file binary data loader 1115 + RLAPI void SetSaveFileDataCallback(SaveFileDataCallback callback); // Set custom file binary data saver 1116 + RLAPI void SetLoadFileTextCallback(LoadFileTextCallback callback); // Set custom file text data loader 1117 + RLAPI void SetSaveFileTextCallback(SaveFileTextCallback callback); // Set custom file text data saver 1118 + 1119 + // Files management functions 1120 + RLAPI unsigned char *LoadFileData(const char *fileName, int *dataSize); // Load file data as byte array (read) 1121 + RLAPI void UnloadFileData(unsigned char *data); // Unload file data allocated by LoadFileData() 1122 + RLAPI bool SaveFileData(const char *fileName, void *data, int dataSize); // Save data to file from byte array (write), returns true on success 1123 + RLAPI bool ExportDataAsCode(const unsigned char *data, int dataSize, const char *fileName); // Export data to code (.h), returns true on success 1124 + RLAPI char *LoadFileText(const char *fileName); // Load text data from file (read), returns a '\0' terminated string 1125 + RLAPI void UnloadFileText(char *text); // Unload file text data allocated by LoadFileText() 1126 + RLAPI bool SaveFileText(const char *fileName, const char *text); // Save text data to file (write), string must be '\0' terminated, returns true on success 1127 + //------------------------------------------------------------------ 1128 + 1129 + // File system functions 1130 + RLAPI int FileRename(const char *fileName, const char *fileRename); // Rename file (if exists) 1131 + RLAPI int FileRemove(const char *fileName); // Remove file (if exists) 1132 + RLAPI int FileCopy(const char *srcPath, const char *dstPath); // Copy file from one path to another, dstPath created if it doesn't exist 1133 + RLAPI int FileMove(const char *srcPath, const char *dstPath); // Move file from one directory to another, dstPath created if it doesn't exist 1134 + RLAPI int FileTextReplace(const char *fileName, const char *search, const char *replacement); // Replace text in an existing file 1135 + RLAPI int FileTextFindIndex(const char *fileName, const char *search); // Find text in existing file 1136 + RLAPI bool FileExists(const char *fileName); // Check if file exists 1137 + RLAPI bool DirectoryExists(const char *dirPath); // Check if a directory path exists 1138 + RLAPI bool IsFileExtension(const char *fileName, const char *ext); // Check file extension (recommended include point: .png, .wav) 1139 + RLAPI int GetFileLength(const char *fileName); // Get file length in bytes (NOTE: GetFileSize() conflicts with windows.h) 1140 + RLAPI long GetFileModTime(const char *fileName); // Get file modification time (last write time) 1141 + RLAPI const char *GetFileExtension(const char *fileName); // Get pointer to extension for a filename string (includes dot: '.png') 1142 + RLAPI const char *GetFileName(const char *filePath); // Get pointer to filename for a path string 1143 + RLAPI const char *GetFileNameWithoutExt(const char *filePath); // Get filename string without extension (uses static string) 1144 + RLAPI const char *GetDirectoryPath(const char *filePath); // Get full path for a given fileName with path (uses static string) 1145 + RLAPI const char *GetPrevDirectoryPath(const char *dirPath); // Get previous directory path for a given path (uses static string) 1146 + RLAPI const char *GetWorkingDirectory(void); // Get current working directory (uses static string) 1147 + RLAPI const char *GetApplicationDirectory(void); // Get the directory of the running application (uses static string) 1148 + RLAPI int MakeDirectory(const char *dirPath); // Create directories (including full path requested), returns 0 on success 1149 + RLAPI bool ChangeDirectory(const char *dir); // Change working directory, return true on success 1150 + RLAPI bool IsPathFile(const char *path); // Check if a given path is a file or a directory 1151 + RLAPI bool IsFileNameValid(const char *fileName); // Check if fileName is valid for the platform/OS 1152 + RLAPI FilePathList LoadDirectoryFiles(const char *dirPath); // Load directory filepaths 1153 + RLAPI FilePathList LoadDirectoryFilesEx(const char *basePath, const char *filter, bool scanSubdirs); // Load directory filepaths with extension filtering and recursive directory scan. Use 'DIR' in the filter string to include directories in the result 1154 + RLAPI void UnloadDirectoryFiles(FilePathList files); // Unload filepaths 1155 + RLAPI bool IsFileDropped(void); // Check if a file has been dropped into window 1156 + RLAPI FilePathList LoadDroppedFiles(void); // Load dropped filepaths 1157 + RLAPI void UnloadDroppedFiles(FilePathList files); // Unload dropped filepaths 1158 + 1159 + // Compression/Encoding functionality 1160 + RLAPI unsigned char *CompressData(const unsigned char *data, int dataSize, int *compDataSize); // Compress data (DEFLATE algorithm), memory must be MemFree() 1161 + RLAPI unsigned char *DecompressData(const unsigned char *compData, int compDataSize, int *dataSize); // Decompress data (DEFLATE algorithm), memory must be MemFree() 1162 + RLAPI char *EncodeDataBase64(const unsigned char *data, int dataSize, int *outputSize); // Encode data to Base64 string (includes NULL terminator), memory must be MemFree() 1163 + RLAPI unsigned char *DecodeDataBase64(const char *text, int *outputSize); // Decode Base64 string (expected NULL terminated), memory must be MemFree() 1164 + RLAPI unsigned int ComputeCRC32(unsigned char *data, int dataSize); // Compute CRC32 hash code 1165 + RLAPI unsigned int *ComputeMD5(unsigned char *data, int dataSize); // Compute MD5 hash code, returns static int[4] (16 bytes) 1166 + RLAPI unsigned int *ComputeSHA1(unsigned char *data, int dataSize); // Compute SHA1 hash code, returns static int[5] (20 bytes) 1167 + 1168 + // Automation events functionality 1169 + RLAPI AutomationEventList LoadAutomationEventList(const char *fileName); // Load automation events list from file, NULL for empty list, capacity = MAX_AUTOMATION_EVENTS 1170 + RLAPI void UnloadAutomationEventList(AutomationEventList list); // Unload automation events list from file 1171 + RLAPI bool ExportAutomationEventList(AutomationEventList list, const char *fileName); // Export automation events list as text file 1172 + RLAPI void SetAutomationEventList(AutomationEventList *list); // Set automation event list to record to 1173 + RLAPI void SetAutomationEventBaseFrame(int frame); // Set automation event internal base frame to start recording 1174 + RLAPI void StartAutomationEventRecording(void); // Start recording automation events (AutomationEventList must be set) 1175 + RLAPI void StopAutomationEventRecording(void); // Stop recording automation events 1176 + RLAPI void PlayAutomationEvent(AutomationEvent event); // Play a recorded automation event 1177 + 1178 + //------------------------------------------------------------------------------------ 1179 + // Input Handling Functions (Module: core) 1180 + //------------------------------------------------------------------------------------ 1181 + 1182 + // Input-related functions: keyboard 1183 + RLAPI bool IsKeyPressed(int key); // Check if a key has been pressed once 1184 + RLAPI bool IsKeyPressedRepeat(int key); // Check if a key has been pressed again 1185 + RLAPI bool IsKeyDown(int key); // Check if a key is being pressed 1186 + RLAPI bool IsKeyReleased(int key); // Check if a key has been released once 1187 + RLAPI bool IsKeyUp(int key); // Check if a key is NOT being pressed 1188 + RLAPI int GetKeyPressed(void); // Get key pressed (keycode), call it multiple times for keys queued, returns 0 when the queue is empty 1189 + RLAPI int GetCharPressed(void); // Get char pressed (unicode), call it multiple times for chars queued, returns 0 when the queue is empty 1190 + RLAPI const char *GetKeyName(int key); // Get name of a QWERTY key on the current keyboard layout (eg returns string 'q' for KEY_A on an AZERTY keyboard) 1191 + RLAPI void SetExitKey(int key); // Set a custom key to exit program (default is ESC) 1192 + 1193 + // Input-related functions: gamepads 1194 + RLAPI bool IsGamepadAvailable(int gamepad); // Check if a gamepad is available 1195 + RLAPI const char *GetGamepadName(int gamepad); // Get gamepad internal name id 1196 + RLAPI bool IsGamepadButtonPressed(int gamepad, int button); // Check if a gamepad button has been pressed once 1197 + RLAPI bool IsGamepadButtonDown(int gamepad, int button); // Check if a gamepad button is being pressed 1198 + RLAPI bool IsGamepadButtonReleased(int gamepad, int button); // Check if a gamepad button has been released once 1199 + RLAPI bool IsGamepadButtonUp(int gamepad, int button); // Check if a gamepad button is NOT being pressed 1200 + RLAPI int GetGamepadButtonPressed(void); // Get the last gamepad button pressed 1201 + RLAPI int GetGamepadAxisCount(int gamepad); // Get axis count for a gamepad 1202 + RLAPI float GetGamepadAxisMovement(int gamepad, int axis); // Get movement value for a gamepad axis 1203 + RLAPI int SetGamepadMappings(const char *mappings); // Set internal gamepad mappings (SDL_GameControllerDB) 1204 + RLAPI void SetGamepadVibration(int gamepad, float leftMotor, float rightMotor, float duration); // Set gamepad vibration for both motors (duration in seconds) 1205 + 1206 + // Input-related functions: mouse 1207 + RLAPI bool IsMouseButtonPressed(int button); // Check if a mouse button has been pressed once 1208 + RLAPI bool IsMouseButtonDown(int button); // Check if a mouse button is being pressed 1209 + RLAPI bool IsMouseButtonReleased(int button); // Check if a mouse button has been released once 1210 + RLAPI bool IsMouseButtonUp(int button); // Check if a mouse button is NOT being pressed 1211 + RLAPI int GetMouseX(void); // Get mouse position X 1212 + RLAPI int GetMouseY(void); // Get mouse position Y 1213 + RLAPI Vector2 GetMousePosition(void); // Get mouse position XY 1214 + RLAPI Vector2 GetMouseDelta(void); // Get mouse delta between frames 1215 + RLAPI void SetMousePosition(int x, int y); // Set mouse position XY 1216 + RLAPI void SetMouseOffset(int offsetX, int offsetY); // Set mouse offset 1217 + RLAPI void SetMouseScale(float scaleX, float scaleY); // Set mouse scaling 1218 + RLAPI float GetMouseWheelMove(void); // Get mouse wheel movement for X or Y, whichever is larger 1219 + RLAPI Vector2 GetMouseWheelMoveV(void); // Get mouse wheel movement for both X and Y 1220 + RLAPI void SetMouseCursor(int cursor); // Set mouse cursor 1221 + 1222 + // Input-related functions: touch 1223 + RLAPI int GetTouchX(void); // Get touch position X for touch point 0 (relative to screen size) 1224 + RLAPI int GetTouchY(void); // Get touch position Y for touch point 0 (relative to screen size) 1225 + RLAPI Vector2 GetTouchPosition(int index); // Get touch position XY for a touch point index (relative to screen size) 1226 + RLAPI int GetTouchPointId(int index); // Get touch point identifier for given index 1227 + RLAPI int GetTouchPointCount(void); // Get number of touch points 1228 + 1229 + //------------------------------------------------------------------------------------ 1230 + // Gestures and Touch Handling Functions (Module: rgestures) 1231 + //------------------------------------------------------------------------------------ 1232 + RLAPI void SetGesturesEnabled(unsigned int flags); // Enable a set of gestures using flags 1233 + RLAPI bool IsGestureDetected(unsigned int gesture); // Check if a gesture have been detected 1234 + RLAPI int GetGestureDetected(void); // Get latest detected gesture 1235 + RLAPI float GetGestureHoldDuration(void); // Get gesture hold time in seconds 1236 + RLAPI Vector2 GetGestureDragVector(void); // Get gesture drag vector 1237 + RLAPI float GetGestureDragAngle(void); // Get gesture drag angle 1238 + RLAPI Vector2 GetGesturePinchVector(void); // Get gesture pinch delta 1239 + RLAPI float GetGesturePinchAngle(void); // Get gesture pinch angle 1240 + 1241 + //------------------------------------------------------------------------------------ 1242 + // Camera System Functions (Module: rcamera) 1243 + //------------------------------------------------------------------------------------ 1244 + RLAPI void UpdateCamera(Camera *camera, int mode); // Update camera position for selected mode 1245 + RLAPI void UpdateCameraPro(Camera *camera, Vector3 movement, Vector3 rotation, float zoom); // Update camera movement/rotation 1246 + 1247 + //------------------------------------------------------------------------------------ 1248 + // Basic Shapes Drawing Functions (Module: shapes) 1249 + //------------------------------------------------------------------------------------ 1250 + // Set texture and rectangle to be used on shapes drawing 1251 + // NOTE: It can be useful when using basic shapes and one single font, 1252 + // defining a font char white rectangle would allow drawing everything in a single draw call 1253 + RLAPI void SetShapesTexture(Texture2D texture, Rectangle source); // Set texture and rectangle to be used on shapes drawing 1254 + RLAPI Texture2D GetShapesTexture(void); // Get texture that is used for shapes drawing 1255 + RLAPI Rectangle GetShapesTextureRectangle(void); // Get texture source rectangle that is used for shapes drawing 1256 + 1257 + // Basic shapes drawing functions 1258 + RLAPI void DrawPixel(int posX, int posY, Color color); // Draw a pixel using geometry [Can be slow, use with care] 1259 + RLAPI void DrawPixelV(Vector2 position, Color color); // Draw a pixel using geometry (Vector version) [Can be slow, use with care] 1260 + RLAPI void DrawLine(int startPosX, int startPosY, int endPosX, int endPosY, Color color); // Draw a line 1261 + RLAPI void DrawLineV(Vector2 startPos, Vector2 endPos, Color color); // Draw a line (using gl lines) 1262 + RLAPI void DrawLineEx(Vector2 startPos, Vector2 endPos, float thick, Color color); // Draw a line (using triangles/quads) 1263 + RLAPI void DrawLineStrip(const Vector2 *points, int pointCount, Color color); // Draw lines sequence (using gl lines) 1264 + RLAPI void DrawLineBezier(Vector2 startPos, Vector2 endPos, float thick, Color color); // Draw line segment cubic-bezier in-out interpolation 1265 + RLAPI void DrawLineDashed(Vector2 startPos, Vector2 endPos, int dashSize, int spaceSize, Color color); // Draw a dashed line 1266 + RLAPI void DrawCircle(int centerX, int centerY, float radius, Color color); // Draw a color-filled circle 1267 + RLAPI void DrawCircleSector(Vector2 center, float radius, float startAngle, float endAngle, int segments, Color color); // Draw a piece of a circle 1268 + RLAPI void DrawCircleSectorLines(Vector2 center, float radius, float startAngle, float endAngle, int segments, Color color); // Draw circle sector outline 1269 + RLAPI void DrawCircleGradient(int centerX, int centerY, float radius, Color inner, Color outer); // Draw a gradient-filled circle 1270 + RLAPI void DrawCircleV(Vector2 center, float radius, Color color); // Draw a color-filled circle (Vector version) 1271 + RLAPI void DrawCircleLines(int centerX, int centerY, float radius, Color color); // Draw circle outline 1272 + RLAPI void DrawCircleLinesV(Vector2 center, float radius, Color color); // Draw circle outline (Vector version) 1273 + RLAPI void DrawEllipse(int centerX, int centerY, float radiusH, float radiusV, Color color); // Draw ellipse 1274 + RLAPI void DrawEllipseV(Vector2 center, float radiusH, float radiusV, Color color); // Draw ellipse (Vector version) 1275 + RLAPI void DrawEllipseLines(int centerX, int centerY, float radiusH, float radiusV, Color color); // Draw ellipse outline 1276 + RLAPI void DrawEllipseLinesV(Vector2 center, float radiusH, float radiusV, Color color); // Draw ellipse outline (Vector version) 1277 + RLAPI void DrawRing(Vector2 center, float innerRadius, float outerRadius, float startAngle, float endAngle, int segments, Color color); // Draw ring 1278 + RLAPI void DrawRingLines(Vector2 center, float innerRadius, float outerRadius, float startAngle, float endAngle, int segments, Color color); // Draw ring outline 1279 + RLAPI void DrawRectangle(int posX, int posY, int width, int height, Color color); // Draw a color-filled rectangle 1280 + RLAPI void DrawRectangleV(Vector2 position, Vector2 size, Color color); // Draw a color-filled rectangle (Vector version) 1281 + RLAPI void DrawRectangleRec(Rectangle rec, Color color); // Draw a color-filled rectangle 1282 + RLAPI void DrawRectanglePro(Rectangle rec, Vector2 origin, float rotation, Color color); // Draw a color-filled rectangle with pro parameters 1283 + RLAPI void DrawRectangleGradientV(int posX, int posY, int width, int height, Color top, Color bottom); // Draw a vertical-gradient-filled rectangle 1284 + RLAPI void DrawRectangleGradientH(int posX, int posY, int width, int height, Color left, Color right); // Draw a horizontal-gradient-filled rectangle 1285 + RLAPI void DrawRectangleGradientEx(Rectangle rec, Color topLeft, Color bottomLeft, Color bottomRight, Color topRight); // Draw a gradient-filled rectangle with custom vertex colors 1286 + RLAPI void DrawRectangleLines(int posX, int posY, int width, int height, Color color); // Draw rectangle outline 1287 + RLAPI void DrawRectangleLinesEx(Rectangle rec, float lineThick, Color color); // Draw rectangle outline with extended parameters 1288 + RLAPI void DrawRectangleRounded(Rectangle rec, float roundness, int segments, Color color); // Draw rectangle with rounded edges 1289 + RLAPI void DrawRectangleRoundedLines(Rectangle rec, float roundness, int segments, Color color); // Draw rectangle lines with rounded edges 1290 + RLAPI void DrawRectangleRoundedLinesEx(Rectangle rec, float roundness, int segments, float lineThick, Color color); // Draw rectangle with rounded edges outline 1291 + RLAPI void DrawTriangle(Vector2 v1, Vector2 v2, Vector2 v3, Color color); // Draw a color-filled triangle (vertex in counter-clockwise order!) 1292 + RLAPI void DrawTriangleLines(Vector2 v1, Vector2 v2, Vector2 v3, Color color); // Draw triangle outline (vertex in counter-clockwise order!) 1293 + RLAPI void DrawTriangleFan(const Vector2 *points, int pointCount, Color color); // Draw a triangle fan defined by points (first vertex is the center) 1294 + RLAPI void DrawTriangleStrip(const Vector2 *points, int pointCount, Color color); // Draw a triangle strip defined by points 1295 + RLAPI void DrawPoly(Vector2 center, int sides, float radius, float rotation, Color color); // Draw a regular polygon (Vector version) 1296 + RLAPI void DrawPolyLines(Vector2 center, int sides, float radius, float rotation, Color color); // Draw a polygon outline of n sides 1297 + RLAPI void DrawPolyLinesEx(Vector2 center, int sides, float radius, float rotation, float lineThick, Color color); // Draw a polygon outline of n sides with extended parameters 1298 + 1299 + // Splines drawing functions 1300 + RLAPI void DrawSplineLinear(const Vector2 *points, int pointCount, float thick, Color color); // Draw spline: Linear, minimum 2 points 1301 + RLAPI void DrawSplineBasis(const Vector2 *points, int pointCount, float thick, Color color); // Draw spline: B-Spline, minimum 4 points 1302 + RLAPI void DrawSplineCatmullRom(const Vector2 *points, int pointCount, float thick, Color color); // Draw spline: Catmull-Rom, minimum 4 points 1303 + RLAPI void DrawSplineBezierQuadratic(const Vector2 *points, int pointCount, float thick, Color color); // Draw spline: Quadratic Bezier, minimum 3 points (1 control point): [p1, c2, p3, c4...] 1304 + RLAPI void DrawSplineBezierCubic(const Vector2 *points, int pointCount, float thick, Color color); // Draw spline: Cubic Bezier, minimum 4 points (2 control points): [p1, c2, c3, p4, c5, c6...] 1305 + RLAPI void DrawSplineSegmentLinear(Vector2 p1, Vector2 p2, float thick, Color color); // Draw spline segment: Linear, 2 points 1306 + RLAPI void DrawSplineSegmentBasis(Vector2 p1, Vector2 p2, Vector2 p3, Vector2 p4, float thick, Color color); // Draw spline segment: B-Spline, 4 points 1307 + RLAPI void DrawSplineSegmentCatmullRom(Vector2 p1, Vector2 p2, Vector2 p3, Vector2 p4, float thick, Color color); // Draw spline segment: Catmull-Rom, 4 points 1308 + RLAPI void DrawSplineSegmentBezierQuadratic(Vector2 p1, Vector2 c2, Vector2 p3, float thick, Color color); // Draw spline segment: Quadratic Bezier, 2 points, 1 control point 1309 + RLAPI void DrawSplineSegmentBezierCubic(Vector2 p1, Vector2 c2, Vector2 c3, Vector2 p4, float thick, Color color); // Draw spline segment: Cubic Bezier, 2 points, 2 control points 1310 + 1311 + // Spline segment point evaluation functions, for a given t [0.0f .. 1.0f] 1312 + RLAPI Vector2 GetSplinePointLinear(Vector2 startPos, Vector2 endPos, float t); // Get (evaluate) spline point: Linear 1313 + RLAPI Vector2 GetSplinePointBasis(Vector2 p1, Vector2 p2, Vector2 p3, Vector2 p4, float t); // Get (evaluate) spline point: B-Spline 1314 + RLAPI Vector2 GetSplinePointCatmullRom(Vector2 p1, Vector2 p2, Vector2 p3, Vector2 p4, float t); // Get (evaluate) spline point: Catmull-Rom 1315 + RLAPI Vector2 GetSplinePointBezierQuad(Vector2 p1, Vector2 c2, Vector2 p3, float t); // Get (evaluate) spline point: Quadratic Bezier 1316 + RLAPI Vector2 GetSplinePointBezierCubic(Vector2 p1, Vector2 c2, Vector2 c3, Vector2 p4, float t); // Get (evaluate) spline point: Cubic Bezier 1317 + 1318 + // Basic shapes collision detection functions 1319 + RLAPI bool CheckCollisionRecs(Rectangle rec1, Rectangle rec2); // Check collision between two rectangles 1320 + RLAPI bool CheckCollisionCircles(Vector2 center1, float radius1, Vector2 center2, float radius2); // Check collision between two circles 1321 + RLAPI bool CheckCollisionCircleRec(Vector2 center, float radius, Rectangle rec); // Check collision between circle and rectangle 1322 + RLAPI bool CheckCollisionCircleLine(Vector2 center, float radius, Vector2 p1, Vector2 p2); // Check if circle collides with a line created betweeen two points [p1] and [p2] 1323 + RLAPI bool CheckCollisionPointRec(Vector2 point, Rectangle rec); // Check if point is inside rectangle 1324 + RLAPI bool CheckCollisionPointCircle(Vector2 point, Vector2 center, float radius); // Check if point is inside circle 1325 + RLAPI bool CheckCollisionPointTriangle(Vector2 point, Vector2 p1, Vector2 p2, Vector2 p3); // Check if point is inside a triangle 1326 + RLAPI bool CheckCollisionPointLine(Vector2 point, Vector2 p1, Vector2 p2, int threshold); // Check if point belongs to line created between two points [p1] and [p2] with defined margin in pixels [threshold] 1327 + RLAPI bool CheckCollisionPointPoly(Vector2 point, const Vector2 *points, int pointCount); // Check if point is within a polygon described by array of vertices 1328 + RLAPI bool CheckCollisionLines(Vector2 startPos1, Vector2 endPos1, Vector2 startPos2, Vector2 endPos2, Vector2 *collisionPoint); // Check the collision between two lines defined by two points each, returns collision point by reference 1329 + RLAPI Rectangle GetCollisionRec(Rectangle rec1, Rectangle rec2); // Get collision rectangle for two rectangles collision 1330 + 1331 + //------------------------------------------------------------------------------------ 1332 + // Texture Loading and Drawing Functions (Module: textures) 1333 + //------------------------------------------------------------------------------------ 1334 + 1335 + // Image loading functions 1336 + // NOTE: These functions do not require GPU access 1337 + RLAPI Image LoadImage(const char *fileName); // Load image from file into CPU memory (RAM) 1338 + RLAPI Image LoadImageRaw(const char *fileName, int width, int height, int format, int headerSize); // Load image from RAW file data 1339 + RLAPI Image LoadImageAnim(const char *fileName, int *frames); // Load image sequence from file (frames appended to image.data) 1340 + RLAPI Image LoadImageAnimFromMemory(const char *fileType, const unsigned char *fileData, int dataSize, int *frames); // Load image sequence from memory buffer 1341 + RLAPI Image LoadImageFromMemory(const char *fileType, const unsigned char *fileData, int dataSize); // Load image from memory buffer, fileType refers to extension: i.e. '.png' 1342 + RLAPI Image LoadImageFromTexture(Texture2D texture); // Load image from GPU texture data 1343 + RLAPI Image LoadImageFromScreen(void); // Load image from screen buffer and (screenshot) 1344 + RLAPI bool IsImageValid(Image image); // Check if an image is valid (data and parameters) 1345 + RLAPI void UnloadImage(Image image); // Unload image from CPU memory (RAM) 1346 + RLAPI bool ExportImage(Image image, const char *fileName); // Export image data to file, returns true on success 1347 + RLAPI unsigned char *ExportImageToMemory(Image image, const char *fileType, int *fileSize); // Export image to memory buffer 1348 + RLAPI bool ExportImageAsCode(Image image, const char *fileName); // Export image as code file defining an array of bytes, returns true on success 1349 + 1350 + // Image generation functions 1351 + RLAPI Image GenImageColor(int width, int height, Color color); // Generate image: plain color 1352 + RLAPI Image GenImageGradientLinear(int width, int height, int direction, Color start, Color end); // Generate image: linear gradient, direction in degrees [0..360], 0=Vertical gradient 1353 + RLAPI Image GenImageGradientRadial(int width, int height, float density, Color inner, Color outer); // Generate image: radial gradient 1354 + RLAPI Image GenImageGradientSquare(int width, int height, float density, Color inner, Color outer); // Generate image: square gradient 1355 + RLAPI Image GenImageChecked(int width, int height, int checksX, int checksY, Color col1, Color col2); // Generate image: checked 1356 + RLAPI Image GenImageWhiteNoise(int width, int height, float factor); // Generate image: white noise 1357 + RLAPI Image GenImagePerlinNoise(int width, int height, int offsetX, int offsetY, float scale); // Generate image: perlin noise 1358 + RLAPI Image GenImageCellular(int width, int height, int tileSize); // Generate image: cellular algorithm, bigger tileSize means bigger cells 1359 + RLAPI Image GenImageText(int width, int height, const char *text); // Generate image: grayscale image from text data 1360 + 1361 + // Image manipulation functions 1362 + RLAPI Image ImageCopy(Image image); // Create an image duplicate (useful for transformations) 1363 + RLAPI Image ImageFromImage(Image image, Rectangle rec); // Create an image from another image piece 1364 + RLAPI Image ImageFromChannel(Image image, int selectedChannel); // Create an image from a selected channel of another image (GRAYSCALE) 1365 + RLAPI Image ImageText(const char *text, int fontSize, Color color); // Create an image from text (default font) 1366 + RLAPI Image ImageTextEx(Font font, const char *text, float fontSize, float spacing, Color tint); // Create an image from text (custom sprite font) 1367 + RLAPI void ImageFormat(Image *image, int newFormat); // Convert image data to desired format 1368 + RLAPI void ImageToPOT(Image *image, Color fill); // Convert image to POT (power-of-two) 1369 + RLAPI void ImageCrop(Image *image, Rectangle crop); // Crop an image to a defined rectangle 1370 + RLAPI void ImageAlphaCrop(Image *image, float threshold); // Crop image depending on alpha value 1371 + RLAPI void ImageAlphaClear(Image *image, Color color, float threshold); // Clear alpha channel to desired color 1372 + RLAPI void ImageAlphaMask(Image *image, Image alphaMask); // Apply alpha mask to image 1373 + RLAPI void ImageAlphaPremultiply(Image *image); // Premultiply alpha channel 1374 + RLAPI void ImageBlurGaussian(Image *image, int blurSize); // Apply Gaussian blur using a box blur approximation 1375 + RLAPI void ImageKernelConvolution(Image *image, const float *kernel, int kernelSize); // Apply custom square convolution kernel to image 1376 + RLAPI void ImageResize(Image *image, int newWidth, int newHeight); // Resize image (Bicubic scaling algorithm) 1377 + RLAPI void ImageResizeNN(Image *image, int newWidth, int newHeight); // Resize image (Nearest-Neighbor scaling algorithm) 1378 + RLAPI void ImageResizeCanvas(Image *image, int newWidth, int newHeight, int offsetX, int offsetY, Color fill); // Resize canvas and fill with color 1379 + RLAPI void ImageMipmaps(Image *image); // Compute all mipmap levels for a provided image 1380 + RLAPI void ImageDither(Image *image, int rBpp, int gBpp, int bBpp, int aBpp); // Dither image data to 16bpp or lower (Floyd-Steinberg dithering) 1381 + RLAPI void ImageFlipVertical(Image *image); // Flip image vertically 1382 + RLAPI void ImageFlipHorizontal(Image *image); // Flip image horizontally 1383 + RLAPI void ImageRotate(Image *image, int degrees); // Rotate image by input angle in degrees (-359 to 359) 1384 + RLAPI void ImageRotateCW(Image *image); // Rotate image clockwise 90deg 1385 + RLAPI void ImageRotateCCW(Image *image); // Rotate image counter-clockwise 90deg 1386 + RLAPI void ImageColorTint(Image *image, Color color); // Modify image color: tint 1387 + RLAPI void ImageColorInvert(Image *image); // Modify image color: invert 1388 + RLAPI void ImageColorGrayscale(Image *image); // Modify image color: grayscale 1389 + RLAPI void ImageColorContrast(Image *image, float contrast); // Modify image color: contrast (-100 to 100) 1390 + RLAPI void ImageColorBrightness(Image *image, int brightness); // Modify image color: brightness (-255 to 255) 1391 + RLAPI void ImageColorReplace(Image *image, Color color, Color replace); // Modify image color: replace color 1392 + RLAPI Color *LoadImageColors(Image image); // Load color data from image as a Color array (RGBA - 32bit) 1393 + RLAPI Color *LoadImagePalette(Image image, int maxPaletteSize, int *colorCount); // Load colors palette from image as a Color array (RGBA - 32bit) 1394 + RLAPI void UnloadImageColors(Color *colors); // Unload color data loaded with LoadImageColors() 1395 + RLAPI void UnloadImagePalette(Color *colors); // Unload colors palette loaded with LoadImagePalette() 1396 + RLAPI Rectangle GetImageAlphaBorder(Image image, float threshold); // Get image alpha border rectangle 1397 + RLAPI Color GetImageColor(Image image, int x, int y); // Get image pixel color at (x, y) position 1398 + 1399 + // Image drawing functions 1400 + // NOTE: Image software-rendering functions (CPU) 1401 + RLAPI void ImageClearBackground(Image *dst, Color color); // Clear image background with given color 1402 + RLAPI void ImageDrawPixel(Image *dst, int posX, int posY, Color color); // Draw pixel within an image 1403 + RLAPI void ImageDrawPixelV(Image *dst, Vector2 position, Color color); // Draw pixel within an image (Vector version) 1404 + RLAPI void ImageDrawLine(Image *dst, int startPosX, int startPosY, int endPosX, int endPosY, Color color); // Draw line within an image 1405 + RLAPI void ImageDrawLineV(Image *dst, Vector2 start, Vector2 end, Color color); // Draw line within an image (Vector version) 1406 + RLAPI void ImageDrawLineEx(Image *dst, Vector2 start, Vector2 end, int thick, Color color); // Draw a line defining thickness within an image 1407 + RLAPI void ImageDrawCircle(Image *dst, int centerX, int centerY, int radius, Color color); // Draw a filled circle within an image 1408 + RLAPI void ImageDrawCircleV(Image *dst, Vector2 center, int radius, Color color); // Draw a filled circle within an image (Vector version) 1409 + RLAPI void ImageDrawCircleLines(Image *dst, int centerX, int centerY, int radius, Color color); // Draw circle outline within an image 1410 + RLAPI void ImageDrawCircleLinesV(Image *dst, Vector2 center, int radius, Color color); // Draw circle outline within an image (Vector version) 1411 + RLAPI void ImageDrawRectangle(Image *dst, int posX, int posY, int width, int height, Color color); // Draw rectangle within an image 1412 + RLAPI void ImageDrawRectangleV(Image *dst, Vector2 position, Vector2 size, Color color); // Draw rectangle within an image (Vector version) 1413 + RLAPI void ImageDrawRectangleRec(Image *dst, Rectangle rec, Color color); // Draw rectangle within an image 1414 + RLAPI void ImageDrawRectangleLines(Image *dst, Rectangle rec, int thick, Color color); // Draw rectangle lines within an image 1415 + RLAPI void ImageDrawTriangle(Image *dst, Vector2 v1, Vector2 v2, Vector2 v3, Color color); // Draw triangle within an image 1416 + RLAPI void ImageDrawTriangleEx(Image *dst, Vector2 v1, Vector2 v2, Vector2 v3, Color c1, Color c2, Color c3); // Draw triangle with interpolated colors within an image 1417 + RLAPI void ImageDrawTriangleLines(Image *dst, Vector2 v1, Vector2 v2, Vector2 v3, Color color); // Draw triangle outline within an image 1418 + RLAPI void ImageDrawTriangleFan(Image *dst, const Vector2 *points, int pointCount, Color color); // Draw a triangle fan defined by points within an image (first vertex is the center) 1419 + RLAPI void ImageDrawTriangleStrip(Image *dst, const Vector2 *points, int pointCount, Color color); // Draw a triangle strip defined by points within an image 1420 + RLAPI void ImageDraw(Image *dst, Image src, Rectangle srcRec, Rectangle dstRec, Color tint); // Draw a source image within a destination image (tint applied to source) 1421 + RLAPI void ImageDrawText(Image *dst, const char *text, int posX, int posY, int fontSize, Color color); // Draw text (using default font) within an image (destination) 1422 + RLAPI void ImageDrawTextEx(Image *dst, Font font, const char *text, Vector2 position, float fontSize, float spacing, Color tint); // Draw text (custom sprite font) within an image (destination) 1423 + 1424 + // Texture loading functions 1425 + // NOTE: These functions require GPU access 1426 + RLAPI Texture2D LoadTexture(const char *fileName); // Load texture from file into GPU memory (VRAM) 1427 + RLAPI Texture2D LoadTextureFromImage(Image image); // Load texture from image data 1428 + RLAPI TextureCubemap LoadTextureCubemap(Image image, int layout); // Load cubemap from image, multiple image cubemap layouts supported 1429 + RLAPI RenderTexture2D LoadRenderTexture(int width, int height); // Load texture for rendering (framebuffer) 1430 + RLAPI bool IsTextureValid(Texture2D texture); // Check if a texture is valid (loaded in GPU) 1431 + RLAPI void UnloadTexture(Texture2D texture); // Unload texture from GPU memory (VRAM) 1432 + RLAPI bool IsRenderTextureValid(RenderTexture2D target); // Check if a render texture is valid (loaded in GPU) 1433 + RLAPI void UnloadRenderTexture(RenderTexture2D target); // Unload render texture from GPU memory (VRAM) 1434 + RLAPI void UpdateTexture(Texture2D texture, const void *pixels); // Update GPU texture with new data (pixels should be able to fill texture) 1435 + RLAPI void UpdateTextureRec(Texture2D texture, Rectangle rec, const void *pixels); // Update GPU texture rectangle with new data (pixels and rec should fit in texture) 1436 + 1437 + // Texture configuration functions 1438 + RLAPI void GenTextureMipmaps(Texture2D *texture); // Generate GPU mipmaps for a texture 1439 + RLAPI void SetTextureFilter(Texture2D texture, int filter); // Set texture scaling filter mode 1440 + RLAPI void SetTextureWrap(Texture2D texture, int wrap); // Set texture wrapping mode 1441 + 1442 + // Texture drawing functions 1443 + RLAPI void DrawTexture(Texture2D texture, int posX, int posY, Color tint); // Draw a Texture2D 1444 + RLAPI void DrawTextureV(Texture2D texture, Vector2 position, Color tint); // Draw a Texture2D with position defined as Vector2 1445 + RLAPI void DrawTextureEx(Texture2D texture, Vector2 position, float rotation, float scale, Color tint); // Draw a Texture2D with extended parameters 1446 + RLAPI void DrawTextureRec(Texture2D texture, Rectangle source, Vector2 position, Color tint); // Draw a part of a texture defined by a rectangle 1447 + RLAPI void DrawTexturePro(Texture2D texture, Rectangle source, Rectangle dest, Vector2 origin, float rotation, Color tint); // Draw a part of a texture defined by a rectangle with 'pro' parameters 1448 + RLAPI void DrawTextureNPatch(Texture2D texture, NPatchInfo nPatchInfo, Rectangle dest, Vector2 origin, float rotation, Color tint); // Draws a texture (or part of it) that stretches or shrinks nicely 1449 + 1450 + // Color/pixel related functions 1451 + RLAPI bool ColorIsEqual(Color col1, Color col2); // Check if two colors are equal 1452 + RLAPI Color Fade(Color color, float alpha); // Get color with alpha applied, alpha goes from 0.0f to 1.0f 1453 + RLAPI int ColorToInt(Color color); // Get hexadecimal value for a Color (0xRRGGBBAA) 1454 + RLAPI Vector4 ColorNormalize(Color color); // Get Color normalized as float [0..1] 1455 + RLAPI Color ColorFromNormalized(Vector4 normalized); // Get Color from normalized values [0..1] 1456 + RLAPI Vector3 ColorToHSV(Color color); // Get HSV values for a Color, hue [0..360], saturation/value [0..1] 1457 + RLAPI Color ColorFromHSV(float hue, float saturation, float value); // Get a Color from HSV values, hue [0..360], saturation/value [0..1] 1458 + RLAPI Color ColorTint(Color color, Color tint); // Get color multiplied with another color 1459 + RLAPI Color ColorBrightness(Color color, float factor); // Get color with brightness correction, brightness factor goes from -1.0f to 1.0f 1460 + RLAPI Color ColorContrast(Color color, float contrast); // Get color with contrast correction, contrast values between -1.0f and 1.0f 1461 + RLAPI Color ColorAlpha(Color color, float alpha); // Get color with alpha applied, alpha goes from 0.0f to 1.0f 1462 + RLAPI Color ColorAlphaBlend(Color dst, Color src, Color tint); // Get src alpha-blended into dst color with tint 1463 + RLAPI Color ColorLerp(Color color1, Color color2, float factor); // Get color lerp interpolation between two colors, factor [0.0f..1.0f] 1464 + RLAPI Color GetColor(unsigned int hexValue); // Get Color structure from hexadecimal value 1465 + RLAPI Color GetPixelColor(void *srcPtr, int format); // Get Color from a source pixel pointer of certain format 1466 + RLAPI void SetPixelColor(void *dstPtr, Color color, int format); // Set color formatted into destination pixel pointer 1467 + RLAPI int GetPixelDataSize(int width, int height, int format); // Get pixel data size in bytes for certain format 1468 + 1469 + //------------------------------------------------------------------------------------ 1470 + // Font Loading and Text Drawing Functions (Module: text) 1471 + //------------------------------------------------------------------------------------ 1472 + 1473 + // Font loading/unloading functions 1474 + RLAPI Font GetFontDefault(void); // Get the default Font 1475 + RLAPI Font LoadFont(const char *fileName); // Load font from file into GPU memory (VRAM) 1476 + RLAPI Font LoadFontEx(const char *fileName, int fontSize, const int *codepoints, int codepointCount); // Load font from file with extended parameters, use NULL for codepoints and 0 for codepointCount to load the default character set, font size is provided in pixels height 1477 + RLAPI Font LoadFontFromImage(Image image, Color key, int firstChar); // Load font from Image (XNA style) 1478 + RLAPI Font LoadFontFromMemory(const char *fileType, const unsigned char *fileData, int dataSize, int fontSize, const int *codepoints, int codepointCount); // Load font from memory buffer, fileType refers to extension: i.e. '.ttf' 1479 + RLAPI bool IsFontValid(Font font); // Check if a font is valid (font data loaded, WARNING: GPU texture not checked) 1480 + RLAPI GlyphInfo *LoadFontData(const unsigned char *fileData, int dataSize, int fontSize, const int *codepoints, int codepointCount, int type, int *glyphCount); // Load font data for further use 1481 + RLAPI Image GenImageFontAtlas(const GlyphInfo *glyphs, Rectangle **glyphRecs, int glyphCount, int fontSize, int padding, int packMethod); // Generate image font atlas using chars info 1482 + RLAPI void UnloadFontData(GlyphInfo *glyphs, int glyphCount); // Unload font chars info data (RAM) 1483 + RLAPI void UnloadFont(Font font); // Unload font from GPU memory (VRAM) 1484 + RLAPI bool ExportFontAsCode(Font font, const char *fileName); // Export font as code file, returns true on success 1485 + 1486 + // Text drawing functions 1487 + RLAPI void DrawFPS(int posX, int posY); // Draw current FPS 1488 + RLAPI void DrawText(const char *text, int posX, int posY, int fontSize, Color color); // Draw text (using default font) 1489 + RLAPI void DrawTextEx(Font font, const char *text, Vector2 position, float fontSize, float spacing, Color tint); // Draw text using font and additional parameters 1490 + RLAPI void DrawTextPro(Font font, const char *text, Vector2 position, Vector2 origin, float rotation, float fontSize, float spacing, Color tint); // Draw text using Font and pro parameters (rotation) 1491 + RLAPI void DrawTextCodepoint(Font font, int codepoint, Vector2 position, float fontSize, Color tint); // Draw one character (codepoint) 1492 + RLAPI void DrawTextCodepoints(Font font, const int *codepoints, int codepointCount, Vector2 position, float fontSize, float spacing, Color tint); // Draw multiple character (codepoint) 1493 + 1494 + // Text font info functions 1495 + RLAPI void SetTextLineSpacing(int spacing); // Set vertical line spacing when drawing with line-breaks 1496 + RLAPI int MeasureText(const char *text, int fontSize); // Measure string width for default font 1497 + RLAPI Vector2 MeasureTextEx(Font font, const char *text, float fontSize, float spacing); // Measure string size for Font 1498 + RLAPI int GetGlyphIndex(Font font, int codepoint); // Get glyph index position in font for a codepoint (unicode character), fallback to '?' if not found 1499 + RLAPI GlyphInfo GetGlyphInfo(Font font, int codepoint); // Get glyph font info data for a codepoint (unicode character), fallback to '?' if not found 1500 + RLAPI Rectangle GetGlyphAtlasRec(Font font, int codepoint); // Get glyph rectangle in font atlas for a codepoint (unicode character), fallback to '?' if not found 1501 + 1502 + // Text codepoints management functions (unicode characters) 1503 + RLAPI char *LoadUTF8(const int *codepoints, int length); // Load UTF-8 text encoded from codepoints array 1504 + RLAPI void UnloadUTF8(char *text); // Unload UTF-8 text encoded from codepoints array 1505 + RLAPI int *LoadCodepoints(const char *text, int *count); // Load all codepoints from a UTF-8 text string, codepoints count returned by parameter 1506 + RLAPI void UnloadCodepoints(int *codepoints); // Unload codepoints data from memory 1507 + RLAPI int GetCodepointCount(const char *text); // Get total number of codepoints in a UTF-8 encoded string 1508 + RLAPI int GetCodepoint(const char *text, int *codepointSize); // Get next codepoint in a UTF-8 encoded string, 0x3f('?') is returned on failure 1509 + RLAPI int GetCodepointNext(const char *text, int *codepointSize); // Get next codepoint in a UTF-8 encoded string, 0x3f('?') is returned on failure 1510 + RLAPI int GetCodepointPrevious(const char *text, int *codepointSize); // Get previous codepoint in a UTF-8 encoded string, 0x3f('?') is returned on failure 1511 + RLAPI const char *CodepointToUTF8(int codepoint, int *utf8Size); // Encode one codepoint into UTF-8 byte array (array length returned as parameter) 1512 + 1513 + // Text strings management functions (no UTF-8 strings, only byte chars) 1514 + // WARNING 1: Most of these functions use internal static buffers[], it's recommended to store returned data on user-side for re-use 1515 + // WARNING 2: Some strings allocate memory internally for the returned strings, those strings must be free by user using MemFree() 1516 + RLAPI char **LoadTextLines(const char *text, int *count); // Load text as separate lines ('\n') 1517 + RLAPI void UnloadTextLines(char **text, int lineCount); // Unload text lines 1518 + RLAPI int TextCopy(char *dst, const char *src); // Copy one string to another, returns bytes copied 1519 + RLAPI bool TextIsEqual(const char *text1, const char *text2); // Check if two text string are equal 1520 + RLAPI unsigned int TextLength(const char *text); // Get text length, checks for '\0' ending 1521 + RLAPI const char *TextFormat(const char *text, ...); // Text formatting with variables (sprintf() style) 1522 + RLAPI const char *TextSubtext(const char *text, int position, int length); // Get a piece of a text string 1523 + RLAPI const char *TextRemoveSpaces(const char *text); // Remove text spaces, concat words 1524 + RLAPI char *GetTextBetween(const char *text, const char *begin, const char *end); // Get text between two strings 1525 + RLAPI char *TextReplace(const char *text, const char *search, const char *replacement); // Replace text string (WARNING: memory must be freed!) 1526 + RLAPI char *TextReplaceBetween(const char *text, const char *begin, const char *end, const char *replacement); // Replace text between two specific strings (WARNING: memory must be freed!) 1527 + RLAPI char *TextInsert(const char *text, const char *insert, int position); // Insert text in a position (WARNING: memory must be freed!) 1528 + RLAPI char *TextJoin(char **textList, int count, const char *delimiter); // Join text strings with delimiter 1529 + RLAPI char **TextSplit(const char *text, char delimiter, int *count); // Split text into multiple strings, using MAX_TEXTSPLIT_COUNT static strings 1530 + RLAPI void TextAppend(char *text, const char *append, int *position); // Append text at specific position and move cursor 1531 + RLAPI int TextFindIndex(const char *text, const char *search); // Find first text occurrence within a string, -1 if not found 1532 + RLAPI char *TextToUpper(const char *text); // Get upper case version of provided string 1533 + RLAPI char *TextToLower(const char *text); // Get lower case version of provided string 1534 + RLAPI char *TextToPascal(const char *text); // Get Pascal case notation version of provided string 1535 + RLAPI char *TextToSnake(const char *text); // Get Snake case notation version of provided string 1536 + RLAPI char *TextToCamel(const char *text); // Get Camel case notation version of provided string 1537 + RLAPI int TextToInteger(const char *text); // Get integer value from text 1538 + RLAPI float TextToFloat(const char *text); // Get float value from text 1539 + 1540 + //------------------------------------------------------------------------------------ 1541 + // Basic 3d Shapes Drawing Functions (Module: models) 1542 + //------------------------------------------------------------------------------------ 1543 + 1544 + // Basic geometric 3D shapes drawing functions 1545 + RLAPI void DrawLine3D(Vector3 startPos, Vector3 endPos, Color color); // Draw a line in 3D world space 1546 + RLAPI void DrawPoint3D(Vector3 position, Color color); // Draw a point in 3D space, actually a small line 1547 + RLAPI void DrawCircle3D(Vector3 center, float radius, Vector3 rotationAxis, float rotationAngle, Color color); // Draw a circle in 3D world space 1548 + RLAPI void DrawTriangle3D(Vector3 v1, Vector3 v2, Vector3 v3, Color color); // Draw a color-filled triangle (vertex in counter-clockwise order!) 1549 + RLAPI void DrawTriangleStrip3D(const Vector3 *points, int pointCount, Color color); // Draw a triangle strip defined by points 1550 + RLAPI void DrawCube(Vector3 position, float width, float height, float length, Color color); // Draw cube 1551 + RLAPI void DrawCubeV(Vector3 position, Vector3 size, Color color); // Draw cube (Vector version) 1552 + RLAPI void DrawCubeWires(Vector3 position, float width, float height, float length, Color color); // Draw cube wires 1553 + RLAPI void DrawCubeWiresV(Vector3 position, Vector3 size, Color color); // Draw cube wires (Vector version) 1554 + RLAPI void DrawSphere(Vector3 centerPos, float radius, Color color); // Draw sphere 1555 + RLAPI void DrawSphereEx(Vector3 centerPos, float radius, int rings, int slices, Color color); // Draw sphere with extended parameters 1556 + RLAPI void DrawSphereWires(Vector3 centerPos, float radius, int rings, int slices, Color color); // Draw sphere wires 1557 + RLAPI void DrawCylinder(Vector3 position, float radiusTop, float radiusBottom, float height, int slices, Color color); // Draw a cylinder/cone 1558 + RLAPI void DrawCylinderEx(Vector3 startPos, Vector3 endPos, float startRadius, float endRadius, int sides, Color color); // Draw a cylinder with base at startPos and top at endPos 1559 + RLAPI void DrawCylinderWires(Vector3 position, float radiusTop, float radiusBottom, float height, int slices, Color color); // Draw a cylinder/cone wires 1560 + RLAPI void DrawCylinderWiresEx(Vector3 startPos, Vector3 endPos, float startRadius, float endRadius, int sides, Color color); // Draw a cylinder wires with base at startPos and top at endPos 1561 + RLAPI void DrawCapsule(Vector3 startPos, Vector3 endPos, float radius, int slices, int rings, Color color); // Draw a capsule with the center of its sphere caps at startPos and endPos 1562 + RLAPI void DrawCapsuleWires(Vector3 startPos, Vector3 endPos, float radius, int slices, int rings, Color color); // Draw capsule wireframe with the center of its sphere caps at startPos and endPos 1563 + RLAPI void DrawPlane(Vector3 centerPos, Vector2 size, Color color); // Draw a plane XZ 1564 + RLAPI void DrawRay(Ray ray, Color color); // Draw a ray line 1565 + RLAPI void DrawGrid(int slices, float spacing); // Draw a grid (centered at (0, 0, 0)) 1566 + 1567 + //------------------------------------------------------------------------------------ 1568 + // Model 3d Loading and Drawing Functions (Module: models) 1569 + //------------------------------------------------------------------------------------ 1570 + 1571 + // Model management functions 1572 + RLAPI Model LoadModel(const char *fileName); // Load model from files (meshes and materials) 1573 + RLAPI Model LoadModelFromMesh(Mesh mesh); // Load model from generated mesh (default material) 1574 + RLAPI bool IsModelValid(Model model); // Check if a model is valid (loaded in GPU, VAO/VBOs) 1575 + RLAPI void UnloadModel(Model model); // Unload model (including meshes) from memory (RAM and/or VRAM) 1576 + RLAPI BoundingBox GetModelBoundingBox(Model model); // Compute model bounding box limits (considers all meshes) 1577 + 1578 + // Model drawing functions 1579 + RLAPI void DrawModel(Model model, Vector3 position, float scale, Color tint); // Draw a model (with texture if set) 1580 + RLAPI void DrawModelEx(Model model, Vector3 position, Vector3 rotationAxis, float rotationAngle, Vector3 scale, Color tint); // Draw a model with extended parameters 1581 + RLAPI void DrawModelWires(Model model, Vector3 position, float scale, Color tint); // Draw a model wires (with texture if set) 1582 + RLAPI void DrawModelWiresEx(Model model, Vector3 position, Vector3 rotationAxis, float rotationAngle, Vector3 scale, Color tint); // Draw a model wires (with texture if set) with extended parameters 1583 + RLAPI void DrawModelPoints(Model model, Vector3 position, float scale, Color tint); // Draw a model as points 1584 + RLAPI void DrawModelPointsEx(Model model, Vector3 position, Vector3 rotationAxis, float rotationAngle, Vector3 scale, Color tint); // Draw a model as points with extended parameters 1585 + RLAPI void DrawBoundingBox(BoundingBox box, Color color); // Draw bounding box (wires) 1586 + RLAPI void DrawBillboard(Camera camera, Texture2D texture, Vector3 position, float scale, Color tint); // Draw a billboard texture 1587 + RLAPI void DrawBillboardRec(Camera camera, Texture2D texture, Rectangle source, Vector3 position, Vector2 size, Color tint); // Draw a billboard texture defined by source 1588 + RLAPI void DrawBillboardPro(Camera camera, Texture2D texture, Rectangle source, Vector3 position, Vector3 up, Vector2 size, Vector2 origin, float rotation, Color tint); // Draw a billboard texture defined by source and rotation 1589 + 1590 + // Mesh management functions 1591 + RLAPI void UploadMesh(Mesh *mesh, bool dynamic); // Upload mesh vertex data in GPU and provide VAO/VBO ids 1592 + RLAPI void UpdateMeshBuffer(Mesh mesh, int index, const void *data, int dataSize, int offset); // Update mesh vertex data in GPU for a specific buffer index 1593 + RLAPI void UnloadMesh(Mesh mesh); // Unload mesh data from CPU and GPU 1594 + RLAPI void DrawMesh(Mesh mesh, Material material, Matrix transform); // Draw a 3d mesh with material and transform 1595 + RLAPI void DrawMeshInstanced(Mesh mesh, Material material, const Matrix *transforms, int instances); // Draw multiple mesh instances with material and different transforms 1596 + RLAPI BoundingBox GetMeshBoundingBox(Mesh mesh); // Compute mesh bounding box limits 1597 + RLAPI void GenMeshTangents(Mesh *mesh); // Compute mesh tangents 1598 + RLAPI bool ExportMesh(Mesh mesh, const char *fileName); // Export mesh data to file, returns true on success 1599 + RLAPI bool ExportMeshAsCode(Mesh mesh, const char *fileName); // Export mesh as code file (.h) defining multiple arrays of vertex attributes 1600 + 1601 + // Mesh generation functions 1602 + RLAPI Mesh GenMeshPoly(int sides, float radius); // Generate polygonal mesh 1603 + RLAPI Mesh GenMeshPlane(float width, float length, int resX, int resZ); // Generate plane mesh (with subdivisions) 1604 + RLAPI Mesh GenMeshCube(float width, float height, float length); // Generate cuboid mesh 1605 + RLAPI Mesh GenMeshSphere(float radius, int rings, int slices); // Generate sphere mesh (standard sphere) 1606 + RLAPI Mesh GenMeshHemiSphere(float radius, int rings, int slices); // Generate half-sphere mesh (no bottom cap) 1607 + RLAPI Mesh GenMeshCylinder(float radius, float height, int slices); // Generate cylinder mesh 1608 + RLAPI Mesh GenMeshCone(float radius, float height, int slices); // Generate cone/pyramid mesh 1609 + RLAPI Mesh GenMeshTorus(float radius, float size, int radSeg, int sides); // Generate torus mesh 1610 + RLAPI Mesh GenMeshKnot(float radius, float size, int radSeg, int sides); // Generate trefoil knot mesh 1611 + RLAPI Mesh GenMeshHeightmap(Image heightmap, Vector3 size); // Generate heightmap mesh from image data 1612 + RLAPI Mesh GenMeshCubicmap(Image cubicmap, Vector3 cubeSize); // Generate cubes-based map mesh from image data 1613 + 1614 + // Material loading/unloading functions 1615 + RLAPI Material *LoadMaterials(const char *fileName, int *materialCount); // Load materials from model file 1616 + RLAPI Material LoadMaterialDefault(void); // Load default material (Supports: DIFFUSE, SPECULAR, NORMAL maps) 1617 + RLAPI bool IsMaterialValid(Material material); // Check if a material is valid (shader assigned, map textures loaded in GPU) 1618 + RLAPI void UnloadMaterial(Material material); // Unload material from GPU memory (VRAM) 1619 + RLAPI void SetMaterialTexture(Material *material, int mapType, Texture2D texture); // Set texture for a material map type (MATERIAL_MAP_DIFFUSE, MATERIAL_MAP_SPECULAR...) 1620 + RLAPI void SetModelMeshMaterial(Model *model, int meshId, int materialId); // Set material for a mesh 1621 + 1622 + // Model animations loading/unloading functions 1623 + RLAPI ModelAnimation *LoadModelAnimations(const char *fileName, int *animCount); // Load model animations from file 1624 + RLAPI void UpdateModelAnimation(Model model, ModelAnimation anim, int frame); // Update model animation pose (CPU) 1625 + RLAPI void UpdateModelAnimationBones(Model model, ModelAnimation anim, int frame); // Update model animation mesh bone matrices (GPU skinning) 1626 + RLAPI void UnloadModelAnimation(ModelAnimation anim); // Unload animation data 1627 + RLAPI void UnloadModelAnimations(ModelAnimation *animations, int animCount); // Unload animation array data 1628 + RLAPI bool IsModelAnimationValid(Model model, ModelAnimation anim); // Check model animation skeleton match 1629 + 1630 + // Collision detection functions 1631 + RLAPI bool CheckCollisionSpheres(Vector3 center1, float radius1, Vector3 center2, float radius2); // Check collision between two spheres 1632 + RLAPI bool CheckCollisionBoxes(BoundingBox box1, BoundingBox box2); // Check collision between two bounding boxes 1633 + RLAPI bool CheckCollisionBoxSphere(BoundingBox box, Vector3 center, float radius); // Check collision between box and sphere 1634 + RLAPI RayCollision GetRayCollisionSphere(Ray ray, Vector3 center, float radius); // Get collision info between ray and sphere 1635 + RLAPI RayCollision GetRayCollisionBox(Ray ray, BoundingBox box); // Get collision info between ray and box 1636 + RLAPI RayCollision GetRayCollisionMesh(Ray ray, Mesh mesh, Matrix transform); // Get collision info between ray and mesh 1637 + RLAPI RayCollision GetRayCollisionTriangle(Ray ray, Vector3 p1, Vector3 p2, Vector3 p3); // Get collision info between ray and triangle 1638 + RLAPI RayCollision GetRayCollisionQuad(Ray ray, Vector3 p1, Vector3 p2, Vector3 p3, Vector3 p4); // Get collision info between ray and quad 1639 + 1640 + //------------------------------------------------------------------------------------ 1641 + // Audio Loading and Playing Functions (Module: audio) 1642 + //------------------------------------------------------------------------------------ 1643 + typedef void (*AudioCallback)(void *bufferData, unsigned int frames); 1644 + 1645 + // Audio device management functions 1646 + RLAPI void InitAudioDevice(void); // Initialize audio device and context 1647 + RLAPI void CloseAudioDevice(void); // Close the audio device and context 1648 + RLAPI bool IsAudioDeviceReady(void); // Check if audio device has been initialized successfully 1649 + RLAPI void SetMasterVolume(float volume); // Set master volume (listener) 1650 + RLAPI float GetMasterVolume(void); // Get master volume (listener) 1651 + 1652 + // Wave/Sound loading/unloading functions 1653 + RLAPI Wave LoadWave(const char *fileName); // Load wave data from file 1654 + RLAPI Wave LoadWaveFromMemory(const char *fileType, const unsigned char *fileData, int dataSize); // Load wave from memory buffer, fileType refers to extension: i.e. '.wav' 1655 + RLAPI bool IsWaveValid(Wave wave); // Checks if wave data is valid (data loaded and parameters) 1656 + RLAPI Sound LoadSound(const char *fileName); // Load sound from file 1657 + RLAPI Sound LoadSoundFromWave(Wave wave); // Load sound from wave data 1658 + RLAPI Sound LoadSoundAlias(Sound source); // Create a new sound that shares the same sample data as the source sound, does not own the sound data 1659 + RLAPI bool IsSoundValid(Sound sound); // Checks if a sound is valid (data loaded and buffers initialized) 1660 + RLAPI void UpdateSound(Sound sound, const void *data, int sampleCount); // Update sound buffer with new data (data and frame count should fit in sound) 1661 + RLAPI void UnloadWave(Wave wave); // Unload wave data 1662 + RLAPI void UnloadSound(Sound sound); // Unload sound 1663 + RLAPI void UnloadSoundAlias(Sound alias); // Unload a sound alias (does not deallocate sample data) 1664 + RLAPI bool ExportWave(Wave wave, const char *fileName); // Export wave data to file, returns true on success 1665 + RLAPI bool ExportWaveAsCode(Wave wave, const char *fileName); // Export wave sample data to code (.h), returns true on success 1666 + 1667 + // Wave/Sound management functions 1668 + RLAPI void PlaySound(Sound sound); // Play a sound 1669 + RLAPI void StopSound(Sound sound); // Stop playing a sound 1670 + RLAPI void PauseSound(Sound sound); // Pause a sound 1671 + RLAPI void ResumeSound(Sound sound); // Resume a paused sound 1672 + RLAPI bool IsSoundPlaying(Sound sound); // Check if a sound is currently playing 1673 + RLAPI void SetSoundVolume(Sound sound, float volume); // Set volume for a sound (1.0 is max level) 1674 + RLAPI void SetSoundPitch(Sound sound, float pitch); // Set pitch for a sound (1.0 is base level) 1675 + RLAPI void SetSoundPan(Sound sound, float pan); // Set pan for a sound (0.5 is center) 1676 + RLAPI Wave WaveCopy(Wave wave); // Copy a wave to a new wave 1677 + RLAPI void WaveCrop(Wave *wave, int initFrame, int finalFrame); // Crop a wave to defined frames range 1678 + RLAPI void WaveFormat(Wave *wave, int sampleRate, int sampleSize, int channels); // Convert wave data to desired format 1679 + RLAPI float *LoadWaveSamples(Wave wave); // Load samples data from wave as a 32bit float data array 1680 + RLAPI void UnloadWaveSamples(float *samples); // Unload samples data loaded with LoadWaveSamples() 1681 + 1682 + // Music management functions 1683 + RLAPI Music LoadMusicStream(const char *fileName); // Load music stream from file 1684 + RLAPI Music LoadMusicStreamFromMemory(const char *fileType, const unsigned char *data, int dataSize); // Load music stream from data 1685 + RLAPI bool IsMusicValid(Music music); // Checks if a music stream is valid (context and buffers initialized) 1686 + RLAPI void UnloadMusicStream(Music music); // Unload music stream 1687 + RLAPI void PlayMusicStream(Music music); // Start music playing 1688 + RLAPI bool IsMusicStreamPlaying(Music music); // Check if music is playing 1689 + RLAPI void UpdateMusicStream(Music music); // Updates buffers for music streaming 1690 + RLAPI void StopMusicStream(Music music); // Stop music playing 1691 + RLAPI void PauseMusicStream(Music music); // Pause music playing 1692 + RLAPI void ResumeMusicStream(Music music); // Resume playing paused music 1693 + RLAPI void SeekMusicStream(Music music, float position); // Seek music to a position (in seconds) 1694 + RLAPI void SetMusicVolume(Music music, float volume); // Set volume for music (1.0 is max level) 1695 + RLAPI void SetMusicPitch(Music music, float pitch); // Set pitch for a music (1.0 is base level) 1696 + RLAPI void SetMusicPan(Music music, float pan); // Set pan for a music (0.5 is center) 1697 + RLAPI float GetMusicTimeLength(Music music); // Get music time length (in seconds) 1698 + RLAPI float GetMusicTimePlayed(Music music); // Get current music time played (in seconds) 1699 + 1700 + // AudioStream management functions 1701 + RLAPI AudioStream LoadAudioStream(unsigned int sampleRate, unsigned int sampleSize, unsigned int channels); // Load audio stream (to stream raw audio pcm data) 1702 + RLAPI bool IsAudioStreamValid(AudioStream stream); // Checks if an audio stream is valid (buffers initialized) 1703 + RLAPI void UnloadAudioStream(AudioStream stream); // Unload audio stream and free memory 1704 + RLAPI void UpdateAudioStream(AudioStream stream, const void *data, int frameCount); // Update audio stream buffers with data 1705 + RLAPI bool IsAudioStreamProcessed(AudioStream stream); // Check if any audio stream buffers requires refill 1706 + RLAPI void PlayAudioStream(AudioStream stream); // Play audio stream 1707 + RLAPI void PauseAudioStream(AudioStream stream); // Pause audio stream 1708 + RLAPI void ResumeAudioStream(AudioStream stream); // Resume audio stream 1709 + RLAPI bool IsAudioStreamPlaying(AudioStream stream); // Check if audio stream is playing 1710 + RLAPI void StopAudioStream(AudioStream stream); // Stop audio stream 1711 + RLAPI void SetAudioStreamVolume(AudioStream stream, float volume); // Set volume for audio stream (1.0 is max level) 1712 + RLAPI void SetAudioStreamPitch(AudioStream stream, float pitch); // Set pitch for audio stream (1.0 is base level) 1713 + RLAPI void SetAudioStreamPan(AudioStream stream, float pan); // Set pan for audio stream (0.5 is centered) 1714 + RLAPI void SetAudioStreamBufferSizeDefault(int size); // Default size for new audio streams 1715 + RLAPI void SetAudioStreamCallback(AudioStream stream, AudioCallback callback); // Audio thread callback to request new data 1716 + 1717 + RLAPI void AttachAudioStreamProcessor(AudioStream stream, AudioCallback processor); // Attach audio stream processor to stream, receives frames x 2 samples as 'float' (stereo) 1718 + RLAPI void DetachAudioStreamProcessor(AudioStream stream, AudioCallback processor); // Detach audio stream processor from stream 1719 + 1720 + RLAPI void AttachAudioMixedProcessor(AudioCallback processor); // Attach audio stream processor to the entire audio pipeline, receives frames x 2 samples as 'float' (stereo) 1721 + RLAPI void DetachAudioMixedProcessor(AudioCallback processor); // Detach audio stream processor from the entire audio pipeline 1722 + 1723 + #if defined(__cplusplus) 1724 + } 1725 + #endif 1726 + 1727 + #endif // RAYLIB_H
+2900
include/raymath.h
··· 1 + /********************************************************************************************** 2 + * 3 + * raymath v2.0 - Math functions to work with Vector2, Vector3, Matrix and 4 + * Quaternions 5 + * 6 + * CONVENTIONS: 7 + * - Matrix structure is defined as row-major (memory layout) but parameters 8 + * naming AND all math operations performed by the library consider the 9 + * structure as it was column-major It is like transposed versions of the 10 + * matrices are used for all the maths It benefits some functions making them 11 + * cache-friendly and also avoids matrix transpositions sometimes required by 12 + * OpenGL Example: In memory order, row0 is [m0 m4 m8 m12] but in semantic math 13 + * row0 is [m0 m1 m2 m3] 14 + * - Functions are always self-contained, no function use another raymath 15 + * function inside, required code is directly re-implemented inside 16 + * - Functions input parameters are always received by value (2 unavoidable 17 + * exceptions) 18 + * - Functions use always a "result" variable for return (except C++ 19 + * operators) 20 + * - Functions are always defined inline 21 + * - Angles are always in radians (DEG2RAD/RAD2DEG macros provided for 22 + * convenience) 23 + * - No compound literals used to make sure libray is compatible with C++ 24 + * 25 + * CONFIGURATION: 26 + * #define RAYMATH_IMPLEMENTATION 27 + * Generates the implementation of the library into the included file. 28 + * If not defined, the library is in header only mode and can be 29 + * included in other headers or source files without problems. But only ONE file 30 + * should hold the implementation. 31 + * 32 + * #define RAYMATH_STATIC_INLINE 33 + * Define static inline functions code, so #include header suffices 34 + * for use. This may use up lots of memory. 35 + * 36 + * #define RAYMATH_DISABLE_CPP_OPERATORS 37 + * Disables C++ operator overloads for raymath types. 38 + * 39 + * LICENSE: zlib/libpng 40 + * 41 + * Copyright (c) 2015-2025 Ramon Santamaria (@raysan5) 42 + * 43 + * This software is provided "as-is", without any express or implied warranty. 44 + * In no event will the authors be held liable for any damages arising from the 45 + * use of this software. 46 + * 47 + * Permission is granted to anyone to use this software for any purpose, 48 + * including commercial applications, and to alter it and redistribute it 49 + * freely, subject to the following restrictions: 50 + * 51 + * 1. The origin of this software must not be misrepresented; you must not 52 + * claim that you wrote the original software. If you use this software in a 53 + * product, an acknowledgment in the product documentation would be appreciated 54 + * but is not required. 55 + * 56 + * 2. Altered source versions must be plainly marked as such, and must not 57 + * be misrepresented as being the original software. 58 + * 59 + * 3. This notice may not be removed or altered from any source 60 + * distribution. 61 + * 62 + **********************************************************************************************/ 63 + 64 + #ifndef RAYMATH_H 65 + #define RAYMATH_H 66 + 67 + #if defined(RAYMATH_IMPLEMENTATION) && defined(RAYMATH_STATIC_INLINE) 68 + #error \ 69 + "Specifying both RAYMATH_IMPLEMENTATION and RAYMATH_STATIC_INLINE is contradictory" 70 + #endif 71 + 72 + // Function specifiers definition 73 + #if defined(RAYMATH_IMPLEMENTATION) 74 + #if defined(_WIN32) && defined(BUILD_LIBTYPE_SHARED) 75 + #define RMAPI \ 76 + __declspec(dllexport) extern inline // We are building raylib as a Win32 77 + // shared library (.dll) 78 + #elif defined(BUILD_LIBTYPE_SHARED) 79 + #define RMAPI \ 80 + __attribute__((visibility("default"))) // We are building raylib as a Unix 81 + // shared library (.so/.dylib) 82 + #elif defined(_WIN32) && defined(USE_LIBTYPE_SHARED) 83 + #define RMAPI \ 84 + __declspec(dllimport) // We are using raylib as a Win32 shared library (.dll) 85 + #else 86 + #define RMAPI extern inline // Provide external definition 87 + #endif 88 + #elif defined(RAYMATH_STATIC_INLINE) 89 + #define RMAPI \ 90 + static inline // Functions may be inlined, no external out-of-line definition 91 + #else 92 + #if defined(__TINYC__) 93 + #define RMAPI \ 94 + static inline // plain inline not supported by tinycc (See issue #435) 95 + #else 96 + #define RMAPI inline // Functions may be inlined or external definition used 97 + #endif 98 + #endif 99 + 100 + //---------------------------------------------------------------------------------- 101 + // Defines and Macros 102 + //---------------------------------------------------------------------------------- 103 + #ifndef PI 104 + #define PI 3.14159265358979323846f 105 + #endif 106 + 107 + #ifndef EPSILON 108 + #define EPSILON 0.000001f 109 + #endif 110 + 111 + #ifndef DEG2RAD 112 + #define DEG2RAD (PI / 180.0f) 113 + #endif 114 + 115 + #ifndef RAD2DEG 116 + #define RAD2DEG (180.0f / PI) 117 + #endif 118 + 119 + // Get float vector for Matrix 120 + #ifndef MatrixToFloat 121 + #define MatrixToFloat(mat) (MatrixToFloatV(mat).v) 122 + #endif 123 + 124 + // Get float vector for Vector3 125 + #ifndef Vector3ToFloat 126 + #define Vector3ToFloat(vec) (Vector3ToFloatV(vec).v) 127 + #endif 128 + 129 + //---------------------------------------------------------------------------------- 130 + // Types and Structures Definition 131 + //---------------------------------------------------------------------------------- 132 + #if !defined(RL_VECTOR2_TYPE) 133 + // Vector2 type 134 + typedef struct Vector2 { 135 + float x; 136 + float y; 137 + } Vector2; 138 + #define RL_VECTOR2_TYPE 139 + #endif 140 + 141 + #if !defined(RL_VECTOR3_TYPE) 142 + // Vector3 type 143 + typedef struct Vector3 { 144 + float x; 145 + float y; 146 + float z; 147 + } Vector3; 148 + #define RL_VECTOR3_TYPE 149 + #endif 150 + 151 + #if !defined(RL_VECTOR4_TYPE) 152 + // Vector4 type 153 + typedef struct Vector4 { 154 + float x; 155 + float y; 156 + float z; 157 + float w; 158 + } Vector4; 159 + #define RL_VECTOR4_TYPE 160 + #endif 161 + 162 + #if !defined(RL_QUATERNION_TYPE) 163 + // Quaternion type 164 + typedef Vector4 Quaternion; 165 + #define RL_QUATERNION_TYPE 166 + #endif 167 + 168 + #if !defined(RL_MATRIX_TYPE) 169 + // Matrix type (OpenGL style 4x4 - right handed, column major) 170 + typedef struct Matrix { 171 + float m0, m4, m8, m12; // Matrix first row (4 components) 172 + float m1, m5, m9, m13; // Matrix second row (4 components) 173 + float m2, m6, m10, m14; // Matrix third row (4 components) 174 + float m3, m7, m11, m15; // Matrix fourth row (4 components) 175 + } Matrix; 176 + #define RL_MATRIX_TYPE 177 + #endif 178 + 179 + // NOTE: Helper types to be used instead of array return types for *ToFloat 180 + // functions 181 + typedef struct float3 { 182 + float v[3]; 183 + } float3; 184 + 185 + typedef struct float16 { 186 + float v[16]; 187 + } float16; 188 + 189 + #include <math.h> // Required for: sinf(), cosf(), tan(), atan2f(), sqrtf(), floor(), fminf(), fmaxf(), fabsf() 190 + 191 + //---------------------------------------------------------------------------------- 192 + // Module Functions Definition - Utils math 193 + //---------------------------------------------------------------------------------- 194 + 195 + // Clamp float value 196 + RMAPI float Clamp(float value, float min, float max) { 197 + float result = (value < min) ? min : value; 198 + 199 + if (result > max) 200 + result = max; 201 + 202 + return result; 203 + } 204 + 205 + // Calculate linear interpolation between two floats 206 + RMAPI float Lerp(float start, float end, float amount) { 207 + float result = start + amount * (end - start); 208 + 209 + return result; 210 + } 211 + 212 + // Normalize input value within input range 213 + RMAPI float Normalize(float value, float start, float end) { 214 + float result = (value - start) / (end - start); 215 + 216 + return result; 217 + } 218 + 219 + // Remap input value within input range to output range 220 + RMAPI float Remap(float value, float inputStart, float inputEnd, 221 + float outputStart, float outputEnd) { 222 + float result = (value - inputStart) / (inputEnd - inputStart) * 223 + (outputEnd - outputStart) + 224 + outputStart; 225 + 226 + return result; 227 + } 228 + 229 + // Wrap input value from min to max 230 + RMAPI float Wrap(float value, float min, float max) { 231 + float result = value - (max - min) * floorf((value - min) / (max - min)); 232 + 233 + return result; 234 + } 235 + 236 + // Check whether two given floats are almost equal 237 + RMAPI int FloatEquals(float x, float y) { 238 + #if !defined(EPSILON) 239 + #define EPSILON 0.000001f 240 + #endif 241 + 242 + int result = 243 + (fabsf(x - y)) <= (EPSILON * fmaxf(1.0f, fmaxf(fabsf(x), fabsf(y)))); 244 + 245 + return result; 246 + } 247 + 248 + //---------------------------------------------------------------------------------- 249 + // Module Functions Definition - Vector2 math 250 + //---------------------------------------------------------------------------------- 251 + 252 + // Vector with components value 0.0f 253 + RMAPI Vector2 Vector2Zero(void) { 254 + Vector2 result = {0.0f, 0.0f}; 255 + 256 + return result; 257 + } 258 + 259 + // Vector with components value 1.0f 260 + RMAPI Vector2 Vector2One(void) { 261 + Vector2 result = {1.0f, 1.0f}; 262 + 263 + return result; 264 + } 265 + 266 + // Add two vectors (v1 + v2) 267 + RMAPI Vector2 Vector2Add(Vector2 v1, Vector2 v2) { 268 + Vector2 result = {v1.x + v2.x, v1.y + v2.y}; 269 + 270 + return result; 271 + } 272 + 273 + // Add vector and float value 274 + RMAPI Vector2 Vector2AddValue(Vector2 v, float add) { 275 + Vector2 result = {v.x + add, v.y + add}; 276 + 277 + return result; 278 + } 279 + 280 + // Subtract two vectors (v1 - v2) 281 + RMAPI Vector2 Vector2Subtract(Vector2 v1, Vector2 v2) { 282 + Vector2 result = {v1.x - v2.x, v1.y - v2.y}; 283 + 284 + return result; 285 + } 286 + 287 + // Subtract vector by float value 288 + RMAPI Vector2 Vector2SubtractValue(Vector2 v, float sub) { 289 + Vector2 result = {v.x - sub, v.y - sub}; 290 + 291 + return result; 292 + } 293 + 294 + // Calculate vector length 295 + RMAPI float Vector2Length(Vector2 v) { 296 + float result = sqrtf((v.x * v.x) + (v.y * v.y)); 297 + 298 + return result; 299 + } 300 + 301 + // Calculate vector square length 302 + RMAPI float Vector2LengthSqr(Vector2 v) { 303 + float result = (v.x * v.x) + (v.y * v.y); 304 + 305 + return result; 306 + } 307 + 308 + // Calculate two vectors dot product 309 + RMAPI float Vector2DotProduct(Vector2 v1, Vector2 v2) { 310 + float result = (v1.x * v2.x + v1.y * v2.y); 311 + 312 + return result; 313 + } 314 + 315 + // Calculate two vectors cross product 316 + RMAPI float Vector2CrossProduct(Vector2 v1, Vector2 v2) { 317 + float result = (v1.x * v2.y - v1.y * v2.x); 318 + 319 + return result; 320 + } 321 + 322 + // Calculate distance between two vectors 323 + RMAPI float Vector2Distance(Vector2 v1, Vector2 v2) { 324 + float result = 325 + sqrtf((v1.x - v2.x) * (v1.x - v2.x) + (v1.y - v2.y) * (v1.y - v2.y)); 326 + 327 + return result; 328 + } 329 + 330 + // Calculate square distance between two vectors 331 + RMAPI float Vector2DistanceSqr(Vector2 v1, Vector2 v2) { 332 + float result = 333 + ((v1.x - v2.x) * (v1.x - v2.x) + (v1.y - v2.y) * (v1.y - v2.y)); 334 + 335 + return result; 336 + } 337 + 338 + // Calculate the signed angle from v1 to v2, relative to the origin (0, 0) 339 + // NOTE: Coordinate system convention: positive X right, positive Y down 340 + // positive angles appear clockwise, and negative angles appear counterclockwise 341 + RMAPI float Vector2Angle(Vector2 v1, Vector2 v2) { 342 + float result = 0.0f; 343 + 344 + float dot = v1.x * v2.x + v1.y * v2.y; 345 + float det = v1.x * v2.y - v1.y * v2.x; 346 + 347 + result = atan2f(det, dot); 348 + 349 + return result; 350 + } 351 + 352 + // Calculate angle defined by a two vectors line 353 + // NOTE: Parameters need to be normalized 354 + // Current implementation should be aligned with glm::angle 355 + RMAPI float Vector2LineAngle(Vector2 start, Vector2 end) { 356 + float result = 0.0f; 357 + 358 + // TODO(10/9/2023): Currently angles move clockwise, determine if this is 359 + // wanted behavior 360 + result = -atan2f(end.y - start.y, end.x - start.x); 361 + 362 + return result; 363 + } 364 + 365 + // Scale vector (multiply by value) 366 + RMAPI Vector2 Vector2Scale(Vector2 v, float scale) { 367 + Vector2 result = {v.x * scale, v.y * scale}; 368 + 369 + return result; 370 + } 371 + 372 + // Multiply vector by vector 373 + RMAPI Vector2 Vector2Multiply(Vector2 v1, Vector2 v2) { 374 + Vector2 result = {v1.x * v2.x, v1.y * v2.y}; 375 + 376 + return result; 377 + } 378 + 379 + // Negate vector 380 + RMAPI Vector2 Vector2Negate(Vector2 v) { 381 + Vector2 result = {-v.x, -v.y}; 382 + 383 + return result; 384 + } 385 + 386 + // Divide vector by vector 387 + RMAPI Vector2 Vector2Divide(Vector2 v1, Vector2 v2) { 388 + Vector2 result = {v1.x / v2.x, v1.y / v2.y}; 389 + 390 + return result; 391 + } 392 + 393 + // Normalize provided vector 394 + RMAPI Vector2 Vector2Normalize(Vector2 v) { 395 + Vector2 result = {0}; 396 + float length = sqrtf((v.x * v.x) + (v.y * v.y)); 397 + 398 + if (length > 0) { 399 + float ilength = 1.0f / length; 400 + result.x = v.x * ilength; 401 + result.y = v.y * ilength; 402 + } 403 + 404 + return result; 405 + } 406 + 407 + // Transforms a Vector2 by a given Matrix 408 + RMAPI Vector2 Vector2Transform(Vector2 v, Matrix mat) { 409 + Vector2 result = {0}; 410 + 411 + float x = v.x; 412 + float y = v.y; 413 + float z = 0; 414 + 415 + result.x = mat.m0 * x + mat.m4 * y + mat.m8 * z + mat.m12; 416 + result.y = mat.m1 * x + mat.m5 * y + mat.m9 * z + mat.m13; 417 + 418 + return result; 419 + } 420 + 421 + // Calculate linear interpolation between two vectors 422 + RMAPI Vector2 Vector2Lerp(Vector2 v1, Vector2 v2, float amount) { 423 + Vector2 result = {0}; 424 + 425 + result.x = v1.x + amount * (v2.x - v1.x); 426 + result.y = v1.y + amount * (v2.y - v1.y); 427 + 428 + return result; 429 + } 430 + 431 + // Calculate reflected vector to normal 432 + RMAPI Vector2 Vector2Reflect(Vector2 v, Vector2 normal) { 433 + Vector2 result = {0}; 434 + 435 + float dotProduct = (v.x * normal.x + v.y * normal.y); // Dot product 436 + 437 + result.x = v.x - (2.0f * normal.x) * dotProduct; 438 + result.y = v.y - (2.0f * normal.y) * dotProduct; 439 + 440 + return result; 441 + } 442 + 443 + // Get min value for each pair of components 444 + RMAPI Vector2 Vector2Min(Vector2 v1, Vector2 v2) { 445 + Vector2 result = {0}; 446 + 447 + result.x = fminf(v1.x, v2.x); 448 + result.y = fminf(v1.y, v2.y); 449 + 450 + return result; 451 + } 452 + 453 + // Get max value for each pair of components 454 + RMAPI Vector2 Vector2Max(Vector2 v1, Vector2 v2) { 455 + Vector2 result = {0}; 456 + 457 + result.x = fmaxf(v1.x, v2.x); 458 + result.y = fmaxf(v1.y, v2.y); 459 + 460 + return result; 461 + } 462 + 463 + // Rotate vector by angle 464 + RMAPI Vector2 Vector2Rotate(Vector2 v, float angle) { 465 + Vector2 result = {0}; 466 + 467 + float cosres = cosf(angle); 468 + float sinres = sinf(angle); 469 + 470 + result.x = v.x * cosres - v.y * sinres; 471 + result.y = v.x * sinres + v.y * cosres; 472 + 473 + return result; 474 + } 475 + 476 + // Move Vector towards target 477 + RMAPI Vector2 Vector2MoveTowards(Vector2 v, Vector2 target, float maxDistance) { 478 + Vector2 result = {0}; 479 + 480 + float dx = target.x - v.x; 481 + float dy = target.y - v.y; 482 + float value = (dx * dx) + (dy * dy); 483 + 484 + if ((value == 0) || 485 + ((maxDistance >= 0) && (value <= maxDistance * maxDistance))) 486 + return target; 487 + 488 + float dist = sqrtf(value); 489 + 490 + result.x = v.x + dx / dist * maxDistance; 491 + result.y = v.y + dy / dist * maxDistance; 492 + 493 + return result; 494 + } 495 + 496 + // Invert the given vector 497 + RMAPI Vector2 Vector2Invert(Vector2 v) { 498 + Vector2 result = {1.0f / v.x, 1.0f / v.y}; 499 + 500 + return result; 501 + } 502 + 503 + // Clamp the components of the vector between 504 + // min and max values specified by the given vectors 505 + RMAPI Vector2 Vector2Clamp(Vector2 v, Vector2 min, Vector2 max) { 506 + Vector2 result = {0}; 507 + 508 + result.x = fminf(max.x, fmaxf(min.x, v.x)); 509 + result.y = fminf(max.y, fmaxf(min.y, v.y)); 510 + 511 + return result; 512 + } 513 + 514 + // Clamp the magnitude of the vector between two min and max values 515 + RMAPI Vector2 Vector2ClampValue(Vector2 v, float min, float max) { 516 + Vector2 result = v; 517 + 518 + float length = (v.x * v.x) + (v.y * v.y); 519 + if (length > 0.0f) { 520 + length = sqrtf(length); 521 + 522 + float scale = 1; // By default, 1 as the neutral element. 523 + if (length < min) { 524 + scale = min / length; 525 + } else if (length > max) { 526 + scale = max / length; 527 + } 528 + 529 + result.x = v.x * scale; 530 + result.y = v.y * scale; 531 + } 532 + 533 + return result; 534 + } 535 + 536 + // Check whether two given vectors are almost equal 537 + RMAPI int Vector2Equals(Vector2 p, Vector2 q) { 538 + #if !defined(EPSILON) 539 + #define EPSILON 0.000001f 540 + #endif 541 + 542 + int result = ((fabsf(p.x - q.x)) <= 543 + (EPSILON * fmaxf(1.0f, fmaxf(fabsf(p.x), fabsf(q.x))))) && 544 + ((fabsf(p.y - q.y)) <= 545 + (EPSILON * fmaxf(1.0f, fmaxf(fabsf(p.y), fabsf(q.y))))); 546 + 547 + return result; 548 + } 549 + 550 + // Compute the direction of a refracted ray 551 + // v: normalized direction of the incoming ray 552 + // n: normalized normal vector of the interface of two optical media 553 + // r: ratio of the refractive index of the medium from where the ray comes 554 + // to the refractive index of the medium on the other side of the surface 555 + RMAPI Vector2 Vector2Refract(Vector2 v, Vector2 n, float r) { 556 + Vector2 result = {0}; 557 + 558 + float dot = v.x * n.x + v.y * n.y; 559 + float d = 1.0f - r * r * (1.0f - dot * dot); 560 + 561 + if (d >= 0.0f) { 562 + d = sqrtf(d); 563 + v.x = r * v.x - (r * dot + d) * n.x; 564 + v.y = r * v.y - (r * dot + d) * n.y; 565 + 566 + result = v; 567 + } 568 + 569 + return result; 570 + } 571 + 572 + //---------------------------------------------------------------------------------- 573 + // Module Functions Definition - Vector3 math 574 + //---------------------------------------------------------------------------------- 575 + 576 + // Vector with components value 0.0f 577 + RMAPI Vector3 Vector3Zero(void) { 578 + Vector3 result = {0.0f, 0.0f, 0.0f}; 579 + 580 + return result; 581 + } 582 + 583 + // Vector with components value 1.0f 584 + RMAPI Vector3 Vector3One(void) { 585 + Vector3 result = {1.0f, 1.0f, 1.0f}; 586 + 587 + return result; 588 + } 589 + 590 + // Add two vectors 591 + RMAPI Vector3 Vector3Add(Vector3 v1, Vector3 v2) { 592 + Vector3 result = {v1.x + v2.x, v1.y + v2.y, v1.z + v2.z}; 593 + 594 + return result; 595 + } 596 + 597 + // Add vector and float value 598 + RMAPI Vector3 Vector3AddValue(Vector3 v, float add) { 599 + Vector3 result = {v.x + add, v.y + add, v.z + add}; 600 + 601 + return result; 602 + } 603 + 604 + // Subtract two vectors 605 + RMAPI Vector3 Vector3Subtract(Vector3 v1, Vector3 v2) { 606 + Vector3 result = {v1.x - v2.x, v1.y - v2.y, v1.z - v2.z}; 607 + 608 + return result; 609 + } 610 + 611 + // Subtract vector by float value 612 + RMAPI Vector3 Vector3SubtractValue(Vector3 v, float sub) { 613 + Vector3 result = {v.x - sub, v.y - sub, v.z - sub}; 614 + 615 + return result; 616 + } 617 + 618 + // Multiply vector by scalar 619 + RMAPI Vector3 Vector3Scale(Vector3 v, float scalar) { 620 + Vector3 result = {v.x * scalar, v.y * scalar, v.z * scalar}; 621 + 622 + return result; 623 + } 624 + 625 + // Multiply vector by vector 626 + RMAPI Vector3 Vector3Multiply(Vector3 v1, Vector3 v2) { 627 + Vector3 result = {v1.x * v2.x, v1.y * v2.y, v1.z * v2.z}; 628 + 629 + return result; 630 + } 631 + 632 + // Calculate two vectors cross product 633 + RMAPI Vector3 Vector3CrossProduct(Vector3 v1, Vector3 v2) { 634 + Vector3 result = {v1.y * v2.z - v1.z * v2.y, v1.z * v2.x - v1.x * v2.z, 635 + v1.x * v2.y - v1.y * v2.x}; 636 + 637 + return result; 638 + } 639 + 640 + // Calculate one vector perpendicular vector 641 + RMAPI Vector3 Vector3Perpendicular(Vector3 v) { 642 + Vector3 result = {0}; 643 + 644 + float min = fabsf(v.x); 645 + Vector3 cardinalAxis = {1.0f, 0.0f, 0.0f}; 646 + 647 + if (fabsf(v.y) < min) { 648 + min = fabsf(v.y); 649 + Vector3 tmp = {0.0f, 1.0f, 0.0f}; 650 + cardinalAxis = tmp; 651 + } 652 + 653 + if (fabsf(v.z) < min) { 654 + Vector3 tmp = {0.0f, 0.0f, 1.0f}; 655 + cardinalAxis = tmp; 656 + } 657 + 658 + // Cross product between vectors 659 + result.x = v.y * cardinalAxis.z - v.z * cardinalAxis.y; 660 + result.y = v.z * cardinalAxis.x - v.x * cardinalAxis.z; 661 + result.z = v.x * cardinalAxis.y - v.y * cardinalAxis.x; 662 + 663 + return result; 664 + } 665 + 666 + // Calculate vector length 667 + RMAPI float Vector3Length(const Vector3 v) { 668 + float result = sqrtf(v.x * v.x + v.y * v.y + v.z * v.z); 669 + 670 + return result; 671 + } 672 + 673 + // Calculate vector square length 674 + RMAPI float Vector3LengthSqr(const Vector3 v) { 675 + float result = v.x * v.x + v.y * v.y + v.z * v.z; 676 + 677 + return result; 678 + } 679 + 680 + // Calculate two vectors dot product 681 + RMAPI float Vector3DotProduct(Vector3 v1, Vector3 v2) { 682 + float result = (v1.x * v2.x + v1.y * v2.y + v1.z * v2.z); 683 + 684 + return result; 685 + } 686 + 687 + // Calculate distance between two vectors 688 + RMAPI float Vector3Distance(Vector3 v1, Vector3 v2) { 689 + float result = 0.0f; 690 + 691 + float dx = v2.x - v1.x; 692 + float dy = v2.y - v1.y; 693 + float dz = v2.z - v1.z; 694 + result = sqrtf(dx * dx + dy * dy + dz * dz); 695 + 696 + return result; 697 + } 698 + 699 + // Calculate square distance between two vectors 700 + RMAPI float Vector3DistanceSqr(Vector3 v1, Vector3 v2) { 701 + float result = 0.0f; 702 + 703 + float dx = v2.x - v1.x; 704 + float dy = v2.y - v1.y; 705 + float dz = v2.z - v1.z; 706 + result = dx * dx + dy * dy + dz * dz; 707 + 708 + return result; 709 + } 710 + 711 + // Calculate angle between two vectors 712 + RMAPI float Vector3Angle(Vector3 v1, Vector3 v2) { 713 + float result = 0.0f; 714 + 715 + Vector3 cross = {v1.y * v2.z - v1.z * v2.y, v1.z * v2.x - v1.x * v2.z, 716 + v1.x * v2.y - v1.y * v2.x}; 717 + float len = sqrtf(cross.x * cross.x + cross.y * cross.y + cross.z * cross.z); 718 + float dot = (v1.x * v2.x + v1.y * v2.y + v1.z * v2.z); 719 + result = atan2f(len, dot); 720 + 721 + return result; 722 + } 723 + 724 + // Negate provided vector (invert direction) 725 + RMAPI Vector3 Vector3Negate(Vector3 v) { 726 + Vector3 result = {-v.x, -v.y, -v.z}; 727 + 728 + return result; 729 + } 730 + 731 + // Divide vector by vector 732 + RMAPI Vector3 Vector3Divide(Vector3 v1, Vector3 v2) { 733 + Vector3 result = {v1.x / v2.x, v1.y / v2.y, v1.z / v2.z}; 734 + 735 + return result; 736 + } 737 + 738 + // Normalize provided vector 739 + RMAPI Vector3 Vector3Normalize(Vector3 v) { 740 + Vector3 result = v; 741 + 742 + float length = sqrtf(v.x * v.x + v.y * v.y + v.z * v.z); 743 + if (length != 0.0f) { 744 + float ilength = 1.0f / length; 745 + 746 + result.x *= ilength; 747 + result.y *= ilength; 748 + result.z *= ilength; 749 + } 750 + 751 + return result; 752 + } 753 + 754 + // Calculate the projection of the vector v1 on to v2 755 + RMAPI Vector3 Vector3Project(Vector3 v1, Vector3 v2) { 756 + Vector3 result = {0}; 757 + 758 + float v1dv2 = (v1.x * v2.x + v1.y * v2.y + v1.z * v2.z); 759 + float v2dv2 = (v2.x * v2.x + v2.y * v2.y + v2.z * v2.z); 760 + 761 + float mag = v1dv2 / v2dv2; 762 + 763 + result.x = v2.x * mag; 764 + result.y = v2.y * mag; 765 + result.z = v2.z * mag; 766 + 767 + return result; 768 + } 769 + 770 + // Calculate the rejection of the vector v1 on to v2 771 + RMAPI Vector3 Vector3Reject(Vector3 v1, Vector3 v2) { 772 + Vector3 result = {0}; 773 + 774 + float v1dv2 = (v1.x * v2.x + v1.y * v2.y + v1.z * v2.z); 775 + float v2dv2 = (v2.x * v2.x + v2.y * v2.y + v2.z * v2.z); 776 + 777 + float mag = v1dv2 / v2dv2; 778 + 779 + result.x = v1.x - (v2.x * mag); 780 + result.y = v1.y - (v2.y * mag); 781 + result.z = v1.z - (v2.z * mag); 782 + 783 + return result; 784 + } 785 + 786 + // Orthonormalize provided vectors 787 + // Makes vectors normalized and orthogonal to each other 788 + // Gram-Schmidt function implementation 789 + RMAPI void Vector3OrthoNormalize(Vector3 *v1, Vector3 *v2) { 790 + float length = 0.0f; 791 + float ilength = 0.0f; 792 + 793 + // Vector3Normalize(*v1); 794 + Vector3 v = *v1; 795 + length = sqrtf(v.x * v.x + v.y * v.y + v.z * v.z); 796 + if (length == 0.0f) 797 + length = 1.0f; 798 + ilength = 1.0f / length; 799 + v1->x *= ilength; 800 + v1->y *= ilength; 801 + v1->z *= ilength; 802 + 803 + // Vector3CrossProduct(*v1, *v2) 804 + Vector3 vn1 = {v1->y * v2->z - v1->z * v2->y, v1->z * v2->x - v1->x * v2->z, 805 + v1->x * v2->y - v1->y * v2->x}; 806 + 807 + // Vector3Normalize(vn1); 808 + v = vn1; 809 + length = sqrtf(v.x * v.x + v.y * v.y + v.z * v.z); 810 + if (length == 0.0f) 811 + length = 1.0f; 812 + ilength = 1.0f / length; 813 + vn1.x *= ilength; 814 + vn1.y *= ilength; 815 + vn1.z *= ilength; 816 + 817 + // Vector3CrossProduct(vn1, *v1) 818 + Vector3 vn2 = {vn1.y * v1->z - vn1.z * v1->y, vn1.z * v1->x - vn1.x * v1->z, 819 + vn1.x * v1->y - vn1.y * v1->x}; 820 + 821 + *v2 = vn2; 822 + } 823 + 824 + // Transforms a Vector3 by a given Matrix 825 + RMAPI Vector3 Vector3Transform(Vector3 v, Matrix mat) { 826 + Vector3 result = {0}; 827 + 828 + float x = v.x; 829 + float y = v.y; 830 + float z = v.z; 831 + 832 + result.x = mat.m0 * x + mat.m4 * y + mat.m8 * z + mat.m12; 833 + result.y = mat.m1 * x + mat.m5 * y + mat.m9 * z + mat.m13; 834 + result.z = mat.m2 * x + mat.m6 * y + mat.m10 * z + mat.m14; 835 + 836 + return result; 837 + } 838 + 839 + // Transform a vector by quaternion rotation 840 + RMAPI Vector3 Vector3RotateByQuaternion(Vector3 v, Quaternion q) { 841 + Vector3 result = {0}; 842 + 843 + result.x = v.x * (q.x * q.x + q.w * q.w - q.y * q.y - q.z * q.z) + 844 + v.y * (2 * q.x * q.y - 2 * q.w * q.z) + 845 + v.z * (2 * q.x * q.z + 2 * q.w * q.y); 846 + result.y = v.x * (2 * q.w * q.z + 2 * q.x * q.y) + 847 + v.y * (q.w * q.w - q.x * q.x + q.y * q.y - q.z * q.z) + 848 + v.z * (-2 * q.w * q.x + 2 * q.y * q.z); 849 + result.z = v.x * (-2 * q.w * q.y + 2 * q.x * q.z) + 850 + v.y * (2 * q.w * q.x + 2 * q.y * q.z) + 851 + v.z * (q.w * q.w - q.x * q.x - q.y * q.y + q.z * q.z); 852 + 853 + return result; 854 + } 855 + 856 + // Rotates a vector around an axis 857 + RMAPI Vector3 Vector3RotateByAxisAngle(Vector3 v, Vector3 axis, float angle) { 858 + // Using Euler-Rodrigues Formula 859 + // Ref.: 860 + // https://en.wikipedia.org/w/index.php?title=Euler%E2%80%93Rodrigues_formula 861 + 862 + Vector3 result = v; 863 + 864 + // Vector3Normalize(axis); 865 + float length = sqrtf(axis.x * axis.x + axis.y * axis.y + axis.z * axis.z); 866 + if (length == 0.0f) 867 + length = 1.0f; 868 + float ilength = 1.0f / length; 869 + axis.x *= ilength; 870 + axis.y *= ilength; 871 + axis.z *= ilength; 872 + 873 + angle /= 2.0f; 874 + float a = sinf(angle); 875 + float b = axis.x * a; 876 + float c = axis.y * a; 877 + float d = axis.z * a; 878 + a = cosf(angle); 879 + Vector3 w = {b, c, d}; 880 + 881 + // Vector3CrossProduct(w, v) 882 + Vector3 wv = {w.y * v.z - w.z * v.y, w.z * v.x - w.x * v.z, 883 + w.x * v.y - w.y * v.x}; 884 + 885 + // Vector3CrossProduct(w, wv) 886 + Vector3 wwv = {w.y * wv.z - w.z * wv.y, w.z * wv.x - w.x * wv.z, 887 + w.x * wv.y - w.y * wv.x}; 888 + 889 + // Vector3Scale(wv, 2*a) 890 + a *= 2; 891 + wv.x *= a; 892 + wv.y *= a; 893 + wv.z *= a; 894 + 895 + // Vector3Scale(wwv, 2) 896 + wwv.x *= 2; 897 + wwv.y *= 2; 898 + wwv.z *= 2; 899 + 900 + result.x += wv.x; 901 + result.y += wv.y; 902 + result.z += wv.z; 903 + 904 + result.x += wwv.x; 905 + result.y += wwv.y; 906 + result.z += wwv.z; 907 + 908 + return result; 909 + } 910 + 911 + // Move Vector towards target 912 + RMAPI Vector3 Vector3MoveTowards(Vector3 v, Vector3 target, float maxDistance) { 913 + Vector3 result = {0}; 914 + 915 + float dx = target.x - v.x; 916 + float dy = target.y - v.y; 917 + float dz = target.z - v.z; 918 + float value = (dx * dx) + (dy * dy) + (dz * dz); 919 + 920 + if ((value == 0) || 921 + ((maxDistance >= 0) && (value <= maxDistance * maxDistance))) 922 + return target; 923 + 924 + float dist = sqrtf(value); 925 + 926 + result.x = v.x + dx / dist * maxDistance; 927 + result.y = v.y + dy / dist * maxDistance; 928 + result.z = v.z + dz / dist * maxDistance; 929 + 930 + return result; 931 + } 932 + 933 + // Calculate linear interpolation between two vectors 934 + RMAPI Vector3 Vector3Lerp(Vector3 v1, Vector3 v2, float amount) { 935 + Vector3 result = {0}; 936 + 937 + result.x = v1.x + amount * (v2.x - v1.x); 938 + result.y = v1.y + amount * (v2.y - v1.y); 939 + result.z = v1.z + amount * (v2.z - v1.z); 940 + 941 + return result; 942 + } 943 + 944 + // Calculate cubic hermite interpolation between two vectors and their tangents 945 + // as described in the GLTF 2.0 specification: 946 + // https://registry.khronos.org/glTF/specs/2.0/glTF-2.0.html#interpolation-cubic 947 + RMAPI Vector3 Vector3CubicHermite(Vector3 v1, Vector3 tangent1, Vector3 v2, 948 + Vector3 tangent2, float amount) { 949 + Vector3 result = {0}; 950 + 951 + float amountPow2 = amount * amount; 952 + float amountPow3 = amount * amount * amount; 953 + 954 + result.x = (2 * amountPow3 - 3 * amountPow2 + 1) * v1.x + 955 + (amountPow3 - 2 * amountPow2 + amount) * tangent1.x + 956 + (-2 * amountPow3 + 3 * amountPow2) * v2.x + 957 + (amountPow3 - amountPow2) * tangent2.x; 958 + result.y = (2 * amountPow3 - 3 * amountPow2 + 1) * v1.y + 959 + (amountPow3 - 2 * amountPow2 + amount) * tangent1.y + 960 + (-2 * amountPow3 + 3 * amountPow2) * v2.y + 961 + (amountPow3 - amountPow2) * tangent2.y; 962 + result.z = (2 * amountPow3 - 3 * amountPow2 + 1) * v1.z + 963 + (amountPow3 - 2 * amountPow2 + amount) * tangent1.z + 964 + (-2 * amountPow3 + 3 * amountPow2) * v2.z + 965 + (amountPow3 - amountPow2) * tangent2.z; 966 + 967 + return result; 968 + } 969 + 970 + // Calculate reflected vector to normal 971 + RMAPI Vector3 Vector3Reflect(Vector3 v, Vector3 normal) { 972 + Vector3 result = {0}; 973 + 974 + // I is the original vector 975 + // N is the normal of the incident plane 976 + // R = I - (2*N*(DotProduct[I, N])) 977 + 978 + float dotProduct = (v.x * normal.x + v.y * normal.y + v.z * normal.z); 979 + 980 + result.x = v.x - (2.0f * normal.x) * dotProduct; 981 + result.y = v.y - (2.0f * normal.y) * dotProduct; 982 + result.z = v.z - (2.0f * normal.z) * dotProduct; 983 + 984 + return result; 985 + } 986 + 987 + // Get min value for each pair of components 988 + RMAPI Vector3 Vector3Min(Vector3 v1, Vector3 v2) { 989 + Vector3 result = {0}; 990 + 991 + result.x = fminf(v1.x, v2.x); 992 + result.y = fminf(v1.y, v2.y); 993 + result.z = fminf(v1.z, v2.z); 994 + 995 + return result; 996 + } 997 + 998 + // Get max value for each pair of components 999 + RMAPI Vector3 Vector3Max(Vector3 v1, Vector3 v2) { 1000 + Vector3 result = {0}; 1001 + 1002 + result.x = fmaxf(v1.x, v2.x); 1003 + result.y = fmaxf(v1.y, v2.y); 1004 + result.z = fmaxf(v1.z, v2.z); 1005 + 1006 + return result; 1007 + } 1008 + 1009 + // Compute barycenter coordinates (u, v, w) for point p with respect to triangle 1010 + // (a, b, c) NOTE: Assumes P is on the plane of the triangle 1011 + RMAPI Vector3 Vector3Barycenter(Vector3 p, Vector3 a, Vector3 b, Vector3 c) { 1012 + Vector3 result = {0}; 1013 + 1014 + Vector3 v0 = {b.x - a.x, b.y - a.y, b.z - a.z}; // Vector3Subtract(b, a) 1015 + Vector3 v1 = {c.x - a.x, c.y - a.y, c.z - a.z}; // Vector3Subtract(c, a) 1016 + Vector3 v2 = {p.x - a.x, p.y - a.y, p.z - a.z}; // Vector3Subtract(p, a) 1017 + float d00 = 1018 + (v0.x * v0.x + v0.y * v0.y + v0.z * v0.z); // Vector3DotProduct(v0, v0) 1019 + float d01 = 1020 + (v0.x * v1.x + v0.y * v1.y + v0.z * v1.z); // Vector3DotProduct(v0, v1) 1021 + float d11 = 1022 + (v1.x * v1.x + v1.y * v1.y + v1.z * v1.z); // Vector3DotProduct(v1, v1) 1023 + float d20 = 1024 + (v2.x * v0.x + v2.y * v0.y + v2.z * v0.z); // Vector3DotProduct(v2, v0) 1025 + float d21 = 1026 + (v2.x * v1.x + v2.y * v1.y + v2.z * v1.z); // Vector3DotProduct(v2, v1) 1027 + 1028 + float denom = d00 * d11 - d01 * d01; 1029 + 1030 + result.y = (d11 * d20 - d01 * d21) / denom; 1031 + result.z = (d00 * d21 - d01 * d20) / denom; 1032 + result.x = 1.0f - (result.z + result.y); 1033 + 1034 + return result; 1035 + } 1036 + 1037 + // Projects a Vector3 from screen space into object space 1038 + // NOTE: We are avoiding calling other raymath functions despite available 1039 + RMAPI Vector3 Vector3Unproject(Vector3 source, Matrix projection, Matrix view) { 1040 + Vector3 result = {0}; 1041 + 1042 + // Calculate unprojected matrix (multiply view matrix by projection matrix) 1043 + // and invert it 1044 + Matrix matViewProj = { 1045 + // MatrixMultiply(view, projection); 1046 + view.m0 * projection.m0 + view.m1 * projection.m4 + 1047 + view.m2 * projection.m8 + view.m3 * projection.m12, 1048 + view.m0 * projection.m1 + view.m1 * projection.m5 + 1049 + view.m2 * projection.m9 + view.m3 * projection.m13, 1050 + view.m0 * projection.m2 + view.m1 * projection.m6 + 1051 + view.m2 * projection.m10 + view.m3 * projection.m14, 1052 + view.m0 * projection.m3 + view.m1 * projection.m7 + 1053 + view.m2 * projection.m11 + view.m3 * projection.m15, 1054 + view.m4 * projection.m0 + view.m5 * projection.m4 + 1055 + view.m6 * projection.m8 + view.m7 * projection.m12, 1056 + view.m4 * projection.m1 + view.m5 * projection.m5 + 1057 + view.m6 * projection.m9 + view.m7 * projection.m13, 1058 + view.m4 * projection.m2 + view.m5 * projection.m6 + 1059 + view.m6 * projection.m10 + view.m7 * projection.m14, 1060 + view.m4 * projection.m3 + view.m5 * projection.m7 + 1061 + view.m6 * projection.m11 + view.m7 * projection.m15, 1062 + view.m8 * projection.m0 + view.m9 * projection.m4 + 1063 + view.m10 * projection.m8 + view.m11 * projection.m12, 1064 + view.m8 * projection.m1 + view.m9 * projection.m5 + 1065 + view.m10 * projection.m9 + view.m11 * projection.m13, 1066 + view.m8 * projection.m2 + view.m9 * projection.m6 + 1067 + view.m10 * projection.m10 + view.m11 * projection.m14, 1068 + view.m8 * projection.m3 + view.m9 * projection.m7 + 1069 + view.m10 * projection.m11 + view.m11 * projection.m15, 1070 + view.m12 * projection.m0 + view.m13 * projection.m4 + 1071 + view.m14 * projection.m8 + view.m15 * projection.m12, 1072 + view.m12 * projection.m1 + view.m13 * projection.m5 + 1073 + view.m14 * projection.m9 + view.m15 * projection.m13, 1074 + view.m12 * projection.m2 + view.m13 * projection.m6 + 1075 + view.m14 * projection.m10 + view.m15 * projection.m14, 1076 + view.m12 * projection.m3 + view.m13 * projection.m7 + 1077 + view.m14 * projection.m11 + view.m15 * projection.m15}; 1078 + 1079 + // Calculate inverted matrix -> MatrixInvert(matViewProj); 1080 + // Cache the matrix values (speed optimization) 1081 + float a00 = matViewProj.m0, a01 = matViewProj.m1, a02 = matViewProj.m2, 1082 + a03 = matViewProj.m3; 1083 + float a10 = matViewProj.m4, a11 = matViewProj.m5, a12 = matViewProj.m6, 1084 + a13 = matViewProj.m7; 1085 + float a20 = matViewProj.m8, a21 = matViewProj.m9, a22 = matViewProj.m10, 1086 + a23 = matViewProj.m11; 1087 + float a30 = matViewProj.m12, a31 = matViewProj.m13, a32 = matViewProj.m14, 1088 + a33 = matViewProj.m15; 1089 + 1090 + float b00 = a00 * a11 - a01 * a10; 1091 + float b01 = a00 * a12 - a02 * a10; 1092 + float b02 = a00 * a13 - a03 * a10; 1093 + float b03 = a01 * a12 - a02 * a11; 1094 + float b04 = a01 * a13 - a03 * a11; 1095 + float b05 = a02 * a13 - a03 * a12; 1096 + float b06 = a20 * a31 - a21 * a30; 1097 + float b07 = a20 * a32 - a22 * a30; 1098 + float b08 = a20 * a33 - a23 * a30; 1099 + float b09 = a21 * a32 - a22 * a31; 1100 + float b10 = a21 * a33 - a23 * a31; 1101 + float b11 = a22 * a33 - a23 * a32; 1102 + 1103 + // Calculate the invert determinant (inlined to avoid double-caching) 1104 + float invDet = 1.0f / (b00 * b11 - b01 * b10 + b02 * b09 + b03 * b08 - 1105 + b04 * b07 + b05 * b06); 1106 + 1107 + Matrix matViewProjInv = {(a11 * b11 - a12 * b10 + a13 * b09) * invDet, 1108 + (-a01 * b11 + a02 * b10 - a03 * b09) * invDet, 1109 + (a31 * b05 - a32 * b04 + a33 * b03) * invDet, 1110 + (-a21 * b05 + a22 * b04 - a23 * b03) * invDet, 1111 + (-a10 * b11 + a12 * b08 - a13 * b07) * invDet, 1112 + (a00 * b11 - a02 * b08 + a03 * b07) * invDet, 1113 + (-a30 * b05 + a32 * b02 - a33 * b01) * invDet, 1114 + (a20 * b05 - a22 * b02 + a23 * b01) * invDet, 1115 + (a10 * b10 - a11 * b08 + a13 * b06) * invDet, 1116 + (-a00 * b10 + a01 * b08 - a03 * b06) * invDet, 1117 + (a30 * b04 - a31 * b02 + a33 * b00) * invDet, 1118 + (-a20 * b04 + a21 * b02 - a23 * b00) * invDet, 1119 + (-a10 * b09 + a11 * b07 - a12 * b06) * invDet, 1120 + (a00 * b09 - a01 * b07 + a02 * b06) * invDet, 1121 + (-a30 * b03 + a31 * b01 - a32 * b00) * invDet, 1122 + (a20 * b03 - a21 * b01 + a22 * b00) * invDet}; 1123 + 1124 + // Create quaternion from source point 1125 + Quaternion quat = {source.x, source.y, source.z, 1.0f}; 1126 + 1127 + // Multiply quat point by unprojecte matrix 1128 + Quaternion qtransformed = { 1129 + // QuaternionTransform(quat, matViewProjInv) 1130 + matViewProjInv.m0 * quat.x + matViewProjInv.m4 * quat.y + 1131 + matViewProjInv.m8 * quat.z + matViewProjInv.m12 * quat.w, 1132 + matViewProjInv.m1 * quat.x + matViewProjInv.m5 * quat.y + 1133 + matViewProjInv.m9 * quat.z + matViewProjInv.m13 * quat.w, 1134 + matViewProjInv.m2 * quat.x + matViewProjInv.m6 * quat.y + 1135 + matViewProjInv.m10 * quat.z + matViewProjInv.m14 * quat.w, 1136 + matViewProjInv.m3 * quat.x + matViewProjInv.m7 * quat.y + 1137 + matViewProjInv.m11 * quat.z + matViewProjInv.m15 * quat.w}; 1138 + 1139 + // Normalized world points in vectors 1140 + result.x = qtransformed.x / qtransformed.w; 1141 + result.y = qtransformed.y / qtransformed.w; 1142 + result.z = qtransformed.z / qtransformed.w; 1143 + 1144 + return result; 1145 + } 1146 + 1147 + // Get Vector3 as float array 1148 + RMAPI float3 Vector3ToFloatV(Vector3 v) { 1149 + float3 buffer = {0}; 1150 + 1151 + buffer.v[0] = v.x; 1152 + buffer.v[1] = v.y; 1153 + buffer.v[2] = v.z; 1154 + 1155 + return buffer; 1156 + } 1157 + 1158 + // Invert the given vector 1159 + RMAPI Vector3 Vector3Invert(Vector3 v) { 1160 + Vector3 result = {1.0f / v.x, 1.0f / v.y, 1.0f / v.z}; 1161 + 1162 + return result; 1163 + } 1164 + 1165 + // Clamp the components of the vector between 1166 + // min and max values specified by the given vectors 1167 + RMAPI Vector3 Vector3Clamp(Vector3 v, Vector3 min, Vector3 max) { 1168 + Vector3 result = {0}; 1169 + 1170 + result.x = fminf(max.x, fmaxf(min.x, v.x)); 1171 + result.y = fminf(max.y, fmaxf(min.y, v.y)); 1172 + result.z = fminf(max.z, fmaxf(min.z, v.z)); 1173 + 1174 + return result; 1175 + } 1176 + 1177 + // Clamp the magnitude of the vector between two values 1178 + RMAPI Vector3 Vector3ClampValue(Vector3 v, float min, float max) { 1179 + Vector3 result = v; 1180 + 1181 + float length = (v.x * v.x) + (v.y * v.y) + (v.z * v.z); 1182 + if (length > 0.0f) { 1183 + length = sqrtf(length); 1184 + 1185 + float scale = 1; // By default, 1 as the neutral element. 1186 + if (length < min) { 1187 + scale = min / length; 1188 + } else if (length > max) { 1189 + scale = max / length; 1190 + } 1191 + 1192 + result.x = v.x * scale; 1193 + result.y = v.y * scale; 1194 + result.z = v.z * scale; 1195 + } 1196 + 1197 + return result; 1198 + } 1199 + 1200 + // Check whether two given vectors are almost equal 1201 + RMAPI int Vector3Equals(Vector3 p, Vector3 q) { 1202 + #if !defined(EPSILON) 1203 + #define EPSILON 0.000001f 1204 + #endif 1205 + 1206 + int result = ((fabsf(p.x - q.x)) <= 1207 + (EPSILON * fmaxf(1.0f, fmaxf(fabsf(p.x), fabsf(q.x))))) && 1208 + ((fabsf(p.y - q.y)) <= 1209 + (EPSILON * fmaxf(1.0f, fmaxf(fabsf(p.y), fabsf(q.y))))) && 1210 + ((fabsf(p.z - q.z)) <= 1211 + (EPSILON * fmaxf(1.0f, fmaxf(fabsf(p.z), fabsf(q.z))))); 1212 + 1213 + return result; 1214 + } 1215 + 1216 + // Compute the direction of a refracted ray 1217 + // v: normalized direction of the incoming ray 1218 + // n: normalized normal vector of the interface of two optical media 1219 + // r: ratio of the refractive index of the medium from where the ray comes 1220 + // to the refractive index of the medium on the other side of the surface 1221 + RMAPI Vector3 Vector3Refract(Vector3 v, Vector3 n, float r) { 1222 + Vector3 result = {0}; 1223 + 1224 + float dot = v.x * n.x + v.y * n.y + v.z * n.z; 1225 + float d = 1.0f - r * r * (1.0f - dot * dot); 1226 + 1227 + if (d >= 0.0f) { 1228 + d = sqrtf(d); 1229 + v.x = r * v.x - (r * dot + d) * n.x; 1230 + v.y = r * v.y - (r * dot + d) * n.y; 1231 + v.z = r * v.z - (r * dot + d) * n.z; 1232 + 1233 + result = v; 1234 + } 1235 + 1236 + return result; 1237 + } 1238 + 1239 + //---------------------------------------------------------------------------------- 1240 + // Module Functions Definition - Vector4 math 1241 + //---------------------------------------------------------------------------------- 1242 + 1243 + RMAPI Vector4 Vector4Zero(void) { 1244 + Vector4 result = {0.0f, 0.0f, 0.0f, 0.0f}; 1245 + return result; 1246 + } 1247 + 1248 + RMAPI Vector4 Vector4One(void) { 1249 + Vector4 result = {1.0f, 1.0f, 1.0f, 1.0f}; 1250 + return result; 1251 + } 1252 + 1253 + RMAPI Vector4 Vector4Add(Vector4 v1, Vector4 v2) { 1254 + Vector4 result = {v1.x + v2.x, v1.y + v2.y, v1.z + v2.z, v1.w + v2.w}; 1255 + return result; 1256 + } 1257 + 1258 + RMAPI Vector4 Vector4AddValue(Vector4 v, float add) { 1259 + Vector4 result = {v.x + add, v.y + add, v.z + add, v.w + add}; 1260 + return result; 1261 + } 1262 + 1263 + RMAPI Vector4 Vector4Subtract(Vector4 v1, Vector4 v2) { 1264 + Vector4 result = {v1.x - v2.x, v1.y - v2.y, v1.z - v2.z, v1.w - v2.w}; 1265 + return result; 1266 + } 1267 + 1268 + RMAPI Vector4 Vector4SubtractValue(Vector4 v, float add) { 1269 + Vector4 result = {v.x - add, v.y - add, v.z - add, v.w - add}; 1270 + return result; 1271 + } 1272 + 1273 + RMAPI float Vector4Length(Vector4 v) { 1274 + float result = sqrtf((v.x * v.x) + (v.y * v.y) + (v.z * v.z) + (v.w * v.w)); 1275 + return result; 1276 + } 1277 + 1278 + RMAPI float Vector4LengthSqr(Vector4 v) { 1279 + float result = (v.x * v.x) + (v.y * v.y) + (v.z * v.z) + (v.w * v.w); 1280 + return result; 1281 + } 1282 + 1283 + RMAPI float Vector4DotProduct(Vector4 v1, Vector4 v2) { 1284 + float result = (v1.x * v2.x + v1.y * v2.y + v1.z * v2.z + v1.w * v2.w); 1285 + return result; 1286 + } 1287 + 1288 + // Calculate distance between two vectors 1289 + RMAPI float Vector4Distance(Vector4 v1, Vector4 v2) { 1290 + float result = 1291 + sqrtf((v1.x - v2.x) * (v1.x - v2.x) + (v1.y - v2.y) * (v1.y - v2.y) + 1292 + (v1.z - v2.z) * (v1.z - v2.z) + (v1.w - v2.w) * (v1.w - v2.w)); 1293 + return result; 1294 + } 1295 + 1296 + // Calculate square distance between two vectors 1297 + RMAPI float Vector4DistanceSqr(Vector4 v1, Vector4 v2) { 1298 + float result = (v1.x - v2.x) * (v1.x - v2.x) + (v1.y - v2.y) * (v1.y - v2.y) + 1299 + (v1.z - v2.z) * (v1.z - v2.z) + (v1.w - v2.w) * (v1.w - v2.w); 1300 + 1301 + return result; 1302 + } 1303 + 1304 + RMAPI Vector4 Vector4Scale(Vector4 v, float scale) { 1305 + Vector4 result = {v.x * scale, v.y * scale, v.z * scale, v.w * scale}; 1306 + return result; 1307 + } 1308 + 1309 + // Multiply vector by vector 1310 + RMAPI Vector4 Vector4Multiply(Vector4 v1, Vector4 v2) { 1311 + Vector4 result = {v1.x * v2.x, v1.y * v2.y, v1.z * v2.z, v1.w * v2.w}; 1312 + return result; 1313 + } 1314 + 1315 + // Negate vector 1316 + RMAPI Vector4 Vector4Negate(Vector4 v) { 1317 + Vector4 result = {-v.x, -v.y, -v.z, -v.w}; 1318 + return result; 1319 + } 1320 + 1321 + // Divide vector by vector 1322 + RMAPI Vector4 Vector4Divide(Vector4 v1, Vector4 v2) { 1323 + Vector4 result = {v1.x / v2.x, v1.y / v2.y, v1.z / v2.z, v1.w / v2.w}; 1324 + return result; 1325 + } 1326 + 1327 + // Normalize provided vector 1328 + RMAPI Vector4 Vector4Normalize(Vector4 v) { 1329 + Vector4 result = {0}; 1330 + float length = sqrtf((v.x * v.x) + (v.y * v.y) + (v.z * v.z) + (v.w * v.w)); 1331 + 1332 + if (length > 0) { 1333 + float ilength = 1.0f / length; 1334 + result.x = v.x * ilength; 1335 + result.y = v.y * ilength; 1336 + result.z = v.z * ilength; 1337 + result.w = v.w * ilength; 1338 + } 1339 + 1340 + return result; 1341 + } 1342 + 1343 + // Get min value for each pair of components 1344 + RMAPI Vector4 Vector4Min(Vector4 v1, Vector4 v2) { 1345 + Vector4 result = {0}; 1346 + 1347 + result.x = fminf(v1.x, v2.x); 1348 + result.y = fminf(v1.y, v2.y); 1349 + result.z = fminf(v1.z, v2.z); 1350 + result.w = fminf(v1.w, v2.w); 1351 + 1352 + return result; 1353 + } 1354 + 1355 + // Get max value for each pair of components 1356 + RMAPI Vector4 Vector4Max(Vector4 v1, Vector4 v2) { 1357 + Vector4 result = {0}; 1358 + 1359 + result.x = fmaxf(v1.x, v2.x); 1360 + result.y = fmaxf(v1.y, v2.y); 1361 + result.z = fmaxf(v1.z, v2.z); 1362 + result.w = fmaxf(v1.w, v2.w); 1363 + 1364 + return result; 1365 + } 1366 + 1367 + // Calculate linear interpolation between two vectors 1368 + RMAPI Vector4 Vector4Lerp(Vector4 v1, Vector4 v2, float amount) { 1369 + Vector4 result = {0}; 1370 + 1371 + result.x = v1.x + amount * (v2.x - v1.x); 1372 + result.y = v1.y + amount * (v2.y - v1.y); 1373 + result.z = v1.z + amount * (v2.z - v1.z); 1374 + result.w = v1.w + amount * (v2.w - v1.w); 1375 + 1376 + return result; 1377 + } 1378 + 1379 + // Move Vector towards target 1380 + RMAPI Vector4 Vector4MoveTowards(Vector4 v, Vector4 target, float maxDistance) { 1381 + Vector4 result = {0}; 1382 + 1383 + float dx = target.x - v.x; 1384 + float dy = target.y - v.y; 1385 + float dz = target.z - v.z; 1386 + float dw = target.w - v.w; 1387 + float value = (dx * dx) + (dy * dy) + (dz * dz) + (dw * dw); 1388 + 1389 + if ((value == 0) || 1390 + ((maxDistance >= 0) && (value <= maxDistance * maxDistance))) 1391 + return target; 1392 + 1393 + float dist = sqrtf(value); 1394 + 1395 + result.x = v.x + dx / dist * maxDistance; 1396 + result.y = v.y + dy / dist * maxDistance; 1397 + result.z = v.z + dz / dist * maxDistance; 1398 + result.w = v.w + dw / dist * maxDistance; 1399 + 1400 + return result; 1401 + } 1402 + 1403 + // Invert the given vector 1404 + RMAPI Vector4 Vector4Invert(Vector4 v) { 1405 + Vector4 result = {1.0f / v.x, 1.0f / v.y, 1.0f / v.z, 1.0f / v.w}; 1406 + return result; 1407 + } 1408 + 1409 + // Check whether two given vectors are almost equal 1410 + RMAPI int Vector4Equals(Vector4 p, Vector4 q) { 1411 + #if !defined(EPSILON) 1412 + #define EPSILON 0.000001f 1413 + #endif 1414 + 1415 + int result = ((fabsf(p.x - q.x)) <= 1416 + (EPSILON * fmaxf(1.0f, fmaxf(fabsf(p.x), fabsf(q.x))))) && 1417 + ((fabsf(p.y - q.y)) <= 1418 + (EPSILON * fmaxf(1.0f, fmaxf(fabsf(p.y), fabsf(q.y))))) && 1419 + ((fabsf(p.z - q.z)) <= 1420 + (EPSILON * fmaxf(1.0f, fmaxf(fabsf(p.z), fabsf(q.z))))) && 1421 + ((fabsf(p.w - q.w)) <= 1422 + (EPSILON * fmaxf(1.0f, fmaxf(fabsf(p.w), fabsf(q.w))))); 1423 + return result; 1424 + } 1425 + 1426 + //---------------------------------------------------------------------------------- 1427 + // Module Functions Definition - Matrix math 1428 + //---------------------------------------------------------------------------------- 1429 + 1430 + // Compute matrix determinant 1431 + RMAPI float MatrixDeterminant(Matrix mat) { 1432 + float result = 0.0f; 1433 + /* 1434 + // Cache the matrix values (speed optimization) 1435 + float a00 = mat.m0, a01 = mat.m1, a02 = mat.m2, a03 = mat.m3; 1436 + float a10 = mat.m4, a11 = mat.m5, a12 = mat.m6, a13 = mat.m7; 1437 + float a20 = mat.m8, a21 = mat.m9, a22 = mat.m10, a23 = mat.m11; 1438 + float a30 = mat.m12, a31 = mat.m13, a32 = mat.m14, a33 = mat.m15; 1439 + 1440 + // NOTE: It takes 72 multiplication to calculate 4x4 matrix determinant 1441 + result = a30*a21*a12*a03 - a20*a31*a12*a03 - a30*a11*a22*a03 + 1442 + a10*a31*a22*a03 + a20*a11*a32*a03 - a10*a21*a32*a03 - a30*a21*a02*a13 + 1443 + a20*a31*a02*a13 + a30*a01*a22*a13 - a00*a31*a22*a13 - a20*a01*a32*a13 + 1444 + a00*a21*a32*a13 + a30*a11*a02*a23 - a10*a31*a02*a23 - a30*a01*a12*a23 + 1445 + a00*a31*a12*a23 + a10*a01*a32*a23 - a00*a11*a32*a23 - a20*a11*a02*a33 + 1446 + a10*a21*a02*a33 + a20*a01*a12*a33 - a00*a21*a12*a33 - a10*a01*a22*a33 + 1447 + a00*a11*a22*a33; 1448 + */ 1449 + // Using Laplace expansion (https://en.wikipedia.org/wiki/Laplace_expansion), 1450 + // previous operation can be simplified to 40 multiplications, decreasing 1451 + // matrix size from 4x4 to 2x2 using minors 1452 + 1453 + // Cache the matrix values (speed optimization) 1454 + float m0 = mat.m0, m1 = mat.m1, m2 = mat.m2, m3 = mat.m3; 1455 + float m4 = mat.m4, m5 = mat.m5, m6 = mat.m6, m7 = mat.m7; 1456 + float m8 = mat.m8, m9 = mat.m9, m10 = mat.m10, m11 = mat.m11; 1457 + float m12 = mat.m12, m13 = mat.m13, m14 = mat.m14, m15 = mat.m15; 1458 + 1459 + result = (m0 * ((m5 * (m10 * m15 - m11 * m14) - m9 * (m6 * m15 - m7 * m14) + 1460 + m13 * (m6 * m11 - m7 * m10))) - 1461 + m4 * ((m1 * (m10 * m15 - m11 * m14) - m9 * (m2 * m15 - m3 * m14) + 1462 + m13 * (m2 * m11 - m3 * m10))) + 1463 + m8 * ((m1 * (m6 * m15 - m7 * m14) - m5 * (m2 * m15 - m3 * m14) + 1464 + m13 * (m2 * m7 - m3 * m6))) - 1465 + m12 * ((m1 * (m6 * m11 - m7 * m10) - m5 * (m2 * m11 - m3 * m10) + 1466 + m9 * (m2 * m7 - m3 * m6)))); 1467 + 1468 + return result; 1469 + } 1470 + 1471 + // Get the trace of the matrix (sum of the values along the diagonal) 1472 + RMAPI float MatrixTrace(Matrix mat) { 1473 + float result = (mat.m0 + mat.m5 + mat.m10 + mat.m15); 1474 + 1475 + return result; 1476 + } 1477 + 1478 + // Transposes provided matrix 1479 + RMAPI Matrix MatrixTranspose(Matrix mat) { 1480 + Matrix result = {0}; 1481 + 1482 + result.m0 = mat.m0; 1483 + result.m1 = mat.m4; 1484 + result.m2 = mat.m8; 1485 + result.m3 = mat.m12; 1486 + result.m4 = mat.m1; 1487 + result.m5 = mat.m5; 1488 + result.m6 = mat.m9; 1489 + result.m7 = mat.m13; 1490 + result.m8 = mat.m2; 1491 + result.m9 = mat.m6; 1492 + result.m10 = mat.m10; 1493 + result.m11 = mat.m14; 1494 + result.m12 = mat.m3; 1495 + result.m13 = mat.m7; 1496 + result.m14 = mat.m11; 1497 + result.m15 = mat.m15; 1498 + 1499 + return result; 1500 + } 1501 + 1502 + // Invert provided matrix 1503 + RMAPI Matrix MatrixInvert(Matrix mat) { 1504 + Matrix result = {0}; 1505 + 1506 + // Cache the matrix values (speed optimization) 1507 + float a00 = mat.m0, a01 = mat.m1, a02 = mat.m2, a03 = mat.m3; 1508 + float a10 = mat.m4, a11 = mat.m5, a12 = mat.m6, a13 = mat.m7; 1509 + float a20 = mat.m8, a21 = mat.m9, a22 = mat.m10, a23 = mat.m11; 1510 + float a30 = mat.m12, a31 = mat.m13, a32 = mat.m14, a33 = mat.m15; 1511 + 1512 + float b00 = a00 * a11 - a01 * a10; 1513 + float b01 = a00 * a12 - a02 * a10; 1514 + float b02 = a00 * a13 - a03 * a10; 1515 + float b03 = a01 * a12 - a02 * a11; 1516 + float b04 = a01 * a13 - a03 * a11; 1517 + float b05 = a02 * a13 - a03 * a12; 1518 + float b06 = a20 * a31 - a21 * a30; 1519 + float b07 = a20 * a32 - a22 * a30; 1520 + float b08 = a20 * a33 - a23 * a30; 1521 + float b09 = a21 * a32 - a22 * a31; 1522 + float b10 = a21 * a33 - a23 * a31; 1523 + float b11 = a22 * a33 - a23 * a32; 1524 + 1525 + // Calculate the invert determinant (inlined to avoid double-caching) 1526 + float invDet = 1.0f / (b00 * b11 - b01 * b10 + b02 * b09 + b03 * b08 - 1527 + b04 * b07 + b05 * b06); 1528 + 1529 + result.m0 = (a11 * b11 - a12 * b10 + a13 * b09) * invDet; 1530 + result.m1 = (-a01 * b11 + a02 * b10 - a03 * b09) * invDet; 1531 + result.m2 = (a31 * b05 - a32 * b04 + a33 * b03) * invDet; 1532 + result.m3 = (-a21 * b05 + a22 * b04 - a23 * b03) * invDet; 1533 + result.m4 = (-a10 * b11 + a12 * b08 - a13 * b07) * invDet; 1534 + result.m5 = (a00 * b11 - a02 * b08 + a03 * b07) * invDet; 1535 + result.m6 = (-a30 * b05 + a32 * b02 - a33 * b01) * invDet; 1536 + result.m7 = (a20 * b05 - a22 * b02 + a23 * b01) * invDet; 1537 + result.m8 = (a10 * b10 - a11 * b08 + a13 * b06) * invDet; 1538 + result.m9 = (-a00 * b10 + a01 * b08 - a03 * b06) * invDet; 1539 + result.m10 = (a30 * b04 - a31 * b02 + a33 * b00) * invDet; 1540 + result.m11 = (-a20 * b04 + a21 * b02 - a23 * b00) * invDet; 1541 + result.m12 = (-a10 * b09 + a11 * b07 - a12 * b06) * invDet; 1542 + result.m13 = (a00 * b09 - a01 * b07 + a02 * b06) * invDet; 1543 + result.m14 = (-a30 * b03 + a31 * b01 - a32 * b00) * invDet; 1544 + result.m15 = (a20 * b03 - a21 * b01 + a22 * b00) * invDet; 1545 + 1546 + return result; 1547 + } 1548 + 1549 + // Get identity matrix 1550 + RMAPI Matrix MatrixIdentity(void) { 1551 + Matrix result = {1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 1552 + 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f}; 1553 + 1554 + return result; 1555 + } 1556 + 1557 + // Add two matrices 1558 + RMAPI Matrix MatrixAdd(Matrix left, Matrix right) { 1559 + Matrix result = {0}; 1560 + 1561 + result.m0 = left.m0 + right.m0; 1562 + result.m1 = left.m1 + right.m1; 1563 + result.m2 = left.m2 + right.m2; 1564 + result.m3 = left.m3 + right.m3; 1565 + result.m4 = left.m4 + right.m4; 1566 + result.m5 = left.m5 + right.m5; 1567 + result.m6 = left.m6 + right.m6; 1568 + result.m7 = left.m7 + right.m7; 1569 + result.m8 = left.m8 + right.m8; 1570 + result.m9 = left.m9 + right.m9; 1571 + result.m10 = left.m10 + right.m10; 1572 + result.m11 = left.m11 + right.m11; 1573 + result.m12 = left.m12 + right.m12; 1574 + result.m13 = left.m13 + right.m13; 1575 + result.m14 = left.m14 + right.m14; 1576 + result.m15 = left.m15 + right.m15; 1577 + 1578 + return result; 1579 + } 1580 + 1581 + // Subtract two matrices (left - right) 1582 + RMAPI Matrix MatrixSubtract(Matrix left, Matrix right) { 1583 + Matrix result = {0}; 1584 + 1585 + result.m0 = left.m0 - right.m0; 1586 + result.m1 = left.m1 - right.m1; 1587 + result.m2 = left.m2 - right.m2; 1588 + result.m3 = left.m3 - right.m3; 1589 + result.m4 = left.m4 - right.m4; 1590 + result.m5 = left.m5 - right.m5; 1591 + result.m6 = left.m6 - right.m6; 1592 + result.m7 = left.m7 - right.m7; 1593 + result.m8 = left.m8 - right.m8; 1594 + result.m9 = left.m9 - right.m9; 1595 + result.m10 = left.m10 - right.m10; 1596 + result.m11 = left.m11 - right.m11; 1597 + result.m12 = left.m12 - right.m12; 1598 + result.m13 = left.m13 - right.m13; 1599 + result.m14 = left.m14 - right.m14; 1600 + result.m15 = left.m15 - right.m15; 1601 + 1602 + return result; 1603 + } 1604 + 1605 + // Get two matrix multiplication 1606 + // NOTE: When multiplying matrices... the order matters! 1607 + RMAPI Matrix MatrixMultiply(Matrix left, Matrix right) { 1608 + Matrix result = {0}; 1609 + 1610 + result.m0 = left.m0 * right.m0 + left.m1 * right.m4 + left.m2 * right.m8 + 1611 + left.m3 * right.m12; 1612 + result.m1 = left.m0 * right.m1 + left.m1 * right.m5 + left.m2 * right.m9 + 1613 + left.m3 * right.m13; 1614 + result.m2 = left.m0 * right.m2 + left.m1 * right.m6 + left.m2 * right.m10 + 1615 + left.m3 * right.m14; 1616 + result.m3 = left.m0 * right.m3 + left.m1 * right.m7 + left.m2 * right.m11 + 1617 + left.m3 * right.m15; 1618 + result.m4 = left.m4 * right.m0 + left.m5 * right.m4 + left.m6 * right.m8 + 1619 + left.m7 * right.m12; 1620 + result.m5 = left.m4 * right.m1 + left.m5 * right.m5 + left.m6 * right.m9 + 1621 + left.m7 * right.m13; 1622 + result.m6 = left.m4 * right.m2 + left.m5 * right.m6 + left.m6 * right.m10 + 1623 + left.m7 * right.m14; 1624 + result.m7 = left.m4 * right.m3 + left.m5 * right.m7 + left.m6 * right.m11 + 1625 + left.m7 * right.m15; 1626 + result.m8 = left.m8 * right.m0 + left.m9 * right.m4 + left.m10 * right.m8 + 1627 + left.m11 * right.m12; 1628 + result.m9 = left.m8 * right.m1 + left.m9 * right.m5 + left.m10 * right.m9 + 1629 + left.m11 * right.m13; 1630 + result.m10 = left.m8 * right.m2 + left.m9 * right.m6 + left.m10 * right.m10 + 1631 + left.m11 * right.m14; 1632 + result.m11 = left.m8 * right.m3 + left.m9 * right.m7 + left.m10 * right.m11 + 1633 + left.m11 * right.m15; 1634 + result.m12 = left.m12 * right.m0 + left.m13 * right.m4 + left.m14 * right.m8 + 1635 + left.m15 * right.m12; 1636 + result.m13 = left.m12 * right.m1 + left.m13 * right.m5 + left.m14 * right.m9 + 1637 + left.m15 * right.m13; 1638 + result.m14 = left.m12 * right.m2 + left.m13 * right.m6 + 1639 + left.m14 * right.m10 + left.m15 * right.m14; 1640 + result.m15 = left.m12 * right.m3 + left.m13 * right.m7 + 1641 + left.m14 * right.m11 + left.m15 * right.m15; 1642 + 1643 + return result; 1644 + } 1645 + 1646 + // Get translation matrix 1647 + RMAPI Matrix MatrixTranslate(float x, float y, float z) { 1648 + Matrix result = {1.0f, 0.0f, 0.0f, x, 0.0f, 1.0f, 0.0f, y, 1649 + 0.0f, 0.0f, 1.0f, z, 0.0f, 0.0f, 0.0f, 1.0f}; 1650 + 1651 + return result; 1652 + } 1653 + 1654 + // Create rotation matrix from axis and angle 1655 + // NOTE: Angle should be provided in radians 1656 + RMAPI Matrix MatrixRotate(Vector3 axis, float angle) { 1657 + Matrix result = {0}; 1658 + 1659 + float x = axis.x, y = axis.y, z = axis.z; 1660 + 1661 + float lengthSquared = x * x + y * y + z * z; 1662 + 1663 + if ((lengthSquared != 1.0f) && (lengthSquared != 0.0f)) { 1664 + float ilength = 1.0f / sqrtf(lengthSquared); 1665 + x *= ilength; 1666 + y *= ilength; 1667 + z *= ilength; 1668 + } 1669 + 1670 + float sinres = sinf(angle); 1671 + float cosres = cosf(angle); 1672 + float t = 1.0f - cosres; 1673 + 1674 + result.m0 = x * x * t + cosres; 1675 + result.m1 = y * x * t + z * sinres; 1676 + result.m2 = z * x * t - y * sinres; 1677 + result.m3 = 0.0f; 1678 + 1679 + result.m4 = x * y * t - z * sinres; 1680 + result.m5 = y * y * t + cosres; 1681 + result.m6 = z * y * t + x * sinres; 1682 + result.m7 = 0.0f; 1683 + 1684 + result.m8 = x * z * t + y * sinres; 1685 + result.m9 = y * z * t - x * sinres; 1686 + result.m10 = z * z * t + cosres; 1687 + result.m11 = 0.0f; 1688 + 1689 + result.m12 = 0.0f; 1690 + result.m13 = 0.0f; 1691 + result.m14 = 0.0f; 1692 + result.m15 = 1.0f; 1693 + 1694 + return result; 1695 + } 1696 + 1697 + // Get x-rotation matrix 1698 + // NOTE: Angle must be provided in radians 1699 + RMAPI Matrix MatrixRotateX(float angle) { 1700 + Matrix result = { 1701 + 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 1702 + 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f}; // MatrixIdentity() 1703 + 1704 + float cosres = cosf(angle); 1705 + float sinres = sinf(angle); 1706 + 1707 + result.m5 = cosres; 1708 + result.m6 = sinres; 1709 + result.m9 = -sinres; 1710 + result.m10 = cosres; 1711 + 1712 + return result; 1713 + } 1714 + 1715 + // Get y-rotation matrix 1716 + // NOTE: Angle must be provided in radians 1717 + RMAPI Matrix MatrixRotateY(float angle) { 1718 + Matrix result = { 1719 + 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 1720 + 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f}; // MatrixIdentity() 1721 + 1722 + float cosres = cosf(angle); 1723 + float sinres = sinf(angle); 1724 + 1725 + result.m0 = cosres; 1726 + result.m2 = -sinres; 1727 + result.m8 = sinres; 1728 + result.m10 = cosres; 1729 + 1730 + return result; 1731 + } 1732 + 1733 + // Get z-rotation matrix 1734 + // NOTE: Angle must be provided in radians 1735 + RMAPI Matrix MatrixRotateZ(float angle) { 1736 + Matrix result = { 1737 + 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 1738 + 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f}; // MatrixIdentity() 1739 + 1740 + float cosres = cosf(angle); 1741 + float sinres = sinf(angle); 1742 + 1743 + result.m0 = cosres; 1744 + result.m1 = sinres; 1745 + result.m4 = -sinres; 1746 + result.m5 = cosres; 1747 + 1748 + return result; 1749 + } 1750 + 1751 + // Get xyz-rotation matrix 1752 + // NOTE: Angle must be provided in radians 1753 + RMAPI Matrix MatrixRotateXYZ(Vector3 angle) { 1754 + Matrix result = { 1755 + 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 1756 + 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f}; // MatrixIdentity() 1757 + 1758 + float cosz = cosf(-angle.z); 1759 + float sinz = sinf(-angle.z); 1760 + float cosy = cosf(-angle.y); 1761 + float siny = sinf(-angle.y); 1762 + float cosx = cosf(-angle.x); 1763 + float sinx = sinf(-angle.x); 1764 + 1765 + result.m0 = cosz * cosy; 1766 + result.m1 = (cosz * siny * sinx) - (sinz * cosx); 1767 + result.m2 = (cosz * siny * cosx) + (sinz * sinx); 1768 + 1769 + result.m4 = sinz * cosy; 1770 + result.m5 = (sinz * siny * sinx) + (cosz * cosx); 1771 + result.m6 = (sinz * siny * cosx) - (cosz * sinx); 1772 + 1773 + result.m8 = -siny; 1774 + result.m9 = cosy * sinx; 1775 + result.m10 = cosy * cosx; 1776 + 1777 + return result; 1778 + } 1779 + 1780 + // Get zyx-rotation matrix 1781 + // NOTE: Angle must be provided in radians 1782 + RMAPI Matrix MatrixRotateZYX(Vector3 angle) { 1783 + Matrix result = {0}; 1784 + 1785 + float cz = cosf(angle.z); 1786 + float sz = sinf(angle.z); 1787 + float cy = cosf(angle.y); 1788 + float sy = sinf(angle.y); 1789 + float cx = cosf(angle.x); 1790 + float sx = sinf(angle.x); 1791 + 1792 + result.m0 = cz * cy; 1793 + result.m4 = cz * sy * sx - cx * sz; 1794 + result.m8 = sz * sx + cz * cx * sy; 1795 + result.m12 = 0; 1796 + 1797 + result.m1 = cy * sz; 1798 + result.m5 = cz * cx + sz * sy * sx; 1799 + result.m9 = cx * sz * sy - cz * sx; 1800 + result.m13 = 0; 1801 + 1802 + result.m2 = -sy; 1803 + result.m6 = cy * sx; 1804 + result.m10 = cy * cx; 1805 + result.m14 = 0; 1806 + 1807 + result.m3 = 0; 1808 + result.m7 = 0; 1809 + result.m11 = 0; 1810 + result.m15 = 1; 1811 + 1812 + return result; 1813 + } 1814 + 1815 + // Get scaling matrix 1816 + RMAPI Matrix MatrixScale(float x, float y, float z) { 1817 + Matrix result = {x, 0.0f, 0.0f, 0.0f, 0.0f, y, 0.0f, 0.0f, 1818 + 0.0f, 0.0f, z, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f}; 1819 + 1820 + return result; 1821 + } 1822 + 1823 + // Get perspective projection matrix 1824 + RMAPI Matrix MatrixFrustum(double left, double right, double bottom, double top, 1825 + double nearPlane, double farPlane) { 1826 + Matrix result = {0}; 1827 + 1828 + float rl = (float)(right - left); 1829 + float tb = (float)(top - bottom); 1830 + float fn = (float)(farPlane - nearPlane); 1831 + 1832 + result.m0 = ((float)nearPlane * 2.0f) / rl; 1833 + result.m1 = 0.0f; 1834 + result.m2 = 0.0f; 1835 + result.m3 = 0.0f; 1836 + 1837 + result.m4 = 0.0f; 1838 + result.m5 = ((float)nearPlane * 2.0f) / tb; 1839 + result.m6 = 0.0f; 1840 + result.m7 = 0.0f; 1841 + 1842 + result.m8 = ((float)right + (float)left) / rl; 1843 + result.m9 = ((float)top + (float)bottom) / tb; 1844 + result.m10 = -((float)farPlane + (float)nearPlane) / fn; 1845 + result.m11 = -1.0f; 1846 + 1847 + result.m12 = 0.0f; 1848 + result.m13 = 0.0f; 1849 + result.m14 = -((float)farPlane * (float)nearPlane * 2.0f) / fn; 1850 + result.m15 = 0.0f; 1851 + 1852 + return result; 1853 + } 1854 + 1855 + // Get perspective projection matrix 1856 + // NOTE: Fovy angle must be provided in radians 1857 + RMAPI Matrix MatrixPerspective(double fovY, double aspect, double nearPlane, 1858 + double farPlane) { 1859 + Matrix result = {0}; 1860 + 1861 + double top = nearPlane * tan(fovY * 0.5); 1862 + double bottom = -top; 1863 + double right = top * aspect; 1864 + double left = -right; 1865 + 1866 + // MatrixFrustum(-right, right, -top, top, near, far); 1867 + float rl = (float)(right - left); 1868 + float tb = (float)(top - bottom); 1869 + float fn = (float)(farPlane - nearPlane); 1870 + 1871 + result.m0 = ((float)nearPlane * 2.0f) / rl; 1872 + result.m5 = ((float)nearPlane * 2.0f) / tb; 1873 + result.m8 = ((float)right + (float)left) / rl; 1874 + result.m9 = ((float)top + (float)bottom) / tb; 1875 + result.m10 = -((float)farPlane + (float)nearPlane) / fn; 1876 + result.m11 = -1.0f; 1877 + result.m14 = -((float)farPlane * (float)nearPlane * 2.0f) / fn; 1878 + 1879 + return result; 1880 + } 1881 + 1882 + // Get orthographic projection matrix 1883 + RMAPI Matrix MatrixOrtho(double left, double right, double bottom, double top, 1884 + double nearPlane, double farPlane) { 1885 + Matrix result = {0}; 1886 + 1887 + float rl = (float)(right - left); 1888 + float tb = (float)(top - bottom); 1889 + float fn = (float)(farPlane - nearPlane); 1890 + 1891 + result.m0 = 2.0f / rl; 1892 + result.m1 = 0.0f; 1893 + result.m2 = 0.0f; 1894 + result.m3 = 0.0f; 1895 + result.m4 = 0.0f; 1896 + result.m5 = 2.0f / tb; 1897 + result.m6 = 0.0f; 1898 + result.m7 = 0.0f; 1899 + result.m8 = 0.0f; 1900 + result.m9 = 0.0f; 1901 + result.m10 = -2.0f / fn; 1902 + result.m11 = 0.0f; 1903 + result.m12 = -((float)left + (float)right) / rl; 1904 + result.m13 = -((float)top + (float)bottom) / tb; 1905 + result.m14 = -((float)farPlane + (float)nearPlane) / fn; 1906 + result.m15 = 1.0f; 1907 + 1908 + return result; 1909 + } 1910 + 1911 + // Get camera look-at matrix (view matrix) 1912 + RMAPI Matrix MatrixLookAt(Vector3 eye, Vector3 target, Vector3 up) { 1913 + Matrix result = {0}; 1914 + 1915 + float length = 0.0f; 1916 + float ilength = 0.0f; 1917 + 1918 + // Vector3Subtract(eye, target) 1919 + Vector3 vz = {eye.x - target.x, eye.y - target.y, eye.z - target.z}; 1920 + 1921 + // Vector3Normalize(vz) 1922 + Vector3 v = vz; 1923 + length = sqrtf(v.x * v.x + v.y * v.y + v.z * v.z); 1924 + if (length == 0.0f) 1925 + length = 1.0f; 1926 + ilength = 1.0f / length; 1927 + vz.x *= ilength; 1928 + vz.y *= ilength; 1929 + vz.z *= ilength; 1930 + 1931 + // Vector3CrossProduct(up, vz) 1932 + Vector3 vx = {up.y * vz.z - up.z * vz.y, up.z * vz.x - up.x * vz.z, 1933 + up.x * vz.y - up.y * vz.x}; 1934 + 1935 + // Vector3Normalize(x) 1936 + v = vx; 1937 + length = sqrtf(v.x * v.x + v.y * v.y + v.z * v.z); 1938 + if (length == 0.0f) 1939 + length = 1.0f; 1940 + ilength = 1.0f / length; 1941 + vx.x *= ilength; 1942 + vx.y *= ilength; 1943 + vx.z *= ilength; 1944 + 1945 + // Vector3CrossProduct(vz, vx) 1946 + Vector3 vy = {vz.y * vx.z - vz.z * vx.y, vz.z * vx.x - vz.x * vx.z, 1947 + vz.x * vx.y - vz.y * vx.x}; 1948 + 1949 + result.m0 = vx.x; 1950 + result.m1 = vy.x; 1951 + result.m2 = vz.x; 1952 + result.m3 = 0.0f; 1953 + result.m4 = vx.y; 1954 + result.m5 = vy.y; 1955 + result.m6 = vz.y; 1956 + result.m7 = 0.0f; 1957 + result.m8 = vx.z; 1958 + result.m9 = vy.z; 1959 + result.m10 = vz.z; 1960 + result.m11 = 0.0f; 1961 + result.m12 = -(vx.x * eye.x + vx.y * eye.y + 1962 + vx.z * eye.z); // Vector3DotProduct(vx, eye) 1963 + result.m13 = -(vy.x * eye.x + vy.y * eye.y + 1964 + vy.z * eye.z); // Vector3DotProduct(vy, eye) 1965 + result.m14 = -(vz.x * eye.x + vz.y * eye.y + 1966 + vz.z * eye.z); // Vector3DotProduct(vz, eye) 1967 + result.m15 = 1.0f; 1968 + 1969 + return result; 1970 + } 1971 + 1972 + // Get float array of matrix data 1973 + RMAPI float16 MatrixToFloatV(Matrix mat) { 1974 + float16 result = {0}; 1975 + 1976 + result.v[0] = mat.m0; 1977 + result.v[1] = mat.m1; 1978 + result.v[2] = mat.m2; 1979 + result.v[3] = mat.m3; 1980 + result.v[4] = mat.m4; 1981 + result.v[5] = mat.m5; 1982 + result.v[6] = mat.m6; 1983 + result.v[7] = mat.m7; 1984 + result.v[8] = mat.m8; 1985 + result.v[9] = mat.m9; 1986 + result.v[10] = mat.m10; 1987 + result.v[11] = mat.m11; 1988 + result.v[12] = mat.m12; 1989 + result.v[13] = mat.m13; 1990 + result.v[14] = mat.m14; 1991 + result.v[15] = mat.m15; 1992 + 1993 + return result; 1994 + } 1995 + 1996 + //---------------------------------------------------------------------------------- 1997 + // Module Functions Definition - Quaternion math 1998 + //---------------------------------------------------------------------------------- 1999 + 2000 + // Add two quaternions 2001 + RMAPI Quaternion QuaternionAdd(Quaternion q1, Quaternion q2) { 2002 + Quaternion result = {q1.x + q2.x, q1.y + q2.y, q1.z + q2.z, q1.w + q2.w}; 2003 + 2004 + return result; 2005 + } 2006 + 2007 + // Add quaternion and float value 2008 + RMAPI Quaternion QuaternionAddValue(Quaternion q, float add) { 2009 + Quaternion result = {q.x + add, q.y + add, q.z + add, q.w + add}; 2010 + 2011 + return result; 2012 + } 2013 + 2014 + // Subtract two quaternions 2015 + RMAPI Quaternion QuaternionSubtract(Quaternion q1, Quaternion q2) { 2016 + Quaternion result = {q1.x - q2.x, q1.y - q2.y, q1.z - q2.z, q1.w - q2.w}; 2017 + 2018 + return result; 2019 + } 2020 + 2021 + // Subtract quaternion and float value 2022 + RMAPI Quaternion QuaternionSubtractValue(Quaternion q, float sub) { 2023 + Quaternion result = {q.x - sub, q.y - sub, q.z - sub, q.w - sub}; 2024 + 2025 + return result; 2026 + } 2027 + 2028 + // Get identity quaternion 2029 + RMAPI Quaternion QuaternionIdentity(void) { 2030 + Quaternion result = {0.0f, 0.0f, 0.0f, 1.0f}; 2031 + 2032 + return result; 2033 + } 2034 + 2035 + // Computes the length of a quaternion 2036 + RMAPI float QuaternionLength(Quaternion q) { 2037 + float result = sqrtf(q.x * q.x + q.y * q.y + q.z * q.z + q.w * q.w); 2038 + 2039 + return result; 2040 + } 2041 + 2042 + // Normalize provided quaternion 2043 + RMAPI Quaternion QuaternionNormalize(Quaternion q) { 2044 + Quaternion result = {0}; 2045 + 2046 + float length = sqrtf(q.x * q.x + q.y * q.y + q.z * q.z + q.w * q.w); 2047 + if (length == 0.0f) 2048 + length = 1.0f; 2049 + float ilength = 1.0f / length; 2050 + 2051 + result.x = q.x * ilength; 2052 + result.y = q.y * ilength; 2053 + result.z = q.z * ilength; 2054 + result.w = q.w * ilength; 2055 + 2056 + return result; 2057 + } 2058 + 2059 + // Invert provided quaternion 2060 + RMAPI Quaternion QuaternionInvert(Quaternion q) { 2061 + Quaternion result = q; 2062 + 2063 + float lengthSq = q.x * q.x + q.y * q.y + q.z * q.z + q.w * q.w; 2064 + 2065 + if (lengthSq != 0.0f) { 2066 + float invLength = 1.0f / lengthSq; 2067 + 2068 + result.x *= -invLength; 2069 + result.y *= -invLength; 2070 + result.z *= -invLength; 2071 + result.w *= invLength; 2072 + } 2073 + 2074 + return result; 2075 + } 2076 + 2077 + // Calculate two quaternion multiplication 2078 + RMAPI Quaternion QuaternionMultiply(Quaternion q1, Quaternion q2) { 2079 + Quaternion result = {0}; 2080 + 2081 + float qax = q1.x, qay = q1.y, qaz = q1.z, qaw = q1.w; 2082 + float qbx = q2.x, qby = q2.y, qbz = q2.z, qbw = q2.w; 2083 + 2084 + result.x = qax * qbw + qaw * qbx + qay * qbz - qaz * qby; 2085 + result.y = qay * qbw + qaw * qby + qaz * qbx - qax * qbz; 2086 + result.z = qaz * qbw + qaw * qbz + qax * qby - qay * qbx; 2087 + result.w = qaw * qbw - qax * qbx - qay * qby - qaz * qbz; 2088 + 2089 + return result; 2090 + } 2091 + 2092 + // Scale quaternion by float value 2093 + RMAPI Quaternion QuaternionScale(Quaternion q, float mul) { 2094 + Quaternion result = {0}; 2095 + 2096 + result.x = q.x * mul; 2097 + result.y = q.y * mul; 2098 + result.z = q.z * mul; 2099 + result.w = q.w * mul; 2100 + 2101 + return result; 2102 + } 2103 + 2104 + // Divide two quaternions 2105 + RMAPI Quaternion QuaternionDivide(Quaternion q1, Quaternion q2) { 2106 + Quaternion result = {q1.x / q2.x, q1.y / q2.y, q1.z / q2.z, q1.w / q2.w}; 2107 + 2108 + return result; 2109 + } 2110 + 2111 + // Calculate linear interpolation between two quaternions 2112 + RMAPI Quaternion QuaternionLerp(Quaternion q1, Quaternion q2, float amount) { 2113 + Quaternion result = {0}; 2114 + 2115 + result.x = q1.x + amount * (q2.x - q1.x); 2116 + result.y = q1.y + amount * (q2.y - q1.y); 2117 + result.z = q1.z + amount * (q2.z - q1.z); 2118 + result.w = q1.w + amount * (q2.w - q1.w); 2119 + 2120 + return result; 2121 + } 2122 + 2123 + // Calculate slerp-optimized interpolation between two quaternions 2124 + RMAPI Quaternion QuaternionNlerp(Quaternion q1, Quaternion q2, float amount) { 2125 + Quaternion result = {0}; 2126 + 2127 + // QuaternionLerp(q1, q2, amount) 2128 + result.x = q1.x + amount * (q2.x - q1.x); 2129 + result.y = q1.y + amount * (q2.y - q1.y); 2130 + result.z = q1.z + amount * (q2.z - q1.z); 2131 + result.w = q1.w + amount * (q2.w - q1.w); 2132 + 2133 + // QuaternionNormalize(q); 2134 + Quaternion q = result; 2135 + float length = sqrtf(q.x * q.x + q.y * q.y + q.z * q.z + q.w * q.w); 2136 + if (length == 0.0f) 2137 + length = 1.0f; 2138 + float ilength = 1.0f / length; 2139 + 2140 + result.x = q.x * ilength; 2141 + result.y = q.y * ilength; 2142 + result.z = q.z * ilength; 2143 + result.w = q.w * ilength; 2144 + 2145 + return result; 2146 + } 2147 + 2148 + // Calculates spherical linear interpolation between two quaternions 2149 + RMAPI Quaternion QuaternionSlerp(Quaternion q1, Quaternion q2, float amount) { 2150 + Quaternion result = {0}; 2151 + 2152 + #if !defined(EPSILON) 2153 + #define EPSILON 0.000001f 2154 + #endif 2155 + 2156 + float cosHalfTheta = q1.x * q2.x + q1.y * q2.y + q1.z * q2.z + q1.w * q2.w; 2157 + 2158 + if (cosHalfTheta < 0) { 2159 + q2.x = -q2.x; 2160 + q2.y = -q2.y; 2161 + q2.z = -q2.z; 2162 + q2.w = -q2.w; 2163 + cosHalfTheta = -cosHalfTheta; 2164 + } 2165 + 2166 + if (fabsf(cosHalfTheta) >= 1.0f) 2167 + result = q1; 2168 + else if (cosHalfTheta > 0.95f) 2169 + result = QuaternionNlerp(q1, q2, amount); 2170 + else { 2171 + float halfTheta = acosf(cosHalfTheta); 2172 + float sinHalfTheta = sqrtf(1.0f - cosHalfTheta * cosHalfTheta); 2173 + 2174 + if (fabsf(sinHalfTheta) < EPSILON) { 2175 + result.x = (q1.x * 0.5f + q2.x * 0.5f); 2176 + result.y = (q1.y * 0.5f + q2.y * 0.5f); 2177 + result.z = (q1.z * 0.5f + q2.z * 0.5f); 2178 + result.w = (q1.w * 0.5f + q2.w * 0.5f); 2179 + } else { 2180 + float ratioA = sinf((1 - amount) * halfTheta) / sinHalfTheta; 2181 + float ratioB = sinf(amount * halfTheta) / sinHalfTheta; 2182 + 2183 + result.x = (q1.x * ratioA + q2.x * ratioB); 2184 + result.y = (q1.y * ratioA + q2.y * ratioB); 2185 + result.z = (q1.z * ratioA + q2.z * ratioB); 2186 + result.w = (q1.w * ratioA + q2.w * ratioB); 2187 + } 2188 + } 2189 + 2190 + return result; 2191 + } 2192 + 2193 + // Calculate quaternion cubic spline interpolation using Cubic Hermite Spline 2194 + // algorithm as described in the GLTF 2.0 specification: 2195 + // https://registry.khronos.org/glTF/specs/2.0/glTF-2.0.html#interpolation-cubic 2196 + RMAPI Quaternion QuaternionCubicHermiteSpline(Quaternion q1, 2197 + Quaternion outTangent1, 2198 + Quaternion q2, 2199 + Quaternion inTangent2, float t) { 2200 + float t2 = t * t; 2201 + float t3 = t2 * t; 2202 + float h00 = 2 * t3 - 3 * t2 + 1; 2203 + float h10 = t3 - 2 * t2 + t; 2204 + float h01 = -2 * t3 + 3 * t2; 2205 + float h11 = t3 - t2; 2206 + 2207 + Quaternion p0 = QuaternionScale(q1, h00); 2208 + Quaternion m0 = QuaternionScale(outTangent1, h10); 2209 + Quaternion p1 = QuaternionScale(q2, h01); 2210 + Quaternion m1 = QuaternionScale(inTangent2, h11); 2211 + 2212 + Quaternion result = {0}; 2213 + 2214 + result = QuaternionAdd(p0, m0); 2215 + result = QuaternionAdd(result, p1); 2216 + result = QuaternionAdd(result, m1); 2217 + result = QuaternionNormalize(result); 2218 + 2219 + return result; 2220 + } 2221 + 2222 + // Calculate quaternion based on the rotation from one vector to another 2223 + RMAPI Quaternion QuaternionFromVector3ToVector3(Vector3 from, Vector3 to) { 2224 + Quaternion result = {0}; 2225 + 2226 + float cos2Theta = (from.x * to.x + from.y * to.y + 2227 + from.z * to.z); // Vector3DotProduct(from, to) 2228 + Vector3 cross = {from.y * to.z - from.z * to.y, from.z * to.x - from.x * to.z, 2229 + from.x * to.y - 2230 + from.y * to.x}; // Vector3CrossProduct(from, to) 2231 + 2232 + result.x = cross.x; 2233 + result.y = cross.y; 2234 + result.z = cross.z; 2235 + result.w = 1.0f + cos2Theta; 2236 + 2237 + // QuaternionNormalize(q); 2238 + // NOTE: Normalize to essentially nlerp the original and identity to 0.5 2239 + Quaternion q = result; 2240 + float length = sqrtf(q.x * q.x + q.y * q.y + q.z * q.z + q.w * q.w); 2241 + if (length == 0.0f) 2242 + length = 1.0f; 2243 + float ilength = 1.0f / length; 2244 + 2245 + result.x = q.x * ilength; 2246 + result.y = q.y * ilength; 2247 + result.z = q.z * ilength; 2248 + result.w = q.w * ilength; 2249 + 2250 + return result; 2251 + } 2252 + 2253 + // Get a quaternion for a given rotation matrix 2254 + RMAPI Quaternion QuaternionFromMatrix(Matrix mat) { 2255 + Quaternion result = {0}; 2256 + 2257 + float fourWSquaredMinus1 = mat.m0 + mat.m5 + mat.m10; 2258 + float fourXSquaredMinus1 = mat.m0 - mat.m5 - mat.m10; 2259 + float fourYSquaredMinus1 = mat.m5 - mat.m0 - mat.m10; 2260 + float fourZSquaredMinus1 = mat.m10 - mat.m0 - mat.m5; 2261 + 2262 + int biggestIndex = 0; 2263 + float fourBiggestSquaredMinus1 = fourWSquaredMinus1; 2264 + if (fourXSquaredMinus1 > fourBiggestSquaredMinus1) { 2265 + fourBiggestSquaredMinus1 = fourXSquaredMinus1; 2266 + biggestIndex = 1; 2267 + } 2268 + 2269 + if (fourYSquaredMinus1 > fourBiggestSquaredMinus1) { 2270 + fourBiggestSquaredMinus1 = fourYSquaredMinus1; 2271 + biggestIndex = 2; 2272 + } 2273 + 2274 + if (fourZSquaredMinus1 > fourBiggestSquaredMinus1) { 2275 + fourBiggestSquaredMinus1 = fourZSquaredMinus1; 2276 + biggestIndex = 3; 2277 + } 2278 + 2279 + float biggestVal = sqrtf(fourBiggestSquaredMinus1 + 1.0f) * 0.5f; 2280 + float mult = 0.25f / biggestVal; 2281 + 2282 + switch (biggestIndex) { 2283 + case 0: 2284 + result.w = biggestVal; 2285 + result.x = (mat.m6 - mat.m9) * mult; 2286 + result.y = (mat.m8 - mat.m2) * mult; 2287 + result.z = (mat.m1 - mat.m4) * mult; 2288 + break; 2289 + case 1: 2290 + result.x = biggestVal; 2291 + result.w = (mat.m6 - mat.m9) * mult; 2292 + result.y = (mat.m1 + mat.m4) * mult; 2293 + result.z = (mat.m8 + mat.m2) * mult; 2294 + break; 2295 + case 2: 2296 + result.y = biggestVal; 2297 + result.w = (mat.m8 - mat.m2) * mult; 2298 + result.x = (mat.m1 + mat.m4) * mult; 2299 + result.z = (mat.m6 + mat.m9) * mult; 2300 + break; 2301 + case 3: 2302 + result.z = biggestVal; 2303 + result.w = (mat.m1 - mat.m4) * mult; 2304 + result.x = (mat.m8 + mat.m2) * mult; 2305 + result.y = (mat.m6 + mat.m9) * mult; 2306 + break; 2307 + } 2308 + 2309 + return result; 2310 + } 2311 + 2312 + // Get a matrix for a given quaternion 2313 + RMAPI Matrix QuaternionToMatrix(Quaternion q) { 2314 + Matrix result = { 2315 + 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 2316 + 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f}; // MatrixIdentity() 2317 + 2318 + float a2 = q.x * q.x; 2319 + float b2 = q.y * q.y; 2320 + float c2 = q.z * q.z; 2321 + float ac = q.x * q.z; 2322 + float ab = q.x * q.y; 2323 + float bc = q.y * q.z; 2324 + float ad = q.w * q.x; 2325 + float bd = q.w * q.y; 2326 + float cd = q.w * q.z; 2327 + 2328 + result.m0 = 1 - 2 * (b2 + c2); 2329 + result.m1 = 2 * (ab + cd); 2330 + result.m2 = 2 * (ac - bd); 2331 + 2332 + result.m4 = 2 * (ab - cd); 2333 + result.m5 = 1 - 2 * (a2 + c2); 2334 + result.m6 = 2 * (bc + ad); 2335 + 2336 + result.m8 = 2 * (ac + bd); 2337 + result.m9 = 2 * (bc - ad); 2338 + result.m10 = 1 - 2 * (a2 + b2); 2339 + 2340 + return result; 2341 + } 2342 + 2343 + // Get rotation quaternion for an angle and axis 2344 + // NOTE: Angle must be provided in radians 2345 + RMAPI Quaternion QuaternionFromAxisAngle(Vector3 axis, float angle) { 2346 + Quaternion result = {0.0f, 0.0f, 0.0f, 1.0f}; 2347 + 2348 + float axisLength = sqrtf(axis.x * axis.x + axis.y * axis.y + axis.z * axis.z); 2349 + 2350 + if (axisLength != 0.0f) { 2351 + angle *= 0.5f; 2352 + 2353 + float length = 0.0f; 2354 + float ilength = 0.0f; 2355 + 2356 + // Vector3Normalize(axis) 2357 + length = axisLength; 2358 + if (length == 0.0f) 2359 + length = 1.0f; 2360 + ilength = 1.0f / length; 2361 + axis.x *= ilength; 2362 + axis.y *= ilength; 2363 + axis.z *= ilength; 2364 + 2365 + float sinres = sinf(angle); 2366 + float cosres = cosf(angle); 2367 + 2368 + result.x = axis.x * sinres; 2369 + result.y = axis.y * sinres; 2370 + result.z = axis.z * sinres; 2371 + result.w = cosres; 2372 + 2373 + // QuaternionNormalize(q); 2374 + Quaternion q = result; 2375 + length = sqrtf(q.x * q.x + q.y * q.y + q.z * q.z + q.w * q.w); 2376 + if (length == 0.0f) 2377 + length = 1.0f; 2378 + ilength = 1.0f / length; 2379 + result.x = q.x * ilength; 2380 + result.y = q.y * ilength; 2381 + result.z = q.z * ilength; 2382 + result.w = q.w * ilength; 2383 + } 2384 + 2385 + return result; 2386 + } 2387 + 2388 + // Get the rotation angle and axis for a given quaternion 2389 + RMAPI void QuaternionToAxisAngle(Quaternion q, Vector3 *outAxis, 2390 + float *outAngle) { 2391 + if (fabsf(q.w) > 1.0f) { 2392 + // QuaternionNormalize(q); 2393 + float length = sqrtf(q.x * q.x + q.y * q.y + q.z * q.z + q.w * q.w); 2394 + if (length == 0.0f) 2395 + length = 1.0f; 2396 + float ilength = 1.0f / length; 2397 + 2398 + q.x = q.x * ilength; 2399 + q.y = q.y * ilength; 2400 + q.z = q.z * ilength; 2401 + q.w = q.w * ilength; 2402 + } 2403 + 2404 + Vector3 resAxis = {0.0f, 0.0f, 0.0f}; 2405 + float resAngle = 2.0f * acosf(q.w); 2406 + float den = sqrtf(1.0f - q.w * q.w); 2407 + 2408 + if (den > EPSILON) { 2409 + resAxis.x = q.x / den; 2410 + resAxis.y = q.y / den; 2411 + resAxis.z = q.z / den; 2412 + } else { 2413 + // This occurs when the angle is zero. 2414 + // Not a problem: just set an arbitrary normalized axis. 2415 + resAxis.x = 1.0f; 2416 + } 2417 + 2418 + *outAxis = resAxis; 2419 + *outAngle = resAngle; 2420 + } 2421 + 2422 + // Get the quaternion equivalent to Euler angles 2423 + // NOTE: Rotation order is ZYX 2424 + RMAPI Quaternion QuaternionFromEuler(float pitch, float yaw, float roll) { 2425 + Quaternion result = {0}; 2426 + 2427 + float x0 = cosf(pitch * 0.5f); 2428 + float x1 = sinf(pitch * 0.5f); 2429 + float y0 = cosf(yaw * 0.5f); 2430 + float y1 = sinf(yaw * 0.5f); 2431 + float z0 = cosf(roll * 0.5f); 2432 + float z1 = sinf(roll * 0.5f); 2433 + 2434 + result.x = x1 * y0 * z0 - x0 * y1 * z1; 2435 + result.y = x0 * y1 * z0 + x1 * y0 * z1; 2436 + result.z = x0 * y0 * z1 - x1 * y1 * z0; 2437 + result.w = x0 * y0 * z0 + x1 * y1 * z1; 2438 + 2439 + return result; 2440 + } 2441 + 2442 + // Get the Euler angles equivalent to quaternion (roll, pitch, yaw) 2443 + // NOTE: Angles are returned in a Vector3 struct in radians 2444 + RMAPI Vector3 QuaternionToEuler(Quaternion q) { 2445 + Vector3 result = {0}; 2446 + 2447 + // Roll (x-axis rotation) 2448 + float x0 = 2.0f * (q.w * q.x + q.y * q.z); 2449 + float x1 = 1.0f - 2.0f * (q.x * q.x + q.y * q.y); 2450 + result.x = atan2f(x0, x1); 2451 + 2452 + // Pitch (y-axis rotation) 2453 + float y0 = 2.0f * (q.w * q.y - q.z * q.x); 2454 + y0 = y0 > 1.0f ? 1.0f : y0; 2455 + y0 = y0 < -1.0f ? -1.0f : y0; 2456 + result.y = asinf(y0); 2457 + 2458 + // Yaw (z-axis rotation) 2459 + float z0 = 2.0f * (q.w * q.z + q.x * q.y); 2460 + float z1 = 1.0f - 2.0f * (q.y * q.y + q.z * q.z); 2461 + result.z = atan2f(z0, z1); 2462 + 2463 + return result; 2464 + } 2465 + 2466 + // Transform a quaternion given a transformation matrix 2467 + RMAPI Quaternion QuaternionTransform(Quaternion q, Matrix mat) { 2468 + Quaternion result = {0}; 2469 + 2470 + result.x = mat.m0 * q.x + mat.m4 * q.y + mat.m8 * q.z + mat.m12 * q.w; 2471 + result.y = mat.m1 * q.x + mat.m5 * q.y + mat.m9 * q.z + mat.m13 * q.w; 2472 + result.z = mat.m2 * q.x + mat.m6 * q.y + mat.m10 * q.z + mat.m14 * q.w; 2473 + result.w = mat.m3 * q.x + mat.m7 * q.y + mat.m11 * q.z + mat.m15 * q.w; 2474 + 2475 + return result; 2476 + } 2477 + 2478 + // Check whether two given quaternions are almost equal 2479 + RMAPI int QuaternionEquals(Quaternion p, Quaternion q) { 2480 + #if !defined(EPSILON) 2481 + #define EPSILON 0.000001f 2482 + #endif 2483 + 2484 + int result = (((fabsf(p.x - q.x)) <= 2485 + (EPSILON * fmaxf(1.0f, fmaxf(fabsf(p.x), fabsf(q.x))))) && 2486 + ((fabsf(p.y - q.y)) <= 2487 + (EPSILON * fmaxf(1.0f, fmaxf(fabsf(p.y), fabsf(q.y))))) && 2488 + ((fabsf(p.z - q.z)) <= 2489 + (EPSILON * fmaxf(1.0f, fmaxf(fabsf(p.z), fabsf(q.z))))) && 2490 + ((fabsf(p.w - q.w)) <= 2491 + (EPSILON * fmaxf(1.0f, fmaxf(fabsf(p.w), fabsf(q.w)))))) || 2492 + (((fabsf(p.x + q.x)) <= 2493 + (EPSILON * fmaxf(1.0f, fmaxf(fabsf(p.x), fabsf(q.x))))) && 2494 + ((fabsf(p.y + q.y)) <= 2495 + (EPSILON * fmaxf(1.0f, fmaxf(fabsf(p.y), fabsf(q.y))))) && 2496 + ((fabsf(p.z + q.z)) <= 2497 + (EPSILON * fmaxf(1.0f, fmaxf(fabsf(p.z), fabsf(q.z))))) && 2498 + ((fabsf(p.w + q.w)) <= 2499 + (EPSILON * fmaxf(1.0f, fmaxf(fabsf(p.w), fabsf(q.w)))))); 2500 + 2501 + return result; 2502 + } 2503 + 2504 + // Decompose a transformation matrix into its rotational, translational and 2505 + // scaling components and remove shear 2506 + RMAPI void MatrixDecompose(Matrix mat, Vector3 *translation, 2507 + Quaternion *rotation, Vector3 *scale) { 2508 + float eps = (float)1e-9; 2509 + 2510 + // Extract Translation 2511 + translation->x = mat.m12; 2512 + translation->y = mat.m13; 2513 + translation->z = mat.m14; 2514 + 2515 + // Matrix Columns - Rotation will be extracted into here. 2516 + Vector3 matColumns[3] = {{mat.m0, mat.m4, mat.m8}, 2517 + {mat.m1, mat.m5, mat.m9}, 2518 + {mat.m2, mat.m6, mat.m10}}; 2519 + 2520 + // Shear Parameters XY, XZ, and YZ (extract and ignored) 2521 + float shear[3] = {0}; 2522 + 2523 + // Normalized Scale Parameters 2524 + Vector3 scl = {0}; 2525 + 2526 + // Max-Normalizing helps numerical stability 2527 + float stabilizer = eps; 2528 + for (int i = 0; i < 3; i++) { 2529 + stabilizer = fmaxf(stabilizer, fabsf(matColumns[i].x)); 2530 + stabilizer = fmaxf(stabilizer, fabsf(matColumns[i].y)); 2531 + stabilizer = fmaxf(stabilizer, fabsf(matColumns[i].z)); 2532 + }; 2533 + matColumns[0] = Vector3Scale(matColumns[0], 1.0f / stabilizer); 2534 + matColumns[1] = Vector3Scale(matColumns[1], 1.0f / stabilizer); 2535 + matColumns[2] = Vector3Scale(matColumns[2], 1.0f / stabilizer); 2536 + 2537 + // X Scale 2538 + scl.x = Vector3Length(matColumns[0]); 2539 + if (scl.x > eps) { 2540 + matColumns[0] = Vector3Scale(matColumns[0], 1.0f / scl.x); 2541 + } 2542 + 2543 + // Compute XY shear and make col2 orthogonal 2544 + shear[0] = Vector3DotProduct(matColumns[0], matColumns[1]); 2545 + matColumns[1] = 2546 + Vector3Subtract(matColumns[1], Vector3Scale(matColumns[0], shear[0])); 2547 + 2548 + // Y Scale 2549 + scl.y = Vector3Length(matColumns[1]); 2550 + if (scl.y > eps) { 2551 + matColumns[1] = Vector3Scale(matColumns[1], 1.0f / scl.y); 2552 + shear[0] /= scl.y; // Correct XY shear 2553 + } 2554 + 2555 + // Compute XZ and YZ shears and make col3 orthogonal 2556 + shear[1] = Vector3DotProduct(matColumns[0], matColumns[2]); 2557 + matColumns[2] = 2558 + Vector3Subtract(matColumns[2], Vector3Scale(matColumns[0], shear[1])); 2559 + shear[2] = Vector3DotProduct(matColumns[1], matColumns[2]); 2560 + matColumns[2] = 2561 + Vector3Subtract(matColumns[2], Vector3Scale(matColumns[1], shear[2])); 2562 + 2563 + // Z Scale 2564 + scl.z = Vector3Length(matColumns[2]); 2565 + if (scl.z > eps) { 2566 + matColumns[2] = Vector3Scale(matColumns[2], 1.0f / scl.z); 2567 + shear[1] /= scl.z; // Correct XZ shear 2568 + shear[2] /= scl.z; // Correct YZ shear 2569 + } 2570 + 2571 + // matColumns are now orthonormal in O(3). Now ensure its in SO(3) by 2572 + // enforcing det = 1. 2573 + if (Vector3DotProduct(matColumns[0], Vector3CrossProduct( 2574 + matColumns[1], matColumns[2])) < 0) { 2575 + scl = Vector3Negate(scl); 2576 + matColumns[0] = Vector3Negate(matColumns[0]); 2577 + matColumns[1] = Vector3Negate(matColumns[1]); 2578 + matColumns[2] = Vector3Negate(matColumns[2]); 2579 + } 2580 + 2581 + // Set Scale 2582 + *scale = Vector3Scale(scl, stabilizer); 2583 + 2584 + // Extract Rotation 2585 + Matrix rotationMatrix = {matColumns[0].x, 2586 + matColumns[0].y, 2587 + matColumns[0].z, 2588 + 0, 2589 + matColumns[1].x, 2590 + matColumns[1].y, 2591 + matColumns[1].z, 2592 + 0, 2593 + matColumns[2].x, 2594 + matColumns[2].y, 2595 + matColumns[2].z, 2596 + 0, 2597 + 0, 2598 + 0, 2599 + 0, 2600 + 1}; 2601 + *rotation = QuaternionFromMatrix(rotationMatrix); 2602 + } 2603 + 2604 + #if defined(__cplusplus) && !defined(RAYMATH_DISABLE_CPP_OPERATORS) 2605 + 2606 + // Optional C++ math operators 2607 + //------------------------------------------------------------------------------- 2608 + 2609 + // Vector2 operators 2610 + static constexpr Vector2 Vector2Zeros = {0, 0}; 2611 + static constexpr Vector2 Vector2Ones = {1, 1}; 2612 + static constexpr Vector2 Vector2UnitX = {1, 0}; 2613 + static constexpr Vector2 Vector2UnitY = {0, 1}; 2614 + 2615 + inline Vector2 operator+(const Vector2 &lhs, const Vector2 &rhs) { 2616 + return Vector2Add(lhs, rhs); 2617 + } 2618 + 2619 + inline const Vector2 &operator+=(Vector2 &lhs, const Vector2 &rhs) { 2620 + lhs = Vector2Add(lhs, rhs); 2621 + return lhs; 2622 + } 2623 + 2624 + inline Vector2 operator-(const Vector2 &lhs, const Vector2 &rhs) { 2625 + return Vector2Subtract(lhs, rhs); 2626 + } 2627 + 2628 + inline const Vector2 &operator-=(Vector2 &lhs, const Vector2 &rhs) { 2629 + lhs = Vector2Subtract(lhs, rhs); 2630 + return lhs; 2631 + } 2632 + 2633 + inline Vector2 operator*(const Vector2 &lhs, const float &rhs) { 2634 + return Vector2Scale(lhs, rhs); 2635 + } 2636 + 2637 + inline const Vector2 &operator*=(Vector2 &lhs, const float &rhs) { 2638 + lhs = Vector2Scale(lhs, rhs); 2639 + return lhs; 2640 + } 2641 + 2642 + inline Vector2 operator*(const Vector2 &lhs, const Vector2 &rhs) { 2643 + return Vector2Multiply(lhs, rhs); 2644 + } 2645 + 2646 + inline const Vector2 &operator*=(Vector2 &lhs, const Vector2 &rhs) { 2647 + lhs = Vector2Multiply(lhs, rhs); 2648 + return lhs; 2649 + } 2650 + 2651 + inline Vector2 operator*(const Vector2 &lhs, const Matrix &rhs) { 2652 + return Vector2Transform(lhs, rhs); 2653 + } 2654 + 2655 + inline const Vector2 &operator*=(Vector2 &lhs, const Matrix &rhs) { 2656 + lhs = Vector2Transform(lhs, rhs); 2657 + return lhs; 2658 + } 2659 + 2660 + inline Vector2 operator/(const Vector2 &lhs, const float &rhs) { 2661 + return Vector2Scale(lhs, 1.0f / rhs); 2662 + } 2663 + 2664 + inline const Vector2 &operator/=(Vector2 &lhs, const float &rhs) { 2665 + lhs = Vector2Scale(lhs, 1.0f / rhs); 2666 + return lhs; 2667 + } 2668 + 2669 + inline Vector2 operator/(const Vector2 &lhs, const Vector2 &rhs) { 2670 + return Vector2Divide(lhs, rhs); 2671 + } 2672 + 2673 + inline const Vector2 &operator/=(Vector2 &lhs, const Vector2 &rhs) { 2674 + lhs = Vector2Divide(lhs, rhs); 2675 + return lhs; 2676 + } 2677 + 2678 + inline bool operator==(const Vector2 &lhs, const Vector2 &rhs) { 2679 + return FloatEquals(lhs.x, rhs.x) && FloatEquals(lhs.y, rhs.y); 2680 + } 2681 + 2682 + inline bool operator!=(const Vector2 &lhs, const Vector2 &rhs) { 2683 + return !FloatEquals(lhs.x, rhs.x) || !FloatEquals(lhs.y, rhs.y); 2684 + } 2685 + 2686 + // Vector3 operators 2687 + static constexpr Vector3 Vector3Zeros = {0, 0, 0}; 2688 + static constexpr Vector3 Vector3Ones = {1, 1, 1}; 2689 + static constexpr Vector3 Vector3UnitX = {1, 0, 0}; 2690 + static constexpr Vector3 Vector3UnitY = {0, 1, 0}; 2691 + static constexpr Vector3 Vector3UnitZ = {0, 0, 1}; 2692 + 2693 + inline Vector3 operator+(const Vector3 &lhs, const Vector3 &rhs) { 2694 + return Vector3Add(lhs, rhs); 2695 + } 2696 + 2697 + inline const Vector3 &operator+=(Vector3 &lhs, const Vector3 &rhs) { 2698 + lhs = Vector3Add(lhs, rhs); 2699 + return lhs; 2700 + } 2701 + 2702 + inline Vector3 operator-(const Vector3 &lhs, const Vector3 &rhs) { 2703 + return Vector3Subtract(lhs, rhs); 2704 + } 2705 + 2706 + inline const Vector3 &operator-=(Vector3 &lhs, const Vector3 &rhs) { 2707 + lhs = Vector3Subtract(lhs, rhs); 2708 + return lhs; 2709 + } 2710 + 2711 + inline Vector3 operator*(const Vector3 &lhs, const float &rhs) { 2712 + return Vector3Scale(lhs, rhs); 2713 + } 2714 + 2715 + inline const Vector3 &operator*=(Vector3 &lhs, const float &rhs) { 2716 + lhs = Vector3Scale(lhs, rhs); 2717 + return lhs; 2718 + } 2719 + 2720 + inline Vector3 operator*(const Vector3 &lhs, const Vector3 &rhs) { 2721 + return Vector3Multiply(lhs, rhs); 2722 + } 2723 + 2724 + inline const Vector3 &operator*=(Vector3 &lhs, const Vector3 &rhs) { 2725 + lhs = Vector3Multiply(lhs, rhs); 2726 + return lhs; 2727 + } 2728 + 2729 + inline Vector3 operator*(const Vector3 &lhs, const Matrix &rhs) { 2730 + return Vector3Transform(lhs, rhs); 2731 + } 2732 + 2733 + inline const Vector3 &operator*=(Vector3 &lhs, const Matrix &rhs) { 2734 + lhs = Vector3Transform(lhs, rhs); 2735 + return lhs; 2736 + } 2737 + 2738 + inline Vector3 operator/(const Vector3 &lhs, const float &rhs) { 2739 + return Vector3Scale(lhs, 1.0f / rhs); 2740 + } 2741 + 2742 + inline const Vector3 &operator/=(Vector3 &lhs, const float &rhs) { 2743 + lhs = Vector3Scale(lhs, 1.0f / rhs); 2744 + return lhs; 2745 + } 2746 + 2747 + inline Vector3 operator/(const Vector3 &lhs, const Vector3 &rhs) { 2748 + return Vector3Divide(lhs, rhs); 2749 + } 2750 + 2751 + inline const Vector3 &operator/=(Vector3 &lhs, const Vector3 &rhs) { 2752 + lhs = Vector3Divide(lhs, rhs); 2753 + return lhs; 2754 + } 2755 + 2756 + inline bool operator==(const Vector3 &lhs, const Vector3 &rhs) { 2757 + return FloatEquals(lhs.x, rhs.x) && FloatEquals(lhs.y, rhs.y) && 2758 + FloatEquals(lhs.z, rhs.z); 2759 + } 2760 + 2761 + inline bool operator!=(const Vector3 &lhs, const Vector3 &rhs) { 2762 + return !FloatEquals(lhs.x, rhs.x) || !FloatEquals(lhs.y, rhs.y) || 2763 + !FloatEquals(lhs.z, rhs.z); 2764 + } 2765 + 2766 + // Vector4 operators 2767 + static constexpr Vector4 Vector4Zeros = {0, 0, 0, 0}; 2768 + static constexpr Vector4 Vector4Ones = {1, 1, 1, 1}; 2769 + static constexpr Vector4 Vector4UnitX = {1, 0, 0, 0}; 2770 + static constexpr Vector4 Vector4UnitY = {0, 1, 0, 0}; 2771 + static constexpr Vector4 Vector4UnitZ = {0, 0, 1, 0}; 2772 + static constexpr Vector4 Vector4UnitW = {0, 0, 0, 1}; 2773 + 2774 + inline Vector4 operator+(const Vector4 &lhs, const Vector4 &rhs) { 2775 + return Vector4Add(lhs, rhs); 2776 + } 2777 + 2778 + inline const Vector4 &operator+=(Vector4 &lhs, const Vector4 &rhs) { 2779 + lhs = Vector4Add(lhs, rhs); 2780 + return lhs; 2781 + } 2782 + 2783 + inline Vector4 operator-(const Vector4 &lhs, const Vector4 &rhs) { 2784 + return Vector4Subtract(lhs, rhs); 2785 + } 2786 + 2787 + inline const Vector4 &operator-=(Vector4 &lhs, const Vector4 &rhs) { 2788 + lhs = Vector4Subtract(lhs, rhs); 2789 + return lhs; 2790 + } 2791 + 2792 + inline Vector4 operator*(const Vector4 &lhs, const float &rhs) { 2793 + return Vector4Scale(lhs, rhs); 2794 + } 2795 + 2796 + inline const Vector4 &operator*=(Vector4 &lhs, const float &rhs) { 2797 + lhs = Vector4Scale(lhs, rhs); 2798 + return lhs; 2799 + } 2800 + 2801 + inline Vector4 operator*(const Vector4 &lhs, const Vector4 &rhs) { 2802 + return Vector4Multiply(lhs, rhs); 2803 + } 2804 + 2805 + inline const Vector4 &operator*=(Vector4 &lhs, const Vector4 &rhs) { 2806 + lhs = Vector4Multiply(lhs, rhs); 2807 + return lhs; 2808 + } 2809 + 2810 + inline Vector4 operator/(const Vector4 &lhs, const float &rhs) { 2811 + return Vector4Scale(lhs, 1.0f / rhs); 2812 + } 2813 + 2814 + inline const Vector4 &operator/=(Vector4 &lhs, const float &rhs) { 2815 + lhs = Vector4Scale(lhs, 1.0f / rhs); 2816 + return lhs; 2817 + } 2818 + 2819 + inline Vector4 operator/(const Vector4 &lhs, const Vector4 &rhs) { 2820 + return Vector4Divide(lhs, rhs); 2821 + } 2822 + 2823 + inline const Vector4 &operator/=(Vector4 &lhs, const Vector4 &rhs) { 2824 + lhs = Vector4Divide(lhs, rhs); 2825 + return lhs; 2826 + } 2827 + 2828 + inline bool operator==(const Vector4 &lhs, const Vector4 &rhs) { 2829 + return FloatEquals(lhs.x, rhs.x) && FloatEquals(lhs.y, rhs.y) && 2830 + FloatEquals(lhs.z, rhs.z) && FloatEquals(lhs.w, rhs.w); 2831 + } 2832 + 2833 + inline bool operator!=(const Vector4 &lhs, const Vector4 &rhs) { 2834 + return !FloatEquals(lhs.x, rhs.x) || !FloatEquals(lhs.y, rhs.y) || 2835 + !FloatEquals(lhs.z, rhs.z) || !FloatEquals(lhs.w, rhs.w); 2836 + } 2837 + 2838 + // Quaternion operators 2839 + static constexpr Quaternion QuaternionZeros = {0, 0, 0, 0}; 2840 + static constexpr Quaternion QuaternionOnes = {1, 1, 1, 1}; 2841 + static constexpr Quaternion QuaternionUnitX = {0, 0, 0, 1}; 2842 + 2843 + inline Quaternion operator+(const Quaternion &lhs, const float &rhs) { 2844 + return QuaternionAddValue(lhs, rhs); 2845 + } 2846 + 2847 + inline const Quaternion &operator+=(Quaternion &lhs, const float &rhs) { 2848 + lhs = QuaternionAddValue(lhs, rhs); 2849 + return lhs; 2850 + } 2851 + 2852 + inline Quaternion operator-(const Quaternion &lhs, const float &rhs) { 2853 + return QuaternionSubtractValue(lhs, rhs); 2854 + } 2855 + 2856 + inline const Quaternion &operator-=(Quaternion &lhs, const float &rhs) { 2857 + lhs = QuaternionSubtractValue(lhs, rhs); 2858 + return lhs; 2859 + } 2860 + 2861 + inline Quaternion operator*(const Quaternion &lhs, const Matrix &rhs) { 2862 + return QuaternionTransform(lhs, rhs); 2863 + } 2864 + 2865 + inline const Quaternion &operator*=(Quaternion &lhs, const Matrix &rhs) { 2866 + lhs = QuaternionTransform(lhs, rhs); 2867 + return lhs; 2868 + } 2869 + 2870 + // Matrix operators 2871 + inline Matrix operator+(const Matrix &lhs, const Matrix &rhs) { 2872 + return MatrixAdd(lhs, rhs); 2873 + } 2874 + 2875 + inline const Matrix &operator+=(Matrix &lhs, const Matrix &rhs) { 2876 + lhs = MatrixAdd(lhs, rhs); 2877 + return lhs; 2878 + } 2879 + 2880 + inline Matrix operator-(const Matrix &lhs, const Matrix &rhs) { 2881 + return MatrixSubtract(lhs, rhs); 2882 + } 2883 + 2884 + inline const Matrix &operator-=(Matrix &lhs, const Matrix &rhs) { 2885 + lhs = MatrixSubtract(lhs, rhs); 2886 + return lhs; 2887 + } 2888 + 2889 + inline Matrix operator*(const Matrix &lhs, const Matrix &rhs) { 2890 + return MatrixMultiply(lhs, rhs); 2891 + } 2892 + 2893 + inline const Matrix &operator*=(Matrix &lhs, const Matrix &rhs) { 2894 + lhs = MatrixMultiply(lhs, rhs); 2895 + return lhs; 2896 + } 2897 + //------------------------------------------------------------------------------- 2898 + #endif // C++ operators 2899 + 2900 + #endif // RAYMATH_H
+54
src/animated_texture.c
··· 1 + #include "../include/animated_texture.h" 2 + #include <stdlib.h> 3 + 4 + AnimatedTexture animated_texture_create( 5 + const char *file_path, int number_of_frames, float speed 6 + ) { 7 + Texture2D texture = LoadTexture(file_path); 8 + 9 + Rectangle current_frame = { 0, 0, texture.width / (float)number_of_frames, texture.height }; 10 + 11 + return (AnimatedTexture){ 12 + .number_of_frames = number_of_frames, 13 + .current_frame = current_frame, 14 + .duration_left = 1.0f, 15 + .speed = speed, 16 + .texture = texture 17 + }; 18 + } 19 + 20 + int animated_texture_delete(AnimatedTexture animated_texture) { 21 + UnloadTexture(animated_texture.texture); 22 + 23 + return EXIT_SUCCESS; 24 + } 25 + 26 + void animated_texture_update(AnimatedTexture *animated_texture) { 27 + float delta_time = GetFrameTime(); 28 + animated_texture->duration_left -= delta_time * animated_texture->speed; 29 + 30 + if (animated_texture->duration_left > 0.0) 31 + return; 32 + 33 + animated_texture->duration_left = 1.0f; 34 + 35 + Rectangle next_frame = { 36 + ((int)animated_texture->current_frame.x 37 + + (int)animated_texture->current_frame.width) 38 + % animated_texture->texture.width, 39 + 0, animated_texture->current_frame.width, 40 + animated_texture->current_frame.height 41 + }; 42 + 43 + animated_texture->current_frame = next_frame; 44 + } 45 + 46 + void animated_texture_draw( 47 + AnimatedTexture *animated_texture, Vector2 position, Color tint 48 + ) { 49 + Rectangle dest = { position.x, position.y, animated_texture->current_frame.width, animated_texture->current_frame.height }; 50 + 51 + DrawTexturePro( 52 + animated_texture->texture, animated_texture->current_frame, dest, (Vector2){ 0, 0 }, 0.0f, tint 53 + ); 54 + }
+31
src/main.c
··· 1 + #include "../include/config.h" 2 + #include "../include/player.h" 3 + #include "../include/raylib.h" 4 + #include <stdlib.h> 5 + 6 + int main() { 7 + InitWindow(WINDOW_WIDTH, WINDOW_HEIGHT, "RPG"); 8 + SetTargetFPS(60); 9 + 10 + Player *player = player_create(0, 0); 11 + 12 + while (!WindowShouldClose()) { 13 + player_update(player); 14 + 15 + BeginDrawing(); 16 + 17 + ClearBackground(WHITE); 18 + 19 + BeginMode2D(player->camera); 20 + 21 + player_draw(player); 22 + 23 + EndMode2D(); 24 + 25 + EndDrawing(); 26 + } 27 + 28 + player_destroy(player); 29 + CloseWindow(); 30 + return EXIT_SUCCESS; 31 + }
+94
src/player.c
··· 1 + #include "../include/player.h" 2 + #include "../include/animated_texture.h" 3 + #include "../include/config.h" 4 + #include "../include/player_state/default.h" 5 + #include "../include/raylib.h" 6 + #include "../include/raymath.h" 7 + #include <stdio.h> 8 + #include <stdlib.h> 9 + 10 + #define PLAYER_FRICTION 0.69f 11 + 12 + Player *player_create(float x, float y) { 13 + Player *player = (Player *)malloc(sizeof(Player)); 14 + 15 + player->textures[PLAYER_TEXTURE_FALLING] = animated_texture_create("assets/textures/player/falling.png", 4, 0.3f); 16 + 17 + player->textures[PLAYER_TEXTURE_FORWARD] = animated_texture_create( 18 + "assets/textures/player/stand-forward.png", 1, 0.0f 19 + ); 20 + 21 + player->textures[PLAYER_TEXTURE_WALK_FORWARD] = animated_texture_create( 22 + "assets/textures/player/walk-forward.png", 2, 0.3f 23 + ); 24 + 25 + player->textures[PLAYER_TEXTURE_WALK_BACKWARD] = animated_texture_create( 26 + "assets/textures/player/walk-backward.png", 2, 0.3f 27 + ); 28 + 29 + player->textures[PLAYER_TEXTURE_WALK_LEFT] = animated_texture_create("assets/textures/player/walk-left.png", 2, 0.3f); 30 + 31 + player->textures[PLAYER_TEXTURE_WALK_RIGHT] = animated_texture_create("assets/textures/player/walk-right.png", 2, 0.3f); 32 + 33 + for (int i = 0; i < _PLAYER_TEXTURE_LENGTH; i++) { 34 + if (player->textures[i].texture.id == 0) { 35 + perror("Failed to load player sprites!\n"); 36 + free(player); 37 + CloseWindow(); 38 + 39 + return NULL; 40 + } 41 + } 42 + 43 + player->camera = (Camera2D){ 0 }; 44 + player->camera.zoom = 4.0f; 45 + player->camera.offset = (Vector2){ WINDOW_WIDTH / 2.0f, WINDOW_HEIGHT / 2.0f }; 46 + 47 + player_state_transition_to_default(&player->state, player); 48 + 49 + player->position.x = x; 50 + player->position.y = y; 51 + 52 + player->velocity = Vector2Zero(); 53 + player->control = Vector2Zero(); 54 + player->speed = 12.0f; 55 + player->friction = 0.69f; 56 + 57 + return player; 58 + } 59 + 60 + int player_destroy(Player *player) { 61 + for (int i = 0; i < _PLAYER_TEXTURE_LENGTH; i++) { 62 + animated_texture_delete(player->textures[i]); 63 + } 64 + 65 + free(player); 66 + 67 + return EXIT_SUCCESS; 68 + } 69 + 70 + Vector2 player_center(Player *player) { 71 + return (Vector2){ player->position.x + 8, player->position.y + 8 }; 72 + } 73 + 74 + void player_draw(Player *player) { 75 + DrawRectangleV(player->position, (Vector2){ 16, 16 }, player->color); 76 + 77 + DrawText(player->state.name, 0, 0, 20, BLACK); 78 + 79 + animated_texture_draw(&player->texture, player->position, WHITE); 80 + 81 + Vector2 center = player_center(player); 82 + Vector2 velocity_from_position = { 83 + center.x + player->velocity.x, center.y + player->velocity.y 84 + }; 85 + DrawLineEx(center, velocity_from_position, 1.0f, GREEN); 86 + } 87 + 88 + void player_update(Player *player) { 89 + if (player->state.update) { 90 + player->state.update(&player->state, player); 91 + } 92 + 93 + player->camera.target = player_center(player); 94 + }
+38
src/player_state/default.c
··· 1 + #include "../../include/player_state/default.h" 2 + 3 + #include "../../include/player_state/walk.h" 4 + 5 + #include "../../include/player.h" 6 + #include "../../include/raylib.h" 7 + 8 + static void player_state_default_update(PlayerState *state, Player *player) 9 + { 10 + if (IsKeyPressed(KEY_UP)) 11 + { 12 + player_state_transition_to_walk(&player->state, player); 13 + } 14 + 15 + if (IsKeyPressed(KEY_DOWN)) 16 + { 17 + player_state_transition_to_walk(&player->state, player); 18 + } 19 + 20 + if (IsKeyPressed(KEY_LEFT)) 21 + { 22 + player_state_transition_to_walk(&player->state, player); 23 + } 24 + 25 + if (IsKeyPressed(KEY_RIGHT)) 26 + { 27 + player_state_transition_to_walk(&player->state, player); 28 + } 29 + } 30 + 31 + void player_state_transition_to_default(PlayerState *state, Player *player) 32 + { 33 + state->name = "Default"; 34 + state->update = player_state_default_update; 35 + 36 + player->velocity = Vector2Zero(); 37 + player->texture = player->textures[PLAYER_TEXTURE_FORWARD]; 38 + }
+20
src/player_state/fall.c
··· 1 + #include "../../include/player_state/fall.h" 2 + 3 + #include "../../include/player.h" 4 + #include "../../include/raylib.h" 5 + 6 + static void player_state_fall_update(PlayerState *state, Player *player) 7 + { 8 + // if (IsKeyPressed(KEY_RIGHT)) 9 + // { 10 + // state->update = player_state_transition_to_walk_right; 11 + // } 12 + } 13 + 14 + void player_state_transition_to_fall(PlayerState *state, Player *player) 15 + { 16 + state->name = "Fall"; 17 + state->update = player_state_fall_update; 18 + 19 + player->speed = 0; 20 + }
+20
src/player_state/run.c
··· 1 + #include "../../include/player_state/run.h" 2 + 3 + #include "../../include/player.h" 4 + #include "../../include/raylib.h" 5 + 6 + static void player_state_run_update(PlayerState *state, Player *player) 7 + { 8 + // if (IsKeyPressed(KEY_RIGHT)) 9 + // { 10 + // state->update = player_state_transition_to_walk_right; 11 + // } 12 + } 13 + 14 + void player_state_transition_to_run(PlayerState *state, Player *player) 15 + { 16 + state->name = "Run"; 17 + state->update = player_state_run_update; 18 + 19 + player->speed = 24.0f; 20 + }
+82
src/player_state/walk.c
··· 1 + #include "../../include/player_state/walk.h" 2 + 3 + #include "../../include/player_state/default.h" 4 + 5 + #include "../../include/player.h" 6 + #include "../../include/raylib.h" 7 + 8 + static void player_state_walk_update(PlayerState *state, Player *player) 9 + { 10 + if (IsKeyDown(KEY_LEFT_SHIFT)) 11 + { 12 + player->speed = 24.0f; 13 + } 14 + else 15 + { 16 + player->speed = 12.0f; 17 + } 18 + 19 + if (IsKeyDown(KEY_UP)) 20 + { 21 + player->texture = player->textures[PLAYER_TEXTURE_WALK_BACKWARD]; 22 + } 23 + else if (IsKeyDown(KEY_DOWN)) 24 + { 25 + player->texture = player->textures[PLAYER_TEXTURE_WALK_FORWARD]; 26 + } 27 + else if (IsKeyDown(KEY_RIGHT)) 28 + { 29 + player->texture = player->textures[PLAYER_TEXTURE_WALK_RIGHT]; 30 + } 31 + else if (IsKeyDown(KEY_LEFT)) 32 + { 33 + player->texture = player->textures[PLAYER_TEXTURE_WALK_LEFT]; 34 + } 35 + 36 + if (IsKeyDown(KEY_RIGHT)) 37 + { 38 + player->control.x = 1; 39 + } 40 + else if (IsKeyDown(KEY_LEFT)) 41 + { 42 + player->control.x = -1; 43 + } 44 + else 45 + { 46 + player->control.x = 0; 47 + } 48 + 49 + if (IsKeyDown(KEY_DOWN)) 50 + { 51 + player->control.y = 1; 52 + } 53 + else if (IsKeyDown(KEY_UP)) 54 + { 55 + player->control.y = -1; 56 + } 57 + else 58 + { 59 + player->control.y = 0; 60 + } 61 + 62 + Vector2 normalized = Vector2Normalize(player->control); 63 + 64 + player->velocity = Vector2Add( 65 + player->velocity, Vector2Scale(normalized, player->speed)); 66 + 67 + player->position.x += player->velocity.x * GetFrameTime(); 68 + player->position.y += player->velocity.y * GetFrameTime(); 69 + 70 + player->velocity = Vector2Scale(player->velocity, player->friction); 71 + 72 + if (Vector2Length(player->velocity) < 0.1f) 73 + { 74 + player_state_transition_to_default(state, player); 75 + } 76 + } 77 + 78 + void player_state_transition_to_walk(PlayerState *state, Player *player) 79 + { 80 + state->name = "Walk"; 81 + state->update = player_state_walk_update; 82 + }