├── .gitattributes ├── .gitignore ├── LICENSE ├── Makefile ├── README.md ├── bin └── build_osx ├── lib ├── particle.h ├── raylib.h ├── raymath.h ├── spring.h └── stb_perlin.h └── src └── main.cpp /.gitattributes: -------------------------------------------------------------------------------- 1 | # Auto detect text files and perform LF normalization 2 | * text=auto 3 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Prerequisites 2 | *.d 3 | 4 | # Compiled Object files 5 | *.slo 6 | *.lo 7 | *.o 8 | *.obj 9 | 10 | # Precompiled Headers 11 | *.gch 12 | *.pch 13 | 14 | # Compiled Dynamic libraries 15 | *.so 16 | *.dylib 17 | *.dll 18 | 19 | # Fortran module files 20 | *.mod 21 | *.smod 22 | 23 | # Compiled Static libraries 24 | *.lai 25 | *.la 26 | *.a 27 | *.lib 28 | 29 | # Executables 30 | *.exe 31 | *.out 32 | *.app 33 | 34 | .vscode/* 35 | 36 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2022 sc21sv 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | COMPILER = clang++ 2 | SOURCE_LIBS = -Ilib/ 3 | OSX_OPT = -std=c++17 -Llib/ -framework CoreVideo -framework IOKit -framework Cocoa -framework GLUT -framework OpenGL lib/libraylib.a 4 | OSX_OUT = -o "bin/build_osx" 5 | CFILES = src/*.cpp 6 | 7 | build_osx: 8 | $(COMPILER) $(CFILES) $(SOURCE_LIBS) $(OSX_OUT) $(OSX_OPT) -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Simple Cloth Simulation 2 | Made with c++ and raylib (Truly awesome library) 3 | You can run the program by double clicking app in the bin. Currentlly, it only works for mac users (however, you can make your own makefile). 4 | 5 | Custom Cloth simulation that was created using c++ and raylib. 6 | The cloth simulation is done by following Hooke's law (F = -k * x): 7 | 1. Create spring 8 | 2. Join springs into system 9 | 3. Enjoy cloth 10 | 11 | # Controls 12 | Right click: Grab rope 13 | 14 | Left Click: Cut rope 15 | 16 | Screenshot 2022-10-22 at 23 36 35 17 | 18 | Screenshot 2022-10-22 at 23 36 46 19 | 20 | Screenshot 2022-10-22 at 23 37 02 21 | 22 | Screenshot 2022-10-22 at 23 46 23 23 | -------------------------------------------------------------------------------- /bin/build_osx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Biebras/Simple-Cloth-Simulation/8a7f31bb2e0c821caf6604ddadf6293c7d55a017/bin/build_osx -------------------------------------------------------------------------------- /lib/particle.h: -------------------------------------------------------------------------------- 1 | #ifndef PARTICLE_H 2 | #define PARTICLE_H 3 | 4 | #include 5 | #include "raylib.h" 6 | #include "raymath.h" 7 | 8 | using namespace std; 9 | 10 | class Particle 11 | { 12 | public: 13 | Particle(); 14 | Particle(float posX, float posY, bool staticParticles = false); 15 | ~Particle(); 16 | void Update(); 17 | void Draw(); 18 | void SetPosition(float posX, float posY); 19 | Vector2 GetPosition(); 20 | void AddForce(Vector2 force); 21 | private: 22 | Vector2 _position = Vector2Zero(); 23 | Vector2 _accelaration = Vector2Zero(); 24 | Vector2 _velocity = Vector2Zero(); 25 | float _mass; 26 | //Can particle move or not 27 | bool _static; 28 | 29 | //draw variables 30 | Color _color; 31 | float _particleRadius; 32 | }; 33 | 34 | Particle::Particle() 35 | { 36 | Particle(0, 0); 37 | } 38 | 39 | Particle::Particle(float posX, float posY, bool staticParticles) 40 | { 41 | _position = {posX, posY}; 42 | _accelaration = Vector2Zero(); 43 | _velocity = Vector2Zero(); 44 | _mass = 10; 45 | _static = staticParticles; 46 | 47 | _particleRadius = 5; 48 | //If static set color to maroon else darkblue 49 | _color = _static == true ? MAROON : DARKBLUE; 50 | } 51 | 52 | Particle::~Particle(){} 53 | 54 | //Add force to particle 55 | void Particle::AddForce(Vector2 force) 56 | { 57 | //if particle is static, don't add force 58 | if(_static) 59 | return; 60 | 61 | //calculate how velocity is change by applied force 62 | Vector2 newForce = Vector2Scale(force, 1/_mass); 63 | _accelaration = Vector2Add(_accelaration, newForce); 64 | } 65 | 66 | //update players location 67 | void Particle::Update() 68 | { 69 | //if particle is static, don't update 70 | if(_static) 71 | return; 72 | 73 | //.95, we lose 5% of our velocity every frame, thus faking drag 74 | _velocity = Vector2Scale(_velocity, 0.95); 75 | //Update velocity 76 | _velocity = Vector2Add(_velocity, _accelaration); 77 | //update position 78 | _position = Vector2Add(_position, _velocity); 79 | //reset accelaration as we already added it 80 | _accelaration = Vector2Zero(); 81 | } 82 | 83 | //Set particle position 84 | void Particle::SetPosition(float posX, float posY) 85 | { 86 | _velocity = Vector2Zero(); 87 | _position = {posX, posY}; 88 | } 89 | 90 | //Get particle position 91 | Vector2 Particle::GetPosition() 92 | { 93 | return _position; 94 | } 95 | 96 | //Draw particles 97 | void Particle::Draw() 98 | { 99 | DrawCircleV(_position, _particleRadius, _color); 100 | } 101 | 102 | #endif -------------------------------------------------------------------------------- /lib/raylib.h: -------------------------------------------------------------------------------- 1 | /********************************************************************************************** 2 | * 3 | * raylib v4.2 - 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 or ES2 - choose at compile) 11 | * - Unique OpenGL abstraction layer (usable as standalone module): [rlgl] 12 | * - Multiple Fonts formats supported (TTF, XNA fonts, AngelCode 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) 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, 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] rglfw (Camilla Löwy - github.com/glfw/glfw) for window/context management and input (PLATFORM_DESKTOP) 31 | * [rlgl] glad (David Herberth - github.com/Dav1dde/glad) for OpenGL 3.3 extensions loading (PLATFORM_DESKTOP) 32 | * [raudio] miniaudio (David Reid - github.com/mackron/miniaudio) for audio device/context management 33 | * 34 | * OPTIONAL DEPENDENCIES (included): 35 | * [rcore] msf_gif (Miles Fogle) for GIF recording 36 | * [rcore] sinfl (Micha Mettke) for DEFLATE decompression algorithm 37 | * [rcore] sdefl (Micha Mettke) for DEFLATE compression algorithm 38 | * [rtextures] stb_image (Sean Barret) for images loading (BMP, TGA, PNG, JPEG, HDR...) 39 | * [rtextures] stb_image_write (Sean Barret) for image writing (BMP, TGA, PNG, JPG) 40 | * [rtextures] stb_image_resize (Sean Barret) for image resizing algorithms 41 | * [rtext] stb_truetype (Sean Barret) for ttf fonts loading 42 | * [rtext] stb_rect_pack (Sean Barret) for rectangles packing 43 | * [rmodels] par_shapes (Philip Rideout) for parametric 3d shapes generation 44 | * [rmodels] tinyobj_loader_c (Syoyo Fujita) for models loading (OBJ, MTL) 45 | * [rmodels] cgltf (Johannes Kuhlmann) for models loading (glTF) 46 | * [raudio] dr_wav (David Reid) for WAV audio file loading 47 | * [raudio] dr_flac (David Reid) for FLAC audio file loading 48 | * [raudio] dr_mp3 (David Reid) for MP3 audio file loading 49 | * [raudio] stb_vorbis (Sean Barret) for OGG audio loading 50 | * [raudio] jar_xm (Joshua Reisenauer) for XM audio module loading 51 | * [raudio] jar_mod (Joshua Reisenauer) for MOD audio module loading 52 | * 53 | * 54 | * LICENSE: zlib/libpng 55 | * 56 | * raylib is licensed under an unmodified zlib/libpng license, which is an OSI-certified, 57 | * BSD-like license that allows static linking with closed source software: 58 | * 59 | * Copyright (c) 2013-2022 Ramon Santamaria (@raysan5) 60 | * 61 | * This software is provided "as-is", without any express or implied warranty. In no event 62 | * will the authors be held liable for any damages arising from the use of this software. 63 | * 64 | * Permission is granted to anyone to use this software for any purpose, including commercial 65 | * applications, and to alter it and redistribute it freely, subject to the following restrictions: 66 | * 67 | * 1. The origin of this software must not be misrepresented; you must not claim that you 68 | * wrote the original software. If you use this software in a product, an acknowledgment 69 | * in the product documentation would be appreciated but is not required. 70 | * 71 | * 2. Altered source versions must be plainly marked as such, and must not be misrepresented 72 | * as being the original software. 73 | * 74 | * 3. This notice may not be removed or altered from any source distribution. 75 | * 76 | **********************************************************************************************/ 77 | 78 | #ifndef RAYLIB_H 79 | #define RAYLIB_H 80 | 81 | #include // Required for: va_list - Only used by TraceLogCallback 82 | 83 | #define RAYLIB_VERSION "4.2" 84 | 85 | // Function specifiers in case library is build/used as a shared library (Windows) 86 | // NOTE: Microsoft specifiers to tell compiler that symbols are imported/exported from a .dll 87 | #if defined(_WIN32) 88 | #if defined(BUILD_LIBTYPE_SHARED) 89 | #if defined(__TINYC__) 90 | #define __declspec(x) __attribute__((x)) 91 | #endif 92 | #define RLAPI __declspec(dllexport) // We are building the library as a Win32 shared library (.dll) 93 | #elif defined(USE_LIBTYPE_SHARED) 94 | #define RLAPI __declspec(dllimport) // We are using the library as a Win32 shared library (.dll) 95 | #endif 96 | #endif 97 | 98 | #ifndef RLAPI 99 | #define RLAPI // Functions defined as 'extern' by default (implicit specifiers) 100 | #endif 101 | 102 | //---------------------------------------------------------------------------------- 103 | // Some basic Defines 104 | //---------------------------------------------------------------------------------- 105 | #ifndef PI 106 | #define PI 3.14159265358979323846f 107 | #endif 108 | #ifndef DEG2RAD 109 | #define DEG2RAD (PI/180.0f) 110 | #endif 111 | #ifndef RAD2DEG 112 | #define RAD2DEG (180.0f/PI) 113 | #endif 114 | 115 | // Allow custom memory allocators 116 | // NOTE: Require recompiling raylib sources 117 | #ifndef RL_MALLOC 118 | #define RL_MALLOC(sz) malloc(sz) 119 | #endif 120 | #ifndef RL_CALLOC 121 | #define RL_CALLOC(n,sz) calloc(n,sz) 122 | #endif 123 | #ifndef RL_REALLOC 124 | #define RL_REALLOC(ptr,sz) realloc(ptr,sz) 125 | #endif 126 | #ifndef RL_FREE 127 | #define RL_FREE(ptr) free(ptr) 128 | #endif 129 | 130 | // NOTE: MSVC C++ compiler does not support compound literals (C99 feature) 131 | // Plain structures in C++ (without constructors) can be initialized with { } 132 | #if defined(__cplusplus) 133 | #define CLITERAL(type) type 134 | #else 135 | #define CLITERAL(type) (type) 136 | #endif 137 | 138 | // NOTE: We set some defines with some data types declared by raylib 139 | // Other modules (raymath, rlgl) also require some of those types, so, 140 | // to be able to use those other modules as standalone (not depending on raylib) 141 | // this defines are very useful for internal check and avoid type (re)definitions 142 | #define RL_COLOR_TYPE 143 | #define RL_RECTANGLE_TYPE 144 | #define RL_VECTOR2_TYPE 145 | #define RL_VECTOR3_TYPE 146 | #define RL_VECTOR4_TYPE 147 | #define RL_QUATERNION_TYPE 148 | #define RL_MATRIX_TYPE 149 | 150 | // Some Basic Colors 151 | // NOTE: Custom raylib color palette for amazing visuals on WHITE background 152 | #define LIGHTGRAY CLITERAL(Color){ 200, 200, 200, 255 } // Light Gray 153 | #define GRAY CLITERAL(Color){ 130, 130, 130, 255 } // Gray 154 | #define DARKGRAY CLITERAL(Color){ 80, 80, 80, 255 } // Dark Gray 155 | #define YELLOW CLITERAL(Color){ 253, 249, 0, 255 } // Yellow 156 | #define GOLD CLITERAL(Color){ 255, 203, 0, 255 } // Gold 157 | #define ORANGE CLITERAL(Color){ 255, 161, 0, 255 } // Orange 158 | #define PINK CLITERAL(Color){ 255, 109, 194, 255 } // Pink 159 | #define RED CLITERAL(Color){ 230, 41, 55, 255 } // Red 160 | #define MAROON CLITERAL(Color){ 190, 33, 55, 255 } // Maroon 161 | #define GREEN CLITERAL(Color){ 0, 228, 48, 255 } // Green 162 | #define LIME CLITERAL(Color){ 0, 158, 47, 255 } // Lime 163 | #define DARKGREEN CLITERAL(Color){ 0, 117, 44, 255 } // Dark Green 164 | #define SKYBLUE CLITERAL(Color){ 102, 191, 255, 255 } // Sky Blue 165 | #define BLUE CLITERAL(Color){ 0, 121, 241, 255 } // Blue 166 | #define DARKBLUE CLITERAL(Color){ 0, 82, 172, 255 } // Dark Blue 167 | #define PURPLE CLITERAL(Color){ 200, 122, 255, 255 } // Purple 168 | #define VIOLET CLITERAL(Color){ 135, 60, 190, 255 } // Violet 169 | #define DARKPURPLE CLITERAL(Color){ 112, 31, 126, 255 } // Dark Purple 170 | #define BEIGE CLITERAL(Color){ 211, 176, 131, 255 } // Beige 171 | #define BROWN CLITERAL(Color){ 127, 106, 79, 255 } // Brown 172 | #define DARKBROWN CLITERAL(Color){ 76, 63, 47, 255 } // Dark Brown 173 | 174 | #define WHITE CLITERAL(Color){ 255, 255, 255, 255 } // White 175 | #define BLACK CLITERAL(Color){ 0, 0, 0, 255 } // Black 176 | #define BLANK CLITERAL(Color){ 0, 0, 0, 0 } // Blank (Transparent) 177 | #define MAGENTA CLITERAL(Color){ 255, 0, 255, 255 } // Magenta 178 | #define RAYWHITE CLITERAL(Color){ 245, 245, 245, 255 } // My own White (raylib logo) 179 | 180 | //---------------------------------------------------------------------------------- 181 | // Structures Definition 182 | //---------------------------------------------------------------------------------- 183 | // Boolean type 184 | #if (defined(__STDC__) && __STDC_VERSION__ >= 199901L) || (defined(_MSC_VER) && _MSC_VER >= 1800) 185 | #include 186 | #elif !defined(__cplusplus) && !defined(bool) 187 | typedef enum bool { false = 0, true = !false } bool; 188 | #define RL_BOOL_TYPE 189 | #endif 190 | 191 | // Vector2, 2 components 192 | typedef struct Vector2 { 193 | float x; // Vector x component 194 | float y; // Vector y component 195 | } Vector2; 196 | 197 | // Vector3, 3 components 198 | typedef struct Vector3 { 199 | float x; // Vector x component 200 | float y; // Vector y component 201 | float z; // Vector z component 202 | } Vector3; 203 | 204 | // Vector4, 4 components 205 | typedef struct Vector4 { 206 | float x; // Vector x component 207 | float y; // Vector y component 208 | float z; // Vector z component 209 | float w; // Vector w component 210 | } Vector4; 211 | 212 | // Quaternion, 4 components (Vector4 alias) 213 | typedef Vector4 Quaternion; 214 | 215 | // Matrix, 4x4 components, column major, OpenGL style, right handed 216 | typedef struct Matrix { 217 | float m0, m4, m8, m12; // Matrix first row (4 components) 218 | float m1, m5, m9, m13; // Matrix second row (4 components) 219 | float m2, m6, m10, m14; // Matrix third row (4 components) 220 | float m3, m7, m11, m15; // Matrix fourth row (4 components) 221 | } Matrix; 222 | 223 | // Color, 4 components, R8G8B8A8 (32bit) 224 | typedef struct Color { 225 | unsigned char r; // Color red value 226 | unsigned char g; // Color green value 227 | unsigned char b; // Color blue value 228 | unsigned char a; // Color alpha value 229 | } Color; 230 | 231 | // Rectangle, 4 components 232 | typedef struct Rectangle { 233 | float x; // Rectangle top-left corner position x 234 | float y; // Rectangle top-left corner position y 235 | float width; // Rectangle width 236 | float height; // Rectangle height 237 | } Rectangle; 238 | 239 | // Image, pixel data stored in CPU memory (RAM) 240 | typedef struct Image { 241 | void *data; // Image raw data 242 | int width; // Image base width 243 | int height; // Image base height 244 | int mipmaps; // Mipmap levels, 1 by default 245 | int format; // Data format (PixelFormat type) 246 | } Image; 247 | 248 | // Texture, tex data stored in GPU memory (VRAM) 249 | typedef struct Texture { 250 | unsigned int id; // OpenGL texture id 251 | int width; // Texture base width 252 | int height; // Texture base height 253 | int mipmaps; // Mipmap levels, 1 by default 254 | int format; // Data format (PixelFormat type) 255 | } Texture; 256 | 257 | // Texture2D, same as Texture 258 | typedef Texture Texture2D; 259 | 260 | // TextureCubemap, same as Texture 261 | typedef Texture TextureCubemap; 262 | 263 | // RenderTexture, fbo for texture rendering 264 | typedef struct RenderTexture { 265 | unsigned int id; // OpenGL framebuffer object id 266 | Texture texture; // Color buffer attachment texture 267 | Texture depth; // Depth buffer attachment texture 268 | } RenderTexture; 269 | 270 | // RenderTexture2D, same as RenderTexture 271 | typedef RenderTexture RenderTexture2D; 272 | 273 | // NPatchInfo, n-patch layout info 274 | typedef struct NPatchInfo { 275 | Rectangle source; // Texture source rectangle 276 | int left; // Left border offset 277 | int top; // Top border offset 278 | int right; // Right border offset 279 | int bottom; // Bottom border offset 280 | int layout; // Layout of the n-patch: 3x3, 1x3 or 3x1 281 | } NPatchInfo; 282 | 283 | // GlyphInfo, font characters glyphs info 284 | typedef struct GlyphInfo { 285 | int value; // Character value (Unicode) 286 | int offsetX; // Character offset X when drawing 287 | int offsetY; // Character offset Y when drawing 288 | int advanceX; // Character advance position X 289 | Image image; // Character image data 290 | } GlyphInfo; 291 | 292 | // Font, font texture and GlyphInfo array data 293 | typedef struct Font { 294 | int baseSize; // Base size (default chars height) 295 | int glyphCount; // Number of glyph characters 296 | int glyphPadding; // Padding around the glyph characters 297 | Texture2D texture; // Texture atlas containing the glyphs 298 | Rectangle *recs; // Rectangles in texture for the glyphs 299 | GlyphInfo *glyphs; // Glyphs info data 300 | } Font; 301 | 302 | // Camera, defines position/orientation in 3d space 303 | typedef struct Camera3D { 304 | Vector3 position; // Camera position 305 | Vector3 target; // Camera target it looks-at 306 | Vector3 up; // Camera up vector (rotation over its axis) 307 | float fovy; // Camera field-of-view apperture in Y (degrees) in perspective, used as near plane width in orthographic 308 | int projection; // Camera projection: CAMERA_PERSPECTIVE or CAMERA_ORTHOGRAPHIC 309 | } Camera3D; 310 | 311 | typedef Camera3D Camera; // Camera type fallback, defaults to Camera3D 312 | 313 | // Camera2D, defines position/orientation in 2d space 314 | typedef struct Camera2D { 315 | Vector2 offset; // Camera offset (displacement from target) 316 | Vector2 target; // Camera target (rotation and zoom origin) 317 | float rotation; // Camera rotation in degrees 318 | float zoom; // Camera zoom (scaling), should be 1.0f by default 319 | } Camera2D; 320 | 321 | // Mesh, vertex data and vao/vbo 322 | typedef struct Mesh { 323 | int vertexCount; // Number of vertices stored in arrays 324 | int triangleCount; // Number of triangles stored (indexed or not) 325 | 326 | // Vertex attributes data 327 | float *vertices; // Vertex position (XYZ - 3 components per vertex) (shader-location = 0) 328 | float *texcoords; // Vertex texture coordinates (UV - 2 components per vertex) (shader-location = 1) 329 | float *texcoords2; // Vertex texture second coordinates (UV - 2 components per vertex) (shader-location = 5) 330 | float *normals; // Vertex normals (XYZ - 3 components per vertex) (shader-location = 2) 331 | float *tangents; // Vertex tangents (XYZW - 4 components per vertex) (shader-location = 4) 332 | unsigned char *colors; // Vertex colors (RGBA - 4 components per vertex) (shader-location = 3) 333 | unsigned short *indices; // Vertex indices (in case vertex data comes indexed) 334 | 335 | // Animation vertex data 336 | float *animVertices; // Animated vertex positions (after bones transformations) 337 | float *animNormals; // Animated normals (after bones transformations) 338 | unsigned char *boneIds; // Vertex bone ids, max 255 bone ids, up to 4 bones influence by vertex (skinning) 339 | float *boneWeights; // Vertex bone weight, up to 4 bones influence by vertex (skinning) 340 | 341 | // OpenGL identifiers 342 | unsigned int vaoId; // OpenGL Vertex Array Object id 343 | unsigned int *vboId; // OpenGL Vertex Buffer Objects id (default vertex data) 344 | } Mesh; 345 | 346 | // Shader 347 | typedef struct Shader { 348 | unsigned int id; // Shader program id 349 | int *locs; // Shader locations array (RL_MAX_SHADER_LOCATIONS) 350 | } Shader; 351 | 352 | // MaterialMap 353 | typedef struct MaterialMap { 354 | Texture2D texture; // Material map texture 355 | Color color; // Material map color 356 | float value; // Material map value 357 | } MaterialMap; 358 | 359 | // Material, includes shader and maps 360 | typedef struct Material { 361 | Shader shader; // Material shader 362 | MaterialMap *maps; // Material maps array (MAX_MATERIAL_MAPS) 363 | float params[4]; // Material generic parameters (if required) 364 | } Material; 365 | 366 | // Transform, vectex transformation data 367 | typedef struct Transform { 368 | Vector3 translation; // Translation 369 | Quaternion rotation; // Rotation 370 | Vector3 scale; // Scale 371 | } Transform; 372 | 373 | // Bone, skeletal animation bone 374 | typedef struct BoneInfo { 375 | char name[32]; // Bone name 376 | int parent; // Bone parent 377 | } BoneInfo; 378 | 379 | // Model, meshes, materials and animation data 380 | typedef struct Model { 381 | Matrix transform; // Local transform matrix 382 | 383 | int meshCount; // Number of meshes 384 | int materialCount; // Number of materials 385 | Mesh *meshes; // Meshes array 386 | Material *materials; // Materials array 387 | int *meshMaterial; // Mesh material number 388 | 389 | // Animation data 390 | int boneCount; // Number of bones 391 | BoneInfo *bones; // Bones information (skeleton) 392 | Transform *bindPose; // Bones base transformation (pose) 393 | } Model; 394 | 395 | // ModelAnimation 396 | typedef struct ModelAnimation { 397 | int boneCount; // Number of bones 398 | int frameCount; // Number of animation frames 399 | BoneInfo *bones; // Bones information (skeleton) 400 | Transform **framePoses; // Poses array by frame 401 | } ModelAnimation; 402 | 403 | // Ray, ray for raycasting 404 | typedef struct Ray { 405 | Vector3 position; // Ray position (origin) 406 | Vector3 direction; // Ray direction 407 | } Ray; 408 | 409 | // RayCollision, ray hit information 410 | typedef struct RayCollision { 411 | bool hit; // Did the ray hit something? 412 | float distance; // Distance to nearest hit 413 | Vector3 point; // Point of nearest hit 414 | Vector3 normal; // Surface normal of hit 415 | } RayCollision; 416 | 417 | // BoundingBox 418 | typedef struct BoundingBox { 419 | Vector3 min; // Minimum vertex box-corner 420 | Vector3 max; // Maximum vertex box-corner 421 | } BoundingBox; 422 | 423 | // Wave, audio wave data 424 | typedef struct Wave { 425 | unsigned int frameCount; // Total number of frames (considering channels) 426 | unsigned int sampleRate; // Frequency (samples per second) 427 | unsigned int sampleSize; // Bit depth (bits per sample): 8, 16, 32 (24 not supported) 428 | unsigned int channels; // Number of channels (1-mono, 2-stereo, ...) 429 | void *data; // Buffer data pointer 430 | } Wave; 431 | 432 | // Opaque structs declaration 433 | // NOTE: Actual structs are defined internally in raudio module 434 | typedef struct rAudioBuffer rAudioBuffer; 435 | typedef struct rAudioProcessor rAudioProcessor; 436 | 437 | // AudioStream, custom audio stream 438 | typedef struct AudioStream { 439 | rAudioBuffer *buffer; // Pointer to internal data used by the audio system 440 | rAudioProcessor *processor; // Pointer to internal data processor, useful for audio effects 441 | 442 | unsigned int sampleRate; // Frequency (samples per second) 443 | unsigned int sampleSize; // Bit depth (bits per sample): 8, 16, 32 (24 not supported) 444 | unsigned int channels; // Number of channels (1-mono, 2-stereo, ...) 445 | } AudioStream; 446 | 447 | // Sound 448 | typedef struct Sound { 449 | AudioStream stream; // Audio stream 450 | unsigned int frameCount; // Total number of frames (considering channels) 451 | } Sound; 452 | 453 | // Music, audio stream, anything longer than ~10 seconds should be streamed 454 | typedef struct Music { 455 | AudioStream stream; // Audio stream 456 | unsigned int frameCount; // Total number of frames (considering channels) 457 | bool looping; // Music looping enable 458 | 459 | int ctxType; // Type of music context (audio filetype) 460 | void *ctxData; // Audio context data, depends on type 461 | } Music; 462 | 463 | // VrDeviceInfo, Head-Mounted-Display device parameters 464 | typedef struct VrDeviceInfo { 465 | int hResolution; // Horizontal resolution in pixels 466 | int vResolution; // Vertical resolution in pixels 467 | float hScreenSize; // Horizontal size in meters 468 | float vScreenSize; // Vertical size in meters 469 | float vScreenCenter; // Screen center in meters 470 | float eyeToScreenDistance; // Distance between eye and display in meters 471 | float lensSeparationDistance; // Lens separation distance in meters 472 | float interpupillaryDistance; // IPD (distance between pupils) in meters 473 | float lensDistortionValues[4]; // Lens distortion constant parameters 474 | float chromaAbCorrection[4]; // Chromatic aberration correction parameters 475 | } VrDeviceInfo; 476 | 477 | // VrStereoConfig, VR stereo rendering configuration for simulator 478 | typedef struct VrStereoConfig { 479 | Matrix projection[2]; // VR projection matrices (per eye) 480 | Matrix viewOffset[2]; // VR view offset matrices (per eye) 481 | float leftLensCenter[2]; // VR left lens center 482 | float rightLensCenter[2]; // VR right lens center 483 | float leftScreenCenter[2]; // VR left screen center 484 | float rightScreenCenter[2]; // VR right screen center 485 | float scale[2]; // VR distortion scale 486 | float scaleIn[2]; // VR distortion scale in 487 | } VrStereoConfig; 488 | 489 | // File path list 490 | typedef struct FilePathList { 491 | unsigned int capacity; // Filepaths max entries 492 | unsigned int count; // Filepaths entries count 493 | char **paths; // Filepaths entries 494 | } FilePathList; 495 | 496 | //---------------------------------------------------------------------------------- 497 | // Enumerators Definition 498 | //---------------------------------------------------------------------------------- 499 | // System/Window config flags 500 | // NOTE: Every bit registers one state (use it with bit masks) 501 | // By default all flags are set to 0 502 | typedef enum { 503 | FLAG_VSYNC_HINT = 0x00000040, // Set to try enabling V-Sync on GPU 504 | FLAG_FULLSCREEN_MODE = 0x00000002, // Set to run program in fullscreen 505 | FLAG_WINDOW_RESIZABLE = 0x00000004, // Set to allow resizable window 506 | FLAG_WINDOW_UNDECORATED = 0x00000008, // Set to disable window decoration (frame and buttons) 507 | FLAG_WINDOW_HIDDEN = 0x00000080, // Set to hide window 508 | FLAG_WINDOW_MINIMIZED = 0x00000200, // Set to minimize window (iconify) 509 | FLAG_WINDOW_MAXIMIZED = 0x00000400, // Set to maximize window (expanded to monitor) 510 | FLAG_WINDOW_UNFOCUSED = 0x00000800, // Set to window non focused 511 | FLAG_WINDOW_TOPMOST = 0x00001000, // Set to window always on top 512 | FLAG_WINDOW_ALWAYS_RUN = 0x00000100, // Set to allow windows running while minimized 513 | FLAG_WINDOW_TRANSPARENT = 0x00000010, // Set to allow transparent framebuffer 514 | FLAG_WINDOW_HIGHDPI = 0x00002000, // Set to support HighDPI 515 | FLAG_WINDOW_MOUSE_PASSTHROUGH = 0x00004000, // Set to support mouse passthrough, only supported when FLAG_WINDOW_UNDECORATED 516 | FLAG_MSAA_4X_HINT = 0x00000020, // Set to try enabling MSAA 4X 517 | FLAG_INTERLACED_HINT = 0x00010000 // Set to try enabling interlaced video format (for V3D) 518 | } ConfigFlags; 519 | 520 | // Trace log level 521 | // NOTE: Organized by priority level 522 | typedef enum { 523 | LOG_ALL = 0, // Display all logs 524 | LOG_TRACE, // Trace logging, intended for internal use only 525 | LOG_DEBUG, // Debug logging, used for internal debugging, it should be disabled on release builds 526 | LOG_INFO, // Info logging, used for program execution info 527 | LOG_WARNING, // Warning logging, used on recoverable failures 528 | LOG_ERROR, // Error logging, used on unrecoverable failures 529 | LOG_FATAL, // Fatal logging, used to abort program: exit(EXIT_FAILURE) 530 | LOG_NONE // Disable logging 531 | } TraceLogLevel; 532 | 533 | // Keyboard keys (US keyboard layout) 534 | // NOTE: Use GetKeyPressed() to allow redefining 535 | // required keys for alternative layouts 536 | typedef enum { 537 | KEY_NULL = 0, // Key: NULL, used for no key pressed 538 | // Alphanumeric keys 539 | KEY_APOSTROPHE = 39, // Key: ' 540 | KEY_COMMA = 44, // Key: , 541 | KEY_MINUS = 45, // Key: - 542 | KEY_PERIOD = 46, // Key: . 543 | KEY_SLASH = 47, // Key: / 544 | KEY_ZERO = 48, // Key: 0 545 | KEY_ONE = 49, // Key: 1 546 | KEY_TWO = 50, // Key: 2 547 | KEY_THREE = 51, // Key: 3 548 | KEY_FOUR = 52, // Key: 4 549 | KEY_FIVE = 53, // Key: 5 550 | KEY_SIX = 54, // Key: 6 551 | KEY_SEVEN = 55, // Key: 7 552 | KEY_EIGHT = 56, // Key: 8 553 | KEY_NINE = 57, // Key: 9 554 | KEY_SEMICOLON = 59, // Key: ; 555 | KEY_EQUAL = 61, // Key: = 556 | KEY_A = 65, // Key: A | a 557 | KEY_B = 66, // Key: B | b 558 | KEY_C = 67, // Key: C | c 559 | KEY_D = 68, // Key: D | d 560 | KEY_E = 69, // Key: E | e 561 | KEY_F = 70, // Key: F | f 562 | KEY_G = 71, // Key: G | g 563 | KEY_H = 72, // Key: H | h 564 | KEY_I = 73, // Key: I | i 565 | KEY_J = 74, // Key: J | j 566 | KEY_K = 75, // Key: K | k 567 | KEY_L = 76, // Key: L | l 568 | KEY_M = 77, // Key: M | m 569 | KEY_N = 78, // Key: N | n 570 | KEY_O = 79, // Key: O | o 571 | KEY_P = 80, // Key: P | p 572 | KEY_Q = 81, // Key: Q | q 573 | KEY_R = 82, // Key: R | r 574 | KEY_S = 83, // Key: S | s 575 | KEY_T = 84, // Key: T | t 576 | KEY_U = 85, // Key: U | u 577 | KEY_V = 86, // Key: V | v 578 | KEY_W = 87, // Key: W | w 579 | KEY_X = 88, // Key: X | x 580 | KEY_Y = 89, // Key: Y | y 581 | KEY_Z = 90, // Key: Z | z 582 | KEY_LEFT_BRACKET = 91, // Key: [ 583 | KEY_BACKSLASH = 92, // Key: '\' 584 | KEY_RIGHT_BRACKET = 93, // Key: ] 585 | KEY_GRAVE = 96, // Key: ` 586 | // Function keys 587 | KEY_SPACE = 32, // Key: Space 588 | KEY_ESCAPE = 256, // Key: Esc 589 | KEY_ENTER = 257, // Key: Enter 590 | KEY_TAB = 258, // Key: Tab 591 | KEY_BACKSPACE = 259, // Key: Backspace 592 | KEY_INSERT = 260, // Key: Ins 593 | KEY_DELETE = 261, // Key: Del 594 | KEY_RIGHT = 262, // Key: Cursor right 595 | KEY_LEFT = 263, // Key: Cursor left 596 | KEY_DOWN = 264, // Key: Cursor down 597 | KEY_UP = 265, // Key: Cursor up 598 | KEY_PAGE_UP = 266, // Key: Page up 599 | KEY_PAGE_DOWN = 267, // Key: Page down 600 | KEY_HOME = 268, // Key: Home 601 | KEY_END = 269, // Key: End 602 | KEY_CAPS_LOCK = 280, // Key: Caps lock 603 | KEY_SCROLL_LOCK = 281, // Key: Scroll down 604 | KEY_NUM_LOCK = 282, // Key: Num lock 605 | KEY_PRINT_SCREEN = 283, // Key: Print screen 606 | KEY_PAUSE = 284, // Key: Pause 607 | KEY_F1 = 290, // Key: F1 608 | KEY_F2 = 291, // Key: F2 609 | KEY_F3 = 292, // Key: F3 610 | KEY_F4 = 293, // Key: F4 611 | KEY_F5 = 294, // Key: F5 612 | KEY_F6 = 295, // Key: F6 613 | KEY_F7 = 296, // Key: F7 614 | KEY_F8 = 297, // Key: F8 615 | KEY_F9 = 298, // Key: F9 616 | KEY_F10 = 299, // Key: F10 617 | KEY_F11 = 300, // Key: F11 618 | KEY_F12 = 301, // Key: F12 619 | KEY_LEFT_SHIFT = 340, // Key: Shift left 620 | KEY_LEFT_CONTROL = 341, // Key: Control left 621 | KEY_LEFT_ALT = 342, // Key: Alt left 622 | KEY_LEFT_SUPER = 343, // Key: Super left 623 | KEY_RIGHT_SHIFT = 344, // Key: Shift right 624 | KEY_RIGHT_CONTROL = 345, // Key: Control right 625 | KEY_RIGHT_ALT = 346, // Key: Alt right 626 | KEY_RIGHT_SUPER = 347, // Key: Super right 627 | KEY_KB_MENU = 348, // Key: KB menu 628 | // Keypad keys 629 | KEY_KP_0 = 320, // Key: Keypad 0 630 | KEY_KP_1 = 321, // Key: Keypad 1 631 | KEY_KP_2 = 322, // Key: Keypad 2 632 | KEY_KP_3 = 323, // Key: Keypad 3 633 | KEY_KP_4 = 324, // Key: Keypad 4 634 | KEY_KP_5 = 325, // Key: Keypad 5 635 | KEY_KP_6 = 326, // Key: Keypad 6 636 | KEY_KP_7 = 327, // Key: Keypad 7 637 | KEY_KP_8 = 328, // Key: Keypad 8 638 | KEY_KP_9 = 329, // Key: Keypad 9 639 | KEY_KP_DECIMAL = 330, // Key: Keypad . 640 | KEY_KP_DIVIDE = 331, // Key: Keypad / 641 | KEY_KP_MULTIPLY = 332, // Key: Keypad * 642 | KEY_KP_SUBTRACT = 333, // Key: Keypad - 643 | KEY_KP_ADD = 334, // Key: Keypad + 644 | KEY_KP_ENTER = 335, // Key: Keypad Enter 645 | KEY_KP_EQUAL = 336, // Key: Keypad = 646 | // Android key buttons 647 | KEY_BACK = 4, // Key: Android back button 648 | KEY_MENU = 82, // Key: Android menu button 649 | KEY_VOLUME_UP = 24, // Key: Android volume up button 650 | KEY_VOLUME_DOWN = 25 // Key: Android volume down button 651 | } KeyboardKey; 652 | 653 | // Add backwards compatibility support for deprecated names 654 | #define MOUSE_LEFT_BUTTON MOUSE_BUTTON_LEFT 655 | #define MOUSE_RIGHT_BUTTON MOUSE_BUTTON_RIGHT 656 | #define MOUSE_MIDDLE_BUTTON MOUSE_BUTTON_MIDDLE 657 | 658 | // Mouse buttons 659 | typedef enum { 660 | MOUSE_BUTTON_LEFT = 0, // Mouse button left 661 | MOUSE_BUTTON_RIGHT = 1, // Mouse button right 662 | MOUSE_BUTTON_MIDDLE = 2, // Mouse button middle (pressed wheel) 663 | MOUSE_BUTTON_SIDE = 3, // Mouse button side (advanced mouse device) 664 | MOUSE_BUTTON_EXTRA = 4, // Mouse button extra (advanced mouse device) 665 | MOUSE_BUTTON_FORWARD = 5, // Mouse button fordward (advanced mouse device) 666 | MOUSE_BUTTON_BACK = 6, // Mouse button back (advanced mouse device) 667 | } MouseButton; 668 | 669 | // Mouse cursor 670 | typedef enum { 671 | MOUSE_CURSOR_DEFAULT = 0, // Default pointer shape 672 | MOUSE_CURSOR_ARROW = 1, // Arrow shape 673 | MOUSE_CURSOR_IBEAM = 2, // Text writing cursor shape 674 | MOUSE_CURSOR_CROSSHAIR = 3, // Cross shape 675 | MOUSE_CURSOR_POINTING_HAND = 4, // Pointing hand cursor 676 | MOUSE_CURSOR_RESIZE_EW = 5, // Horizontal resize/move arrow shape 677 | MOUSE_CURSOR_RESIZE_NS = 6, // Vertical resize/move arrow shape 678 | MOUSE_CURSOR_RESIZE_NWSE = 7, // Top-left to bottom-right diagonal resize/move arrow shape 679 | MOUSE_CURSOR_RESIZE_NESW = 8, // The top-right to bottom-left diagonal resize/move arrow shape 680 | MOUSE_CURSOR_RESIZE_ALL = 9, // The omni-directional resize/move cursor shape 681 | MOUSE_CURSOR_NOT_ALLOWED = 10 // The operation-not-allowed shape 682 | } MouseCursor; 683 | 684 | // Gamepad buttons 685 | typedef enum { 686 | GAMEPAD_BUTTON_UNKNOWN = 0, // Unknown button, just for error checking 687 | GAMEPAD_BUTTON_LEFT_FACE_UP, // Gamepad left DPAD up button 688 | GAMEPAD_BUTTON_LEFT_FACE_RIGHT, // Gamepad left DPAD right button 689 | GAMEPAD_BUTTON_LEFT_FACE_DOWN, // Gamepad left DPAD down button 690 | GAMEPAD_BUTTON_LEFT_FACE_LEFT, // Gamepad left DPAD left button 691 | GAMEPAD_BUTTON_RIGHT_FACE_UP, // Gamepad right button up (i.e. PS3: Triangle, Xbox: Y) 692 | GAMEPAD_BUTTON_RIGHT_FACE_RIGHT, // Gamepad right button right (i.e. PS3: Square, Xbox: X) 693 | GAMEPAD_BUTTON_RIGHT_FACE_DOWN, // Gamepad right button down (i.e. PS3: Cross, Xbox: A) 694 | GAMEPAD_BUTTON_RIGHT_FACE_LEFT, // Gamepad right button left (i.e. PS3: Circle, Xbox: B) 695 | GAMEPAD_BUTTON_LEFT_TRIGGER_1, // Gamepad top/back trigger left (first), it could be a trailing button 696 | GAMEPAD_BUTTON_LEFT_TRIGGER_2, // Gamepad top/back trigger left (second), it could be a trailing button 697 | GAMEPAD_BUTTON_RIGHT_TRIGGER_1, // Gamepad top/back trigger right (one), it could be a trailing button 698 | GAMEPAD_BUTTON_RIGHT_TRIGGER_2, // Gamepad top/back trigger right (second), it could be a trailing button 699 | GAMEPAD_BUTTON_MIDDLE_LEFT, // Gamepad center buttons, left one (i.e. PS3: Select) 700 | GAMEPAD_BUTTON_MIDDLE, // Gamepad center buttons, middle one (i.e. PS3: PS, Xbox: XBOX) 701 | GAMEPAD_BUTTON_MIDDLE_RIGHT, // Gamepad center buttons, right one (i.e. PS3: Start) 702 | GAMEPAD_BUTTON_LEFT_THUMB, // Gamepad joystick pressed button left 703 | GAMEPAD_BUTTON_RIGHT_THUMB // Gamepad joystick pressed button right 704 | } GamepadButton; 705 | 706 | // Gamepad axis 707 | typedef enum { 708 | GAMEPAD_AXIS_LEFT_X = 0, // Gamepad left stick X axis 709 | GAMEPAD_AXIS_LEFT_Y = 1, // Gamepad left stick Y axis 710 | GAMEPAD_AXIS_RIGHT_X = 2, // Gamepad right stick X axis 711 | GAMEPAD_AXIS_RIGHT_Y = 3, // Gamepad right stick Y axis 712 | GAMEPAD_AXIS_LEFT_TRIGGER = 4, // Gamepad back trigger left, pressure level: [1..-1] 713 | GAMEPAD_AXIS_RIGHT_TRIGGER = 5 // Gamepad back trigger right, pressure level: [1..-1] 714 | } GamepadAxis; 715 | 716 | // Material map index 717 | typedef enum { 718 | MATERIAL_MAP_ALBEDO = 0, // Albedo material (same as: MATERIAL_MAP_DIFFUSE) 719 | MATERIAL_MAP_METALNESS, // Metalness material (same as: MATERIAL_MAP_SPECULAR) 720 | MATERIAL_MAP_NORMAL, // Normal material 721 | MATERIAL_MAP_ROUGHNESS, // Roughness material 722 | MATERIAL_MAP_OCCLUSION, // Ambient occlusion material 723 | MATERIAL_MAP_EMISSION, // Emission material 724 | MATERIAL_MAP_HEIGHT, // Heightmap material 725 | MATERIAL_MAP_CUBEMAP, // Cubemap material (NOTE: Uses GL_TEXTURE_CUBE_MAP) 726 | MATERIAL_MAP_IRRADIANCE, // Irradiance material (NOTE: Uses GL_TEXTURE_CUBE_MAP) 727 | MATERIAL_MAP_PREFILTER, // Prefilter material (NOTE: Uses GL_TEXTURE_CUBE_MAP) 728 | MATERIAL_MAP_BRDF // Brdf material 729 | } MaterialMapIndex; 730 | 731 | #define MATERIAL_MAP_DIFFUSE MATERIAL_MAP_ALBEDO 732 | #define MATERIAL_MAP_SPECULAR MATERIAL_MAP_METALNESS 733 | 734 | // Shader location index 735 | typedef enum { 736 | SHADER_LOC_VERTEX_POSITION = 0, // Shader location: vertex attribute: position 737 | SHADER_LOC_VERTEX_TEXCOORD01, // Shader location: vertex attribute: texcoord01 738 | SHADER_LOC_VERTEX_TEXCOORD02, // Shader location: vertex attribute: texcoord02 739 | SHADER_LOC_VERTEX_NORMAL, // Shader location: vertex attribute: normal 740 | SHADER_LOC_VERTEX_TANGENT, // Shader location: vertex attribute: tangent 741 | SHADER_LOC_VERTEX_COLOR, // Shader location: vertex attribute: color 742 | SHADER_LOC_MATRIX_MVP, // Shader location: matrix uniform: model-view-projection 743 | SHADER_LOC_MATRIX_VIEW, // Shader location: matrix uniform: view (camera transform) 744 | SHADER_LOC_MATRIX_PROJECTION, // Shader location: matrix uniform: projection 745 | SHADER_LOC_MATRIX_MODEL, // Shader location: matrix uniform: model (transform) 746 | SHADER_LOC_MATRIX_NORMAL, // Shader location: matrix uniform: normal 747 | SHADER_LOC_VECTOR_VIEW, // Shader location: vector uniform: view 748 | SHADER_LOC_COLOR_DIFFUSE, // Shader location: vector uniform: diffuse color 749 | SHADER_LOC_COLOR_SPECULAR, // Shader location: vector uniform: specular color 750 | SHADER_LOC_COLOR_AMBIENT, // Shader location: vector uniform: ambient color 751 | SHADER_LOC_MAP_ALBEDO, // Shader location: sampler2d texture: albedo (same as: SHADER_LOC_MAP_DIFFUSE) 752 | SHADER_LOC_MAP_METALNESS, // Shader location: sampler2d texture: metalness (same as: SHADER_LOC_MAP_SPECULAR) 753 | SHADER_LOC_MAP_NORMAL, // Shader location: sampler2d texture: normal 754 | SHADER_LOC_MAP_ROUGHNESS, // Shader location: sampler2d texture: roughness 755 | SHADER_LOC_MAP_OCCLUSION, // Shader location: sampler2d texture: occlusion 756 | SHADER_LOC_MAP_EMISSION, // Shader location: sampler2d texture: emission 757 | SHADER_LOC_MAP_HEIGHT, // Shader location: sampler2d texture: height 758 | SHADER_LOC_MAP_CUBEMAP, // Shader location: samplerCube texture: cubemap 759 | SHADER_LOC_MAP_IRRADIANCE, // Shader location: samplerCube texture: irradiance 760 | SHADER_LOC_MAP_PREFILTER, // Shader location: samplerCube texture: prefilter 761 | SHADER_LOC_MAP_BRDF // Shader location: sampler2d texture: brdf 762 | } ShaderLocationIndex; 763 | 764 | #define SHADER_LOC_MAP_DIFFUSE SHADER_LOC_MAP_ALBEDO 765 | #define SHADER_LOC_MAP_SPECULAR SHADER_LOC_MAP_METALNESS 766 | 767 | // Shader uniform data type 768 | typedef enum { 769 | SHADER_UNIFORM_FLOAT = 0, // Shader uniform type: float 770 | SHADER_UNIFORM_VEC2, // Shader uniform type: vec2 (2 float) 771 | SHADER_UNIFORM_VEC3, // Shader uniform type: vec3 (3 float) 772 | SHADER_UNIFORM_VEC4, // Shader uniform type: vec4 (4 float) 773 | SHADER_UNIFORM_INT, // Shader uniform type: int 774 | SHADER_UNIFORM_IVEC2, // Shader uniform type: ivec2 (2 int) 775 | SHADER_UNIFORM_IVEC3, // Shader uniform type: ivec3 (3 int) 776 | SHADER_UNIFORM_IVEC4, // Shader uniform type: ivec4 (4 int) 777 | SHADER_UNIFORM_SAMPLER2D // Shader uniform type: sampler2d 778 | } ShaderUniformDataType; 779 | 780 | // Shader attribute data types 781 | typedef enum { 782 | SHADER_ATTRIB_FLOAT = 0, // Shader attribute type: float 783 | SHADER_ATTRIB_VEC2, // Shader attribute type: vec2 (2 float) 784 | SHADER_ATTRIB_VEC3, // Shader attribute type: vec3 (3 float) 785 | SHADER_ATTRIB_VEC4 // Shader attribute type: vec4 (4 float) 786 | } ShaderAttributeDataType; 787 | 788 | // Pixel formats 789 | // NOTE: Support depends on OpenGL version and platform 790 | typedef enum { 791 | PIXELFORMAT_UNCOMPRESSED_GRAYSCALE = 1, // 8 bit per pixel (no alpha) 792 | PIXELFORMAT_UNCOMPRESSED_GRAY_ALPHA, // 8*2 bpp (2 channels) 793 | PIXELFORMAT_UNCOMPRESSED_R5G6B5, // 16 bpp 794 | PIXELFORMAT_UNCOMPRESSED_R8G8B8, // 24 bpp 795 | PIXELFORMAT_UNCOMPRESSED_R5G5B5A1, // 16 bpp (1 bit alpha) 796 | PIXELFORMAT_UNCOMPRESSED_R4G4B4A4, // 16 bpp (4 bit alpha) 797 | PIXELFORMAT_UNCOMPRESSED_R8G8B8A8, // 32 bpp 798 | PIXELFORMAT_UNCOMPRESSED_R32, // 32 bpp (1 channel - float) 799 | PIXELFORMAT_UNCOMPRESSED_R32G32B32, // 32*3 bpp (3 channels - float) 800 | PIXELFORMAT_UNCOMPRESSED_R32G32B32A32, // 32*4 bpp (4 channels - float) 801 | PIXELFORMAT_COMPRESSED_DXT1_RGB, // 4 bpp (no alpha) 802 | PIXELFORMAT_COMPRESSED_DXT1_RGBA, // 4 bpp (1 bit alpha) 803 | PIXELFORMAT_COMPRESSED_DXT3_RGBA, // 8 bpp 804 | PIXELFORMAT_COMPRESSED_DXT5_RGBA, // 8 bpp 805 | PIXELFORMAT_COMPRESSED_ETC1_RGB, // 4 bpp 806 | PIXELFORMAT_COMPRESSED_ETC2_RGB, // 4 bpp 807 | PIXELFORMAT_COMPRESSED_ETC2_EAC_RGBA, // 8 bpp 808 | PIXELFORMAT_COMPRESSED_PVRT_RGB, // 4 bpp 809 | PIXELFORMAT_COMPRESSED_PVRT_RGBA, // 4 bpp 810 | PIXELFORMAT_COMPRESSED_ASTC_4x4_RGBA, // 8 bpp 811 | PIXELFORMAT_COMPRESSED_ASTC_8x8_RGBA // 2 bpp 812 | } PixelFormat; 813 | 814 | // Texture parameters: filter mode 815 | // NOTE 1: Filtering considers mipmaps if available in the texture 816 | // NOTE 2: Filter is accordingly set for minification and magnification 817 | typedef enum { 818 | TEXTURE_FILTER_POINT = 0, // No filter, just pixel approximation 819 | TEXTURE_FILTER_BILINEAR, // Linear filtering 820 | TEXTURE_FILTER_TRILINEAR, // Trilinear filtering (linear with mipmaps) 821 | TEXTURE_FILTER_ANISOTROPIC_4X, // Anisotropic filtering 4x 822 | TEXTURE_FILTER_ANISOTROPIC_8X, // Anisotropic filtering 8x 823 | TEXTURE_FILTER_ANISOTROPIC_16X, // Anisotropic filtering 16x 824 | } TextureFilter; 825 | 826 | // Texture parameters: wrap mode 827 | typedef enum { 828 | TEXTURE_WRAP_REPEAT = 0, // Repeats texture in tiled mode 829 | TEXTURE_WRAP_CLAMP, // Clamps texture to edge pixel in tiled mode 830 | TEXTURE_WRAP_MIRROR_REPEAT, // Mirrors and repeats the texture in tiled mode 831 | TEXTURE_WRAP_MIRROR_CLAMP // Mirrors and clamps to border the texture in tiled mode 832 | } TextureWrap; 833 | 834 | // Cubemap layouts 835 | typedef enum { 836 | CUBEMAP_LAYOUT_AUTO_DETECT = 0, // Automatically detect layout type 837 | CUBEMAP_LAYOUT_LINE_VERTICAL, // Layout is defined by a vertical line with faces 838 | CUBEMAP_LAYOUT_LINE_HORIZONTAL, // Layout is defined by an horizontal line with faces 839 | CUBEMAP_LAYOUT_CROSS_THREE_BY_FOUR, // Layout is defined by a 3x4 cross with cubemap faces 840 | CUBEMAP_LAYOUT_CROSS_FOUR_BY_THREE, // Layout is defined by a 4x3 cross with cubemap faces 841 | CUBEMAP_LAYOUT_PANORAMA // Layout is defined by a panorama image (equirectangular map) 842 | } CubemapLayout; 843 | 844 | // Font type, defines generation method 845 | typedef enum { 846 | FONT_DEFAULT = 0, // Default font generation, anti-aliased 847 | FONT_BITMAP, // Bitmap font generation, no anti-aliasing 848 | FONT_SDF // SDF font generation, requires external shader 849 | } FontType; 850 | 851 | // Color blending modes (pre-defined) 852 | typedef enum { 853 | BLEND_ALPHA = 0, // Blend textures considering alpha (default) 854 | BLEND_ADDITIVE, // Blend textures adding colors 855 | BLEND_MULTIPLIED, // Blend textures multiplying colors 856 | BLEND_ADD_COLORS, // Blend textures adding colors (alternative) 857 | BLEND_SUBTRACT_COLORS, // Blend textures subtracting colors (alternative) 858 | BLEND_ALPHA_PREMULTIPLY, // Blend premultiplied textures considering alpha 859 | BLEND_CUSTOM // Blend textures using custom src/dst factors (use rlSetBlendMode()) 860 | } BlendMode; 861 | 862 | // Gesture 863 | // NOTE: It could be used as flags to enable only some gestures 864 | typedef enum { 865 | GESTURE_NONE = 0, // No gesture 866 | GESTURE_TAP = 1, // Tap gesture 867 | GESTURE_DOUBLETAP = 2, // Double tap gesture 868 | GESTURE_HOLD = 4, // Hold gesture 869 | GESTURE_DRAG = 8, // Drag gesture 870 | GESTURE_SWIPE_RIGHT = 16, // Swipe right gesture 871 | GESTURE_SWIPE_LEFT = 32, // Swipe left gesture 872 | GESTURE_SWIPE_UP = 64, // Swipe up gesture 873 | GESTURE_SWIPE_DOWN = 128, // Swipe down gesture 874 | GESTURE_PINCH_IN = 256, // Pinch in gesture 875 | GESTURE_PINCH_OUT = 512 // Pinch out gesture 876 | } Gesture; 877 | 878 | // Camera system modes 879 | typedef enum { 880 | CAMERA_CUSTOM = 0, // Custom camera 881 | CAMERA_FREE, // Free camera 882 | CAMERA_ORBITAL, // Orbital camera 883 | CAMERA_FIRST_PERSON, // First person camera 884 | CAMERA_THIRD_PERSON // Third person camera 885 | } CameraMode; 886 | 887 | // Camera projection 888 | typedef enum { 889 | CAMERA_PERSPECTIVE = 0, // Perspective projection 890 | CAMERA_ORTHOGRAPHIC // Orthographic projection 891 | } CameraProjection; 892 | 893 | // N-patch layout 894 | typedef enum { 895 | NPATCH_NINE_PATCH = 0, // Npatch layout: 3x3 tiles 896 | NPATCH_THREE_PATCH_VERTICAL, // Npatch layout: 1x3 tiles 897 | NPATCH_THREE_PATCH_HORIZONTAL // Npatch layout: 3x1 tiles 898 | } NPatchLayout; 899 | 900 | // Callbacks to hook some internal functions 901 | // WARNING: This callbacks are intended for advance users 902 | typedef void (*TraceLogCallback)(int logLevel, const char *text, va_list args); // Logging: Redirect trace log messages 903 | typedef unsigned char *(*LoadFileDataCallback)(const char *fileName, unsigned int *bytesRead); // FileIO: Load binary data 904 | typedef bool (*SaveFileDataCallback)(const char *fileName, void *data, unsigned int bytesToWrite); // FileIO: Save binary data 905 | typedef char *(*LoadFileTextCallback)(const char *fileName); // FileIO: Load text data 906 | typedef bool (*SaveFileTextCallback)(const char *fileName, char *text); // FileIO: Save text data 907 | 908 | //------------------------------------------------------------------------------------ 909 | // Global Variables Definition 910 | //------------------------------------------------------------------------------------ 911 | // It's lonely here... 912 | 913 | //------------------------------------------------------------------------------------ 914 | // Window and Graphics Device Functions (Module: core) 915 | //------------------------------------------------------------------------------------ 916 | 917 | #if defined(__cplusplus) 918 | extern "C" { // Prevents name mangling of functions 919 | #endif 920 | 921 | // Window-related functions 922 | RLAPI void InitWindow(int width, int height, const char *title); // Initialize window and OpenGL context 923 | RLAPI bool WindowShouldClose(void); // Check if KEY_ESCAPE pressed or Close icon pressed 924 | RLAPI void CloseWindow(void); // Close window and unload OpenGL context 925 | RLAPI bool IsWindowReady(void); // Check if window has been initialized successfully 926 | RLAPI bool IsWindowFullscreen(void); // Check if window is currently fullscreen 927 | RLAPI bool IsWindowHidden(void); // Check if window is currently hidden (only PLATFORM_DESKTOP) 928 | RLAPI bool IsWindowMinimized(void); // Check if window is currently minimized (only PLATFORM_DESKTOP) 929 | RLAPI bool IsWindowMaximized(void); // Check if window is currently maximized (only PLATFORM_DESKTOP) 930 | RLAPI bool IsWindowFocused(void); // Check if window is currently focused (only PLATFORM_DESKTOP) 931 | RLAPI bool IsWindowResized(void); // Check if window has been resized last frame 932 | RLAPI bool IsWindowState(unsigned int flag); // Check if one specific window flag is enabled 933 | RLAPI void SetWindowState(unsigned int flags); // Set window configuration state using flags (only PLATFORM_DESKTOP) 934 | RLAPI void ClearWindowState(unsigned int flags); // Clear window configuration state flags 935 | RLAPI void ToggleFullscreen(void); // Toggle window state: fullscreen/windowed (only PLATFORM_DESKTOP) 936 | RLAPI void MaximizeWindow(void); // Set window state: maximized, if resizable (only PLATFORM_DESKTOP) 937 | RLAPI void MinimizeWindow(void); // Set window state: minimized, if resizable (only PLATFORM_DESKTOP) 938 | RLAPI void RestoreWindow(void); // Set window state: not minimized/maximized (only PLATFORM_DESKTOP) 939 | RLAPI void SetWindowIcon(Image image); // Set icon for window (only PLATFORM_DESKTOP) 940 | RLAPI void SetWindowTitle(const char *title); // Set title for window (only PLATFORM_DESKTOP) 941 | RLAPI void SetWindowPosition(int x, int y); // Set window position on screen (only PLATFORM_DESKTOP) 942 | RLAPI void SetWindowMonitor(int monitor); // Set monitor for the current window (fullscreen mode) 943 | RLAPI void SetWindowMinSize(int width, int height); // Set window minimum dimensions (for FLAG_WINDOW_RESIZABLE) 944 | RLAPI void SetWindowSize(int width, int height); // Set window dimensions 945 | RLAPI void SetWindowOpacity(float opacity); // Set window opacity [0.0f..1.0f] (only PLATFORM_DESKTOP) 946 | RLAPI void *GetWindowHandle(void); // Get native window handle 947 | RLAPI int GetScreenWidth(void); // Get current screen width 948 | RLAPI int GetScreenHeight(void); // Get current screen height 949 | RLAPI int GetRenderWidth(void); // Get current render width (it considers HiDPI) 950 | RLAPI int GetRenderHeight(void); // Get current render height (it considers HiDPI) 951 | RLAPI int GetMonitorCount(void); // Get number of connected monitors 952 | RLAPI int GetCurrentMonitor(void); // Get current connected monitor 953 | RLAPI Vector2 GetMonitorPosition(int monitor); // Get specified monitor position 954 | RLAPI int GetMonitorWidth(int monitor); // Get specified monitor width (current video mode used by monitor) 955 | RLAPI int GetMonitorHeight(int monitor); // Get specified monitor height (current video mode used by monitor) 956 | RLAPI int GetMonitorPhysicalWidth(int monitor); // Get specified monitor physical width in millimetres 957 | RLAPI int GetMonitorPhysicalHeight(int monitor); // Get specified monitor physical height in millimetres 958 | RLAPI int GetMonitorRefreshRate(int monitor); // Get specified monitor refresh rate 959 | RLAPI Vector2 GetWindowPosition(void); // Get window position XY on monitor 960 | RLAPI Vector2 GetWindowScaleDPI(void); // Get window scale DPI factor 961 | RLAPI const char *GetMonitorName(int monitor); // Get the human-readable, UTF-8 encoded name of the primary monitor 962 | RLAPI void SetClipboardText(const char *text); // Set clipboard text content 963 | RLAPI const char *GetClipboardText(void); // Get clipboard text content 964 | RLAPI void EnableEventWaiting(void); // Enable waiting for events on EndDrawing(), no automatic event polling 965 | RLAPI void DisableEventWaiting(void); // Disable waiting for events on EndDrawing(), automatic events polling 966 | 967 | // Custom frame control functions 968 | // NOTE: Those functions are intended for advance users that want full control over the frame processing 969 | // By default EndDrawing() does this job: draws everything + SwapScreenBuffer() + manage frame timming + PollInputEvents() 970 | // To avoid that behaviour and control frame processes manually, enable in config.h: SUPPORT_CUSTOM_FRAME_CONTROL 971 | RLAPI void SwapScreenBuffer(void); // Swap back buffer with front buffer (screen drawing) 972 | RLAPI void PollInputEvents(void); // Register all input events 973 | RLAPI void WaitTime(double seconds); // Wait for some time (halt program execution) 974 | 975 | // Cursor-related functions 976 | RLAPI void ShowCursor(void); // Shows cursor 977 | RLAPI void HideCursor(void); // Hides cursor 978 | RLAPI bool IsCursorHidden(void); // Check if cursor is not visible 979 | RLAPI void EnableCursor(void); // Enables cursor (unlock cursor) 980 | RLAPI void DisableCursor(void); // Disables cursor (lock cursor) 981 | RLAPI bool IsCursorOnScreen(void); // Check if cursor is on the screen 982 | 983 | // Drawing-related functions 984 | RLAPI void ClearBackground(Color color); // Set background color (framebuffer clear color) 985 | RLAPI void BeginDrawing(void); // Setup canvas (framebuffer) to start drawing 986 | RLAPI void EndDrawing(void); // End canvas drawing and swap buffers (double buffering) 987 | RLAPI void BeginMode2D(Camera2D camera); // Begin 2D mode with custom camera (2D) 988 | RLAPI void EndMode2D(void); // Ends 2D mode with custom camera 989 | RLAPI void BeginMode3D(Camera3D camera); // Begin 3D mode with custom camera (3D) 990 | RLAPI void EndMode3D(void); // Ends 3D mode and returns to default 2D orthographic mode 991 | RLAPI void BeginTextureMode(RenderTexture2D target); // Begin drawing to render texture 992 | RLAPI void EndTextureMode(void); // Ends drawing to render texture 993 | RLAPI void BeginShaderMode(Shader shader); // Begin custom shader drawing 994 | RLAPI void EndShaderMode(void); // End custom shader drawing (use default shader) 995 | RLAPI void BeginBlendMode(int mode); // Begin blending mode (alpha, additive, multiplied, subtract, custom) 996 | RLAPI void EndBlendMode(void); // End blending mode (reset to default: alpha blending) 997 | RLAPI void BeginScissorMode(int x, int y, int width, int height); // Begin scissor mode (define screen area for following drawing) 998 | RLAPI void EndScissorMode(void); // End scissor mode 999 | RLAPI void BeginVrStereoMode(VrStereoConfig config); // Begin stereo rendering (requires VR simulator) 1000 | RLAPI void EndVrStereoMode(void); // End stereo rendering (requires VR simulator) 1001 | 1002 | // VR stereo config functions for VR simulator 1003 | RLAPI VrStereoConfig LoadVrStereoConfig(VrDeviceInfo device); // Load VR stereo config for VR simulator device parameters 1004 | RLAPI void UnloadVrStereoConfig(VrStereoConfig config); // Unload VR stereo config 1005 | 1006 | // Shader management functions 1007 | // NOTE: Shader functionality is not available on OpenGL 1.1 1008 | RLAPI Shader LoadShader(const char *vsFileName, const char *fsFileName); // Load shader from files and bind default locations 1009 | RLAPI Shader LoadShaderFromMemory(const char *vsCode, const char *fsCode); // Load shader from code strings and bind default locations 1010 | RLAPI int GetShaderLocation(Shader shader, const char *uniformName); // Get shader uniform location 1011 | RLAPI int GetShaderLocationAttrib(Shader shader, const char *attribName); // Get shader attribute location 1012 | RLAPI void SetShaderValue(Shader shader, int locIndex, const void *value, int uniformType); // Set shader uniform value 1013 | RLAPI void SetShaderValueV(Shader shader, int locIndex, const void *value, int uniformType, int count); // Set shader uniform value vector 1014 | RLAPI void SetShaderValueMatrix(Shader shader, int locIndex, Matrix mat); // Set shader uniform value (matrix 4x4) 1015 | RLAPI void SetShaderValueTexture(Shader shader, int locIndex, Texture2D texture); // Set shader uniform value for texture (sampler2d) 1016 | RLAPI void UnloadShader(Shader shader); // Unload shader from GPU memory (VRAM) 1017 | 1018 | // Screen-space-related functions 1019 | RLAPI Ray GetMouseRay(Vector2 mousePosition, Camera camera); // Get a ray trace from mouse position 1020 | RLAPI Matrix GetCameraMatrix(Camera camera); // Get camera transform matrix (view matrix) 1021 | RLAPI Matrix GetCameraMatrix2D(Camera2D camera); // Get camera 2d transform matrix 1022 | RLAPI Vector2 GetWorldToScreen(Vector3 position, Camera camera); // Get the screen space position for a 3d world space position 1023 | RLAPI Vector2 GetScreenToWorld2D(Vector2 position, Camera2D camera); // Get the world space position for a 2d camera screen space position 1024 | RLAPI Vector2 GetWorldToScreenEx(Vector3 position, Camera camera, int width, int height); // Get size position for a 3d world space position 1025 | RLAPI Vector2 GetWorldToScreen2D(Vector2 position, Camera2D camera); // Get the screen space position for a 2d camera world space position 1026 | 1027 | // Timing-related functions 1028 | RLAPI void SetTargetFPS(int fps); // Set target FPS (maximum) 1029 | RLAPI int GetFPS(void); // Get current FPS 1030 | RLAPI float GetFrameTime(void); // Get time in seconds for last frame drawn (delta time) 1031 | RLAPI double GetTime(void); // Get elapsed time in seconds since InitWindow() 1032 | 1033 | // Misc. functions 1034 | RLAPI int GetRandomValue(int min, int max); // Get a random value between min and max (both included) 1035 | RLAPI void SetRandomSeed(unsigned int seed); // Set the seed for the random number generator 1036 | RLAPI void TakeScreenshot(const char *fileName); // Takes a screenshot of current screen (filename extension defines format) 1037 | RLAPI void SetConfigFlags(unsigned int flags); // Setup init configuration flags (view FLAGS) 1038 | 1039 | RLAPI void TraceLog(int logLevel, const char *text, ...); // Show trace log messages (LOG_DEBUG, LOG_INFO, LOG_WARNING, LOG_ERROR...) 1040 | RLAPI void SetTraceLogLevel(int logLevel); // Set the current threshold (minimum) log level 1041 | RLAPI void *MemAlloc(int size); // Internal memory allocator 1042 | RLAPI void *MemRealloc(void *ptr, int size); // Internal memory reallocator 1043 | RLAPI void MemFree(void *ptr); // Internal memory free 1044 | 1045 | RLAPI void OpenURL(const char *url); // Open URL with default system browser (if available) 1046 | 1047 | // Set custom callbacks 1048 | // WARNING: Callbacks setup is intended for advance users 1049 | RLAPI void SetTraceLogCallback(TraceLogCallback callback); // Set custom trace log 1050 | RLAPI void SetLoadFileDataCallback(LoadFileDataCallback callback); // Set custom file binary data loader 1051 | RLAPI void SetSaveFileDataCallback(SaveFileDataCallback callback); // Set custom file binary data saver 1052 | RLAPI void SetLoadFileTextCallback(LoadFileTextCallback callback); // Set custom file text data loader 1053 | RLAPI void SetSaveFileTextCallback(SaveFileTextCallback callback); // Set custom file text data saver 1054 | 1055 | // Files management functions 1056 | RLAPI unsigned char *LoadFileData(const char *fileName, unsigned int *bytesRead); // Load file data as byte array (read) 1057 | RLAPI void UnloadFileData(unsigned char *data); // Unload file data allocated by LoadFileData() 1058 | RLAPI bool SaveFileData(const char *fileName, void *data, unsigned int bytesToWrite); // Save data to file from byte array (write), returns true on success 1059 | RLAPI bool ExportDataAsCode(const char *data, unsigned int size, const char *fileName); // Export data to code (.h), returns true on success 1060 | RLAPI char *LoadFileText(const char *fileName); // Load text data from file (read), returns a '\0' terminated string 1061 | RLAPI void UnloadFileText(char *text); // Unload file text data allocated by LoadFileText() 1062 | RLAPI bool SaveFileText(const char *fileName, char *text); // Save text data to file (write), string must be '\0' terminated, returns true on success 1063 | RLAPI bool FileExists(const char *fileName); // Check if file exists 1064 | RLAPI bool DirectoryExists(const char *dirPath); // Check if a directory path exists 1065 | RLAPI bool IsFileExtension(const char *fileName, const char *ext); // Check file extension (including point: .png, .wav) 1066 | RLAPI int GetFileLength(const char *fileName); // Get file length in bytes (NOTE: GetFileSize() conflicts with windows.h) 1067 | RLAPI const char *GetFileExtension(const char *fileName); // Get pointer to extension for a filename string (includes dot: '.png') 1068 | RLAPI const char *GetFileName(const char *filePath); // Get pointer to filename for a path string 1069 | RLAPI const char *GetFileNameWithoutExt(const char *filePath); // Get filename string without extension (uses static string) 1070 | RLAPI const char *GetDirectoryPath(const char *filePath); // Get full path for a given fileName with path (uses static string) 1071 | RLAPI const char *GetPrevDirectoryPath(const char *dirPath); // Get previous directory path for a given path (uses static string) 1072 | RLAPI const char *GetWorkingDirectory(void); // Get current working directory (uses static string) 1073 | RLAPI const char *GetApplicationDirectory(void); // Get the directory if the running application (uses static string) 1074 | RLAPI bool ChangeDirectory(const char *dir); // Change working directory, return true on success 1075 | RLAPI bool IsPathFile(const char *path); // Check if a given path is a file or a directory 1076 | RLAPI FilePathList LoadDirectoryFiles(const char *dirPath); // Load directory filepaths 1077 | RLAPI FilePathList LoadDirectoryFilesEx(const char *basePath, const char *filter, bool scanSubdirs); // Load directory filepaths with extension filtering and recursive directory scan 1078 | RLAPI void UnloadDirectoryFiles(FilePathList files); // Unload filepaths 1079 | RLAPI bool IsFileDropped(void); // Check if a file has been dropped into window 1080 | RLAPI FilePathList LoadDroppedFiles(void); // Load dropped filepaths 1081 | RLAPI void UnloadDroppedFiles(FilePathList files); // Unload dropped filepaths 1082 | RLAPI long GetFileModTime(const char *fileName); // Get file modification time (last write time) 1083 | 1084 | // Compression/Encoding functionality 1085 | RLAPI unsigned char *CompressData(const unsigned char *data, int dataSize, int *compDataSize); // Compress data (DEFLATE algorithm), memory must be MemFree() 1086 | RLAPI unsigned char *DecompressData(const unsigned char *compData, int compDataSize, int *dataSize); // Decompress data (DEFLATE algorithm), memory must be MemFree() 1087 | RLAPI char *EncodeDataBase64(const unsigned char *data, int dataSize, int *outputSize); // Encode data to Base64 string, memory must be MemFree() 1088 | RLAPI unsigned char *DecodeDataBase64(const unsigned char *data, int *outputSize); // Decode Base64 string data, memory must be MemFree() 1089 | 1090 | //------------------------------------------------------------------------------------ 1091 | // Input Handling Functions (Module: core) 1092 | //------------------------------------------------------------------------------------ 1093 | 1094 | // Input-related functions: keyboard 1095 | RLAPI bool IsKeyPressed(int key); // Check if a key has been pressed once 1096 | RLAPI bool IsKeyDown(int key); // Check if a key is being pressed 1097 | RLAPI bool IsKeyReleased(int key); // Check if a key has been released once 1098 | RLAPI bool IsKeyUp(int key); // Check if a key is NOT being pressed 1099 | RLAPI void SetExitKey(int key); // Set a custom key to exit program (default is ESC) 1100 | RLAPI int GetKeyPressed(void); // Get key pressed (keycode), call it multiple times for keys queued, returns 0 when the queue is empty 1101 | RLAPI int GetCharPressed(void); // Get char pressed (unicode), call it multiple times for chars queued, returns 0 when the queue is empty 1102 | 1103 | // Input-related functions: gamepads 1104 | RLAPI bool IsGamepadAvailable(int gamepad); // Check if a gamepad is available 1105 | RLAPI const char *GetGamepadName(int gamepad); // Get gamepad internal name id 1106 | RLAPI bool IsGamepadButtonPressed(int gamepad, int button); // Check if a gamepad button has been pressed once 1107 | RLAPI bool IsGamepadButtonDown(int gamepad, int button); // Check if a gamepad button is being pressed 1108 | RLAPI bool IsGamepadButtonReleased(int gamepad, int button); // Check if a gamepad button has been released once 1109 | RLAPI bool IsGamepadButtonUp(int gamepad, int button); // Check if a gamepad button is NOT being pressed 1110 | RLAPI int GetGamepadButtonPressed(void); // Get the last gamepad button pressed 1111 | RLAPI int GetGamepadAxisCount(int gamepad); // Get gamepad axis count for a gamepad 1112 | RLAPI float GetGamepadAxisMovement(int gamepad, int axis); // Get axis movement value for a gamepad axis 1113 | RLAPI int SetGamepadMappings(const char *mappings); // Set internal gamepad mappings (SDL_GameControllerDB) 1114 | 1115 | // Input-related functions: mouse 1116 | RLAPI bool IsMouseButtonPressed(int button); // Check if a mouse button has been pressed once 1117 | RLAPI bool IsMouseButtonDown(int button); // Check if a mouse button is being pressed 1118 | RLAPI bool IsMouseButtonReleased(int button); // Check if a mouse button has been released once 1119 | RLAPI bool IsMouseButtonUp(int button); // Check if a mouse button is NOT being pressed 1120 | RLAPI int GetMouseX(void); // Get mouse position X 1121 | RLAPI int GetMouseY(void); // Get mouse position Y 1122 | RLAPI Vector2 GetMousePosition(void); // Get mouse position XY 1123 | RLAPI Vector2 GetMouseDelta(void); // Get mouse delta between frames 1124 | RLAPI void SetMousePosition(int x, int y); // Set mouse position XY 1125 | RLAPI void SetMouseOffset(int offsetX, int offsetY); // Set mouse offset 1126 | RLAPI void SetMouseScale(float scaleX, float scaleY); // Set mouse scaling 1127 | RLAPI float GetMouseWheelMove(void); // Get mouse wheel movement for X or Y, whichever is larger 1128 | RLAPI Vector2 GetMouseWheelMoveV(void); // Get mouse wheel movement for both X and Y 1129 | RLAPI void SetMouseCursor(int cursor); // Set mouse cursor 1130 | 1131 | // Input-related functions: touch 1132 | RLAPI int GetTouchX(void); // Get touch position X for touch point 0 (relative to screen size) 1133 | RLAPI int GetTouchY(void); // Get touch position Y for touch point 0 (relative to screen size) 1134 | RLAPI Vector2 GetTouchPosition(int index); // Get touch position XY for a touch point index (relative to screen size) 1135 | RLAPI int GetTouchPointId(int index); // Get touch point identifier for given index 1136 | RLAPI int GetTouchPointCount(void); // Get number of touch points 1137 | 1138 | //------------------------------------------------------------------------------------ 1139 | // Gestures and Touch Handling Functions (Module: rgestures) 1140 | //------------------------------------------------------------------------------------ 1141 | RLAPI void SetGesturesEnabled(unsigned int flags); // Enable a set of gestures using flags 1142 | RLAPI bool IsGestureDetected(int gesture); // Check if a gesture have been detected 1143 | RLAPI int GetGestureDetected(void); // Get latest detected gesture 1144 | RLAPI float GetGestureHoldDuration(void); // Get gesture hold time in milliseconds 1145 | RLAPI Vector2 GetGestureDragVector(void); // Get gesture drag vector 1146 | RLAPI float GetGestureDragAngle(void); // Get gesture drag angle 1147 | RLAPI Vector2 GetGesturePinchVector(void); // Get gesture pinch delta 1148 | RLAPI float GetGesturePinchAngle(void); // Get gesture pinch angle 1149 | 1150 | //------------------------------------------------------------------------------------ 1151 | // Camera System Functions (Module: rcamera) 1152 | //------------------------------------------------------------------------------------ 1153 | RLAPI void SetCameraMode(Camera camera, int mode); // Set camera mode (multiple camera modes available) 1154 | RLAPI void UpdateCamera(Camera *camera); // Update camera position for selected mode 1155 | 1156 | RLAPI void SetCameraPanControl(int keyPan); // Set camera pan key to combine with mouse movement (free camera) 1157 | RLAPI void SetCameraAltControl(int keyAlt); // Set camera alt key to combine with mouse movement (free camera) 1158 | RLAPI void SetCameraSmoothZoomControl(int keySmoothZoom); // Set camera smooth zoom key to combine with mouse (free camera) 1159 | RLAPI void SetCameraMoveControls(int keyFront, int keyBack, int keyRight, int keyLeft, int keyUp, int keyDown); // Set camera move controls (1st person and 3rd person cameras) 1160 | 1161 | //------------------------------------------------------------------------------------ 1162 | // Basic Shapes Drawing Functions (Module: shapes) 1163 | //------------------------------------------------------------------------------------ 1164 | // Set texture and rectangle to be used on shapes drawing 1165 | // NOTE: It can be useful when using basic shapes and one single font, 1166 | // defining a font char white rectangle would allow drawing everything in a single draw call 1167 | RLAPI void SetShapesTexture(Texture2D texture, Rectangle source); // Set texture and rectangle to be used on shapes drawing 1168 | 1169 | // Basic shapes drawing functions 1170 | RLAPI void DrawPixel(int posX, int posY, Color color); // Draw a pixel 1171 | RLAPI void DrawPixelV(Vector2 position, Color color); // Draw a pixel (Vector version) 1172 | RLAPI void DrawLine(int startPosX, int startPosY, int endPosX, int endPosY, Color color); // Draw a line 1173 | RLAPI void DrawLineV(Vector2 startPos, Vector2 endPos, Color color); // Draw a line (Vector version) 1174 | RLAPI void DrawLineEx(Vector2 startPos, Vector2 endPos, float thick, Color color); // Draw a line defining thickness 1175 | RLAPI void DrawLineBezier(Vector2 startPos, Vector2 endPos, float thick, Color color); // Draw a line using cubic-bezier curves in-out 1176 | RLAPI void DrawLineBezierQuad(Vector2 startPos, Vector2 endPos, Vector2 controlPos, float thick, Color color); // Draw line using quadratic bezier curves with a control point 1177 | RLAPI void DrawLineBezierCubic(Vector2 startPos, Vector2 endPos, Vector2 startControlPos, Vector2 endControlPos, float thick, Color color); // Draw line using cubic bezier curves with 2 control points 1178 | RLAPI void DrawLineStrip(Vector2 *points, int pointCount, Color color); // Draw lines sequence 1179 | RLAPI void DrawCircle(int centerX, int centerY, float radius, Color color); // Draw a color-filled circle 1180 | RLAPI void DrawCircleSector(Vector2 center, float radius, float startAngle, float endAngle, int segments, Color color); // Draw a piece of a circle 1181 | RLAPI void DrawCircleSectorLines(Vector2 center, float radius, float startAngle, float endAngle, int segments, Color color); // Draw circle sector outline 1182 | RLAPI void DrawCircleGradient(int centerX, int centerY, float radius, Color color1, Color color2); // Draw a gradient-filled circle 1183 | RLAPI void DrawCircleV(Vector2 center, float radius, Color color); // Draw a color-filled circle (Vector version) 1184 | RLAPI void DrawCircleLines(int centerX, int centerY, float radius, Color color); // Draw circle outline 1185 | RLAPI void DrawEllipse(int centerX, int centerY, float radiusH, float radiusV, Color color); // Draw ellipse 1186 | RLAPI void DrawEllipseLines(int centerX, int centerY, float radiusH, float radiusV, Color color); // Draw ellipse outline 1187 | RLAPI void DrawRing(Vector2 center, float innerRadius, float outerRadius, float startAngle, float endAngle, int segments, Color color); // Draw ring 1188 | RLAPI void DrawRingLines(Vector2 center, float innerRadius, float outerRadius, float startAngle, float endAngle, int segments, Color color); // Draw ring outline 1189 | RLAPI void DrawRectangle(int posX, int posY, int width, int height, Color color); // Draw a color-filled rectangle 1190 | RLAPI void DrawRectangleV(Vector2 position, Vector2 size, Color color); // Draw a color-filled rectangle (Vector version) 1191 | RLAPI void DrawRectangleRec(Rectangle rec, Color color); // Draw a color-filled rectangle 1192 | RLAPI void DrawRectanglePro(Rectangle rec, Vector2 origin, float rotation, Color color); // Draw a color-filled rectangle with pro parameters 1193 | RLAPI void DrawRectangleGradientV(int posX, int posY, int width, int height, Color color1, Color color2);// Draw a vertical-gradient-filled rectangle 1194 | RLAPI void DrawRectangleGradientH(int posX, int posY, int width, int height, Color color1, Color color2);// Draw a horizontal-gradient-filled rectangle 1195 | RLAPI void DrawRectangleGradientEx(Rectangle rec, Color col1, Color col2, Color col3, Color col4); // Draw a gradient-filled rectangle with custom vertex colors 1196 | RLAPI void DrawRectangleLines(int posX, int posY, int width, int height, Color color); // Draw rectangle outline 1197 | RLAPI void DrawRectangleLinesEx(Rectangle rec, float lineThick, Color color); // Draw rectangle outline with extended parameters 1198 | RLAPI void DrawRectangleRounded(Rectangle rec, float roundness, int segments, Color color); // Draw rectangle with rounded edges 1199 | RLAPI void DrawRectangleRoundedLines(Rectangle rec, float roundness, int segments, float lineThick, Color color); // Draw rectangle with rounded edges outline 1200 | RLAPI void DrawTriangle(Vector2 v1, Vector2 v2, Vector2 v3, Color color); // Draw a color-filled triangle (vertex in counter-clockwise order!) 1201 | RLAPI void DrawTriangleLines(Vector2 v1, Vector2 v2, Vector2 v3, Color color); // Draw triangle outline (vertex in counter-clockwise order!) 1202 | RLAPI void DrawTriangleFan(Vector2 *points, int pointCount, Color color); // Draw a triangle fan defined by points (first vertex is the center) 1203 | RLAPI void DrawTriangleStrip(Vector2 *points, int pointCount, Color color); // Draw a triangle strip defined by points 1204 | RLAPI void DrawPoly(Vector2 center, int sides, float radius, float rotation, Color color); // Draw a regular polygon (Vector version) 1205 | RLAPI void DrawPolyLines(Vector2 center, int sides, float radius, float rotation, Color color); // Draw a polygon outline of n sides 1206 | 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 1207 | 1208 | // Basic shapes collision detection functions 1209 | RLAPI bool CheckCollisionRecs(Rectangle rec1, Rectangle rec2); // Check collision between two rectangles 1210 | RLAPI bool CheckCollisionCircles(Vector2 center1, float radius1, Vector2 center2, float radius2); // Check collision between two circles 1211 | RLAPI bool CheckCollisionCircleRec(Vector2 center, float radius, Rectangle rec); // Check collision between circle and rectangle 1212 | RLAPI bool CheckCollisionPointRec(Vector2 point, Rectangle rec); // Check if point is inside rectangle 1213 | RLAPI bool CheckCollisionPointCircle(Vector2 point, Vector2 center, float radius); // Check if point is inside circle 1214 | RLAPI bool CheckCollisionPointTriangle(Vector2 point, Vector2 p1, Vector2 p2, Vector2 p3); // Check if point is inside a triangle 1215 | 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 1216 | 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] 1217 | RLAPI Rectangle GetCollisionRec(Rectangle rec1, Rectangle rec2); // Get collision rectangle for two rectangles collision 1218 | 1219 | //------------------------------------------------------------------------------------ 1220 | // Texture Loading and Drawing Functions (Module: textures) 1221 | //------------------------------------------------------------------------------------ 1222 | 1223 | // Image loading functions 1224 | // NOTE: This functions do not require GPU access 1225 | RLAPI Image LoadImage(const char *fileName); // Load image from file into CPU memory (RAM) 1226 | RLAPI Image LoadImageRaw(const char *fileName, int width, int height, int format, int headerSize); // Load image from RAW file data 1227 | RLAPI Image LoadImageAnim(const char *fileName, int *frames); // Load image sequence from file (frames appended to image.data) 1228 | RLAPI Image LoadImageFromMemory(const char *fileType, const unsigned char *fileData, int dataSize); // Load image from memory buffer, fileType refers to extension: i.e. '.png' 1229 | RLAPI Image LoadImageFromTexture(Texture2D texture); // Load image from GPU texture data 1230 | RLAPI Image LoadImageFromScreen(void); // Load image from screen buffer and (screenshot) 1231 | RLAPI void UnloadImage(Image image); // Unload image from CPU memory (RAM) 1232 | RLAPI bool ExportImage(Image image, const char *fileName); // Export image data to file, returns true on success 1233 | RLAPI bool ExportImageAsCode(Image image, const char *fileName); // Export image as code file defining an array of bytes, returns true on success 1234 | 1235 | // Image generation functions 1236 | RLAPI Image GenImageColor(int width, int height, Color color); // Generate image: plain color 1237 | RLAPI Image GenImageGradientV(int width, int height, Color top, Color bottom); // Generate image: vertical gradient 1238 | RLAPI Image GenImageGradientH(int width, int height, Color left, Color right); // Generate image: horizontal gradient 1239 | RLAPI Image GenImageGradientRadial(int width, int height, float density, Color inner, Color outer); // Generate image: radial gradient 1240 | RLAPI Image GenImageChecked(int width, int height, int checksX, int checksY, Color col1, Color col2); // Generate image: checked 1241 | RLAPI Image GenImageWhiteNoise(int width, int height, float factor); // Generate image: white noise 1242 | RLAPI Image GenImageCellular(int width, int height, int tileSize); // Generate image: cellular algorithm, bigger tileSize means bigger cells 1243 | 1244 | // Image manipulation functions 1245 | RLAPI Image ImageCopy(Image image); // Create an image duplicate (useful for transformations) 1246 | RLAPI Image ImageFromImage(Image image, Rectangle rec); // Create an image from another image piece 1247 | RLAPI Image ImageText(const char *text, int fontSize, Color color); // Create an image from text (default font) 1248 | RLAPI Image ImageTextEx(Font font, const char *text, float fontSize, float spacing, Color tint); // Create an image from text (custom sprite font) 1249 | RLAPI void ImageFormat(Image *image, int newFormat); // Convert image data to desired format 1250 | RLAPI void ImageToPOT(Image *image, Color fill); // Convert image to POT (power-of-two) 1251 | RLAPI void ImageCrop(Image *image, Rectangle crop); // Crop an image to a defined rectangle 1252 | RLAPI void ImageAlphaCrop(Image *image, float threshold); // Crop image depending on alpha value 1253 | RLAPI void ImageAlphaClear(Image *image, Color color, float threshold); // Clear alpha channel to desired color 1254 | RLAPI void ImageAlphaMask(Image *image, Image alphaMask); // Apply alpha mask to image 1255 | RLAPI void ImageAlphaPremultiply(Image *image); // Premultiply alpha channel 1256 | RLAPI void ImageResize(Image *image, int newWidth, int newHeight); // Resize image (Bicubic scaling algorithm) 1257 | RLAPI void ImageResizeNN(Image *image, int newWidth,int newHeight); // Resize image (Nearest-Neighbor scaling algorithm) 1258 | RLAPI void ImageResizeCanvas(Image *image, int newWidth, int newHeight, int offsetX, int offsetY, Color fill); // Resize canvas and fill with color 1259 | RLAPI void ImageMipmaps(Image *image); // Compute all mipmap levels for a provided image 1260 | RLAPI void ImageDither(Image *image, int rBpp, int gBpp, int bBpp, int aBpp); // Dither image data to 16bpp or lower (Floyd-Steinberg dithering) 1261 | RLAPI void ImageFlipVertical(Image *image); // Flip image vertically 1262 | RLAPI void ImageFlipHorizontal(Image *image); // Flip image horizontally 1263 | RLAPI void ImageRotateCW(Image *image); // Rotate image clockwise 90deg 1264 | RLAPI void ImageRotateCCW(Image *image); // Rotate image counter-clockwise 90deg 1265 | RLAPI void ImageColorTint(Image *image, Color color); // Modify image color: tint 1266 | RLAPI void ImageColorInvert(Image *image); // Modify image color: invert 1267 | RLAPI void ImageColorGrayscale(Image *image); // Modify image color: grayscale 1268 | RLAPI void ImageColorContrast(Image *image, float contrast); // Modify image color: contrast (-100 to 100) 1269 | RLAPI void ImageColorBrightness(Image *image, int brightness); // Modify image color: brightness (-255 to 255) 1270 | RLAPI void ImageColorReplace(Image *image, Color color, Color replace); // Modify image color: replace color 1271 | RLAPI Color *LoadImageColors(Image image); // Load color data from image as a Color array (RGBA - 32bit) 1272 | RLAPI Color *LoadImagePalette(Image image, int maxPaletteSize, int *colorCount); // Load colors palette from image as a Color array (RGBA - 32bit) 1273 | RLAPI void UnloadImageColors(Color *colors); // Unload color data loaded with LoadImageColors() 1274 | RLAPI void UnloadImagePalette(Color *colors); // Unload colors palette loaded with LoadImagePalette() 1275 | RLAPI Rectangle GetImageAlphaBorder(Image image, float threshold); // Get image alpha border rectangle 1276 | RLAPI Color GetImageColor(Image image, int x, int y); // Get image pixel color at (x, y) position 1277 | 1278 | // Image drawing functions 1279 | // NOTE: Image software-rendering functions (CPU) 1280 | RLAPI void ImageClearBackground(Image *dst, Color color); // Clear image background with given color 1281 | RLAPI void ImageDrawPixel(Image *dst, int posX, int posY, Color color); // Draw pixel within an image 1282 | RLAPI void ImageDrawPixelV(Image *dst, Vector2 position, Color color); // Draw pixel within an image (Vector version) 1283 | RLAPI void ImageDrawLine(Image *dst, int startPosX, int startPosY, int endPosX, int endPosY, Color color); // Draw line within an image 1284 | RLAPI void ImageDrawLineV(Image *dst, Vector2 start, Vector2 end, Color color); // Draw line within an image (Vector version) 1285 | RLAPI void ImageDrawCircle(Image *dst, int centerX, int centerY, int radius, Color color); // Draw circle within an image 1286 | RLAPI void ImageDrawCircleV(Image *dst, Vector2 center, int radius, Color color); // Draw circle within an image (Vector version) 1287 | RLAPI void ImageDrawRectangle(Image *dst, int posX, int posY, int width, int height, Color color); // Draw rectangle within an image 1288 | RLAPI void ImageDrawRectangleV(Image *dst, Vector2 position, Vector2 size, Color color); // Draw rectangle within an image (Vector version) 1289 | RLAPI void ImageDrawRectangleRec(Image *dst, Rectangle rec, Color color); // Draw rectangle within an image 1290 | RLAPI void ImageDrawRectangleLines(Image *dst, Rectangle rec, int thick, Color color); // Draw rectangle lines within an image 1291 | 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) 1292 | 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) 1293 | 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) 1294 | 1295 | // Texture loading functions 1296 | // NOTE: These functions require GPU access 1297 | RLAPI Texture2D LoadTexture(const char *fileName); // Load texture from file into GPU memory (VRAM) 1298 | RLAPI Texture2D LoadTextureFromImage(Image image); // Load texture from image data 1299 | RLAPI TextureCubemap LoadTextureCubemap(Image image, int layout); // Load cubemap from image, multiple image cubemap layouts supported 1300 | RLAPI RenderTexture2D LoadRenderTexture(int width, int height); // Load texture for rendering (framebuffer) 1301 | RLAPI void UnloadTexture(Texture2D texture); // Unload texture from GPU memory (VRAM) 1302 | RLAPI void UnloadRenderTexture(RenderTexture2D target); // Unload render texture from GPU memory (VRAM) 1303 | RLAPI void UpdateTexture(Texture2D texture, const void *pixels); // Update GPU texture with new data 1304 | RLAPI void UpdateTextureRec(Texture2D texture, Rectangle rec, const void *pixels); // Update GPU texture rectangle with new data 1305 | 1306 | // Texture configuration functions 1307 | RLAPI void GenTextureMipmaps(Texture2D *texture); // Generate GPU mipmaps for a texture 1308 | RLAPI void SetTextureFilter(Texture2D texture, int filter); // Set texture scaling filter mode 1309 | RLAPI void SetTextureWrap(Texture2D texture, int wrap); // Set texture wrapping mode 1310 | 1311 | // Texture drawing functions 1312 | RLAPI void DrawTexture(Texture2D texture, int posX, int posY, Color tint); // Draw a Texture2D 1313 | RLAPI void DrawTextureV(Texture2D texture, Vector2 position, Color tint); // Draw a Texture2D with position defined as Vector2 1314 | RLAPI void DrawTextureEx(Texture2D texture, Vector2 position, float rotation, float scale, Color tint); // Draw a Texture2D with extended parameters 1315 | RLAPI void DrawTextureRec(Texture2D texture, Rectangle source, Vector2 position, Color tint); // Draw a part of a texture defined by a rectangle 1316 | RLAPI void DrawTextureQuad(Texture2D texture, Vector2 tiling, Vector2 offset, Rectangle quad, Color tint); // Draw texture quad with tiling and offset parameters 1317 | RLAPI void DrawTextureTiled(Texture2D texture, Rectangle source, Rectangle dest, Vector2 origin, float rotation, float scale, Color tint); // Draw part of a texture (defined by a rectangle) with rotation and scale tiled into dest. 1318 | 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 1319 | 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 1320 | RLAPI void DrawTexturePoly(Texture2D texture, Vector2 center, Vector2 *points, Vector2 *texcoords, int pointCount, Color tint); // Draw a textured polygon 1321 | 1322 | // Color/pixel related functions 1323 | RLAPI Color Fade(Color color, float alpha); // Get color with alpha applied, alpha goes from 0.0f to 1.0f 1324 | RLAPI int ColorToInt(Color color); // Get hexadecimal value for a Color 1325 | RLAPI Vector4 ColorNormalize(Color color); // Get Color normalized as float [0..1] 1326 | RLAPI Color ColorFromNormalized(Vector4 normalized); // Get Color from normalized values [0..1] 1327 | RLAPI Vector3 ColorToHSV(Color color); // Get HSV values for a Color, hue [0..360], saturation/value [0..1] 1328 | RLAPI Color ColorFromHSV(float hue, float saturation, float value); // Get a Color from HSV values, hue [0..360], saturation/value [0..1] 1329 | RLAPI Color ColorAlpha(Color color, float alpha); // Get color with alpha applied, alpha goes from 0.0f to 1.0f 1330 | RLAPI Color ColorAlphaBlend(Color dst, Color src, Color tint); // Get src alpha-blended into dst color with tint 1331 | RLAPI Color GetColor(unsigned int hexValue); // Get Color structure from hexadecimal value 1332 | RLAPI Color GetPixelColor(void *srcPtr, int format); // Get Color from a source pixel pointer of certain format 1333 | RLAPI void SetPixelColor(void *dstPtr, Color color, int format); // Set color formatted into destination pixel pointer 1334 | RLAPI int GetPixelDataSize(int width, int height, int format); // Get pixel data size in bytes for certain format 1335 | 1336 | //------------------------------------------------------------------------------------ 1337 | // Font Loading and Text Drawing Functions (Module: text) 1338 | //------------------------------------------------------------------------------------ 1339 | 1340 | // Font loading/unloading functions 1341 | RLAPI Font GetFontDefault(void); // Get the default Font 1342 | RLAPI Font LoadFont(const char *fileName); // Load font from file into GPU memory (VRAM) 1343 | RLAPI Font LoadFontEx(const char *fileName, int fontSize, int *fontChars, int glyphCount); // Load font from file with extended parameters, use NULL for fontChars and 0 for glyphCount to load the default character set 1344 | RLAPI Font LoadFontFromImage(Image image, Color key, int firstChar); // Load font from Image (XNA style) 1345 | RLAPI Font LoadFontFromMemory(const char *fileType, const unsigned char *fileData, int dataSize, int fontSize, int *fontChars, int glyphCount); // Load font from memory buffer, fileType refers to extension: i.e. '.ttf' 1346 | RLAPI GlyphInfo *LoadFontData(const unsigned char *fileData, int dataSize, int fontSize, int *fontChars, int glyphCount, int type); // Load font data for further use 1347 | RLAPI Image GenImageFontAtlas(const GlyphInfo *chars, Rectangle **recs, int glyphCount, int fontSize, int padding, int packMethod); // Generate image font atlas using chars info 1348 | RLAPI void UnloadFontData(GlyphInfo *chars, int glyphCount); // Unload font chars info data (RAM) 1349 | RLAPI void UnloadFont(Font font); // Unload font from GPU memory (VRAM) 1350 | RLAPI bool ExportFontAsCode(Font font, const char *fileName); // Export font as code file, returns true on success 1351 | 1352 | // Text drawing functions 1353 | RLAPI void DrawFPS(int posX, int posY); // Draw current FPS 1354 | RLAPI void DrawText(const char *text, int posX, int posY, int fontSize, Color color); // Draw text (using default font) 1355 | RLAPI void DrawTextEx(Font font, const char *text, Vector2 position, float fontSize, float spacing, Color tint); // Draw text using font and additional parameters 1356 | 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) 1357 | RLAPI void DrawTextCodepoint(Font font, int codepoint, Vector2 position, float fontSize, Color tint); // Draw one character (codepoint) 1358 | RLAPI void DrawTextCodepoints(Font font, const int *codepoints, int count, Vector2 position, float fontSize, float spacing, Color tint); // Draw multiple character (codepoint) 1359 | 1360 | // Text font info functions 1361 | RLAPI int MeasureText(const char *text, int fontSize); // Measure string width for default font 1362 | RLAPI Vector2 MeasureTextEx(Font font, const char *text, float fontSize, float spacing); // Measure string size for Font 1363 | RLAPI int GetGlyphIndex(Font font, int codepoint); // Get glyph index position in font for a codepoint (unicode character), fallback to '?' if not found 1364 | RLAPI GlyphInfo GetGlyphInfo(Font font, int codepoint); // Get glyph font info data for a codepoint (unicode character), fallback to '?' if not found 1365 | RLAPI Rectangle GetGlyphAtlasRec(Font font, int codepoint); // Get glyph rectangle in font atlas for a codepoint (unicode character), fallback to '?' if not found 1366 | 1367 | // Text codepoints management functions (unicode characters) 1368 | RLAPI int *LoadCodepoints(const char *text, int *count); // Load all codepoints from a UTF-8 text string, codepoints count returned by parameter 1369 | RLAPI void UnloadCodepoints(int *codepoints); // Unload codepoints data from memory 1370 | RLAPI int GetCodepointCount(const char *text); // Get total number of codepoints in a UTF-8 encoded string 1371 | RLAPI int GetCodepoint(const char *text, int *bytesProcessed); // Get next codepoint in a UTF-8 encoded string, 0x3f('?') is returned on failure 1372 | RLAPI const char *CodepointToUTF8(int codepoint, int *byteSize); // Encode one codepoint into UTF-8 byte array (array length returned as parameter) 1373 | RLAPI char *TextCodepointsToUTF8(const int *codepoints, int length); // Encode text as codepoints array into UTF-8 text string (WARNING: memory must be freed!) 1374 | 1375 | // Text strings management functions (no UTF-8 strings, only byte chars) 1376 | // NOTE: Some strings allocate memory internally for returned strings, just be careful! 1377 | RLAPI int TextCopy(char *dst, const char *src); // Copy one string to another, returns bytes copied 1378 | RLAPI bool TextIsEqual(const char *text1, const char *text2); // Check if two text string are equal 1379 | RLAPI unsigned int TextLength(const char *text); // Get text length, checks for '\0' ending 1380 | RLAPI const char *TextFormat(const char *text, ...); // Text formatting with variables (sprintf() style) 1381 | RLAPI const char *TextSubtext(const char *text, int position, int length); // Get a piece of a text string 1382 | RLAPI char *TextReplace(char *text, const char *replace, const char *by); // Replace text string (WARNING: memory must be freed!) 1383 | RLAPI char *TextInsert(const char *text, const char *insert, int position); // Insert text in a position (WARNING: memory must be freed!) 1384 | RLAPI const char *TextJoin(const char **textList, int count, const char *delimiter); // Join text strings with delimiter 1385 | RLAPI const char **TextSplit(const char *text, char delimiter, int *count); // Split text into multiple strings 1386 | RLAPI void TextAppend(char *text, const char *append, int *position); // Append text at specific position and move cursor! 1387 | RLAPI int TextFindIndex(const char *text, const char *find); // Find first text occurrence within a string 1388 | RLAPI const char *TextToUpper(const char *text); // Get upper case version of provided string 1389 | RLAPI const char *TextToLower(const char *text); // Get lower case version of provided string 1390 | RLAPI const char *TextToPascal(const char *text); // Get Pascal case notation version of provided string 1391 | RLAPI int TextToInteger(const char *text); // Get integer value from text (negative values not supported) 1392 | 1393 | //------------------------------------------------------------------------------------ 1394 | // Basic 3d Shapes Drawing Functions (Module: models) 1395 | //------------------------------------------------------------------------------------ 1396 | 1397 | // Basic geometric 3D shapes drawing functions 1398 | RLAPI void DrawLine3D(Vector3 startPos, Vector3 endPos, Color color); // Draw a line in 3D world space 1399 | RLAPI void DrawPoint3D(Vector3 position, Color color); // Draw a point in 3D space, actually a small line 1400 | RLAPI void DrawCircle3D(Vector3 center, float radius, Vector3 rotationAxis, float rotationAngle, Color color); // Draw a circle in 3D world space 1401 | RLAPI void DrawTriangle3D(Vector3 v1, Vector3 v2, Vector3 v3, Color color); // Draw a color-filled triangle (vertex in counter-clockwise order!) 1402 | RLAPI void DrawTriangleStrip3D(Vector3 *points, int pointCount, Color color); // Draw a triangle strip defined by points 1403 | RLAPI void DrawCube(Vector3 position, float width, float height, float length, Color color); // Draw cube 1404 | RLAPI void DrawCubeV(Vector3 position, Vector3 size, Color color); // Draw cube (Vector version) 1405 | RLAPI void DrawCubeWires(Vector3 position, float width, float height, float length, Color color); // Draw cube wires 1406 | RLAPI void DrawCubeWiresV(Vector3 position, Vector3 size, Color color); // Draw cube wires (Vector version) 1407 | RLAPI void DrawCubeTexture(Texture2D texture, Vector3 position, float width, float height, float length, Color color); // Draw cube textured 1408 | RLAPI void DrawCubeTextureRec(Texture2D texture, Rectangle source, Vector3 position, float width, float height, float length, Color color); // Draw cube with a region of a texture 1409 | RLAPI void DrawSphere(Vector3 centerPos, float radius, Color color); // Draw sphere 1410 | RLAPI void DrawSphereEx(Vector3 centerPos, float radius, int rings, int slices, Color color); // Draw sphere with extended parameters 1411 | RLAPI void DrawSphereWires(Vector3 centerPos, float radius, int rings, int slices, Color color); // Draw sphere wires 1412 | RLAPI void DrawCylinder(Vector3 position, float radiusTop, float radiusBottom, float height, int slices, Color color); // Draw a cylinder/cone 1413 | 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 1414 | RLAPI void DrawCylinderWires(Vector3 position, float radiusTop, float radiusBottom, float height, int slices, Color color); // Draw a cylinder/cone wires 1415 | 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 1416 | RLAPI void DrawPlane(Vector3 centerPos, Vector2 size, Color color); // Draw a plane XZ 1417 | RLAPI void DrawRay(Ray ray, Color color); // Draw a ray line 1418 | RLAPI void DrawGrid(int slices, float spacing); // Draw a grid (centered at (0, 0, 0)) 1419 | 1420 | //------------------------------------------------------------------------------------ 1421 | // Model 3d Loading and Drawing Functions (Module: models) 1422 | //------------------------------------------------------------------------------------ 1423 | 1424 | // Model management functions 1425 | RLAPI Model LoadModel(const char *fileName); // Load model from files (meshes and materials) 1426 | RLAPI Model LoadModelFromMesh(Mesh mesh); // Load model from generated mesh (default material) 1427 | RLAPI void UnloadModel(Model model); // Unload model (including meshes) from memory (RAM and/or VRAM) 1428 | RLAPI void UnloadModelKeepMeshes(Model model); // Unload model (but not meshes) from memory (RAM and/or VRAM) 1429 | RLAPI BoundingBox GetModelBoundingBox(Model model); // Compute model bounding box limits (considers all meshes) 1430 | 1431 | // Model drawing functions 1432 | RLAPI void DrawModel(Model model, Vector3 position, float scale, Color tint); // Draw a model (with texture if set) 1433 | RLAPI void DrawModelEx(Model model, Vector3 position, Vector3 rotationAxis, float rotationAngle, Vector3 scale, Color tint); // Draw a model with extended parameters 1434 | RLAPI void DrawModelWires(Model model, Vector3 position, float scale, Color tint); // Draw a model wires (with texture if set) 1435 | 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 1436 | RLAPI void DrawBoundingBox(BoundingBox box, Color color); // Draw bounding box (wires) 1437 | RLAPI void DrawBillboard(Camera camera, Texture2D texture, Vector3 position, float size, Color tint); // Draw a billboard texture 1438 | RLAPI void DrawBillboardRec(Camera camera, Texture2D texture, Rectangle source, Vector3 position, Vector2 size, Color tint); // Draw a billboard texture defined by source 1439 | 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 1440 | 1441 | // Mesh management functions 1442 | RLAPI void UploadMesh(Mesh *mesh, bool dynamic); // Upload mesh vertex data in GPU and provide VAO/VBO ids 1443 | 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 1444 | RLAPI void UnloadMesh(Mesh mesh); // Unload mesh data from CPU and GPU 1445 | RLAPI void DrawMesh(Mesh mesh, Material material, Matrix transform); // Draw a 3d mesh with material and transform 1446 | RLAPI void DrawMeshInstanced(Mesh mesh, Material material, const Matrix *transforms, int instances); // Draw multiple mesh instances with material and different transforms 1447 | RLAPI bool ExportMesh(Mesh mesh, const char *fileName); // Export mesh data to file, returns true on success 1448 | RLAPI BoundingBox GetMeshBoundingBox(Mesh mesh); // Compute mesh bounding box limits 1449 | RLAPI void GenMeshTangents(Mesh *mesh); // Compute mesh tangents 1450 | 1451 | // Mesh generation functions 1452 | RLAPI Mesh GenMeshPoly(int sides, float radius); // Generate polygonal mesh 1453 | RLAPI Mesh GenMeshPlane(float width, float length, int resX, int resZ); // Generate plane mesh (with subdivisions) 1454 | RLAPI Mesh GenMeshCube(float width, float height, float length); // Generate cuboid mesh 1455 | RLAPI Mesh GenMeshSphere(float radius, int rings, int slices); // Generate sphere mesh (standard sphere) 1456 | RLAPI Mesh GenMeshHemiSphere(float radius, int rings, int slices); // Generate half-sphere mesh (no bottom cap) 1457 | RLAPI Mesh GenMeshCylinder(float radius, float height, int slices); // Generate cylinder mesh 1458 | RLAPI Mesh GenMeshCone(float radius, float height, int slices); // Generate cone/pyramid mesh 1459 | RLAPI Mesh GenMeshTorus(float radius, float size, int radSeg, int sides); // Generate torus mesh 1460 | RLAPI Mesh GenMeshKnot(float radius, float size, int radSeg, int sides); // Generate trefoil knot mesh 1461 | RLAPI Mesh GenMeshHeightmap(Image heightmap, Vector3 size); // Generate heightmap mesh from image data 1462 | RLAPI Mesh GenMeshCubicmap(Image cubicmap, Vector3 cubeSize); // Generate cubes-based map mesh from image data 1463 | 1464 | // Material loading/unloading functions 1465 | RLAPI Material *LoadMaterials(const char *fileName, int *materialCount); // Load materials from model file 1466 | RLAPI Material LoadMaterialDefault(void); // Load default material (Supports: DIFFUSE, SPECULAR, NORMAL maps) 1467 | RLAPI void UnloadMaterial(Material material); // Unload material from GPU memory (VRAM) 1468 | RLAPI void SetMaterialTexture(Material *material, int mapType, Texture2D texture); // Set texture for a material map type (MATERIAL_MAP_DIFFUSE, MATERIAL_MAP_SPECULAR...) 1469 | RLAPI void SetModelMeshMaterial(Model *model, int meshId, int materialId); // Set material for a mesh 1470 | 1471 | // Model animations loading/unloading functions 1472 | RLAPI ModelAnimation *LoadModelAnimations(const char *fileName, unsigned int *animCount); // Load model animations from file 1473 | RLAPI void UpdateModelAnimation(Model model, ModelAnimation anim, int frame); // Update model animation pose 1474 | RLAPI void UnloadModelAnimation(ModelAnimation anim); // Unload animation data 1475 | RLAPI void UnloadModelAnimations(ModelAnimation *animations, unsigned int count); // Unload animation array data 1476 | RLAPI bool IsModelAnimationValid(Model model, ModelAnimation anim); // Check model animation skeleton match 1477 | 1478 | // Collision detection functions 1479 | RLAPI bool CheckCollisionSpheres(Vector3 center1, float radius1, Vector3 center2, float radius2); // Check collision between two spheres 1480 | RLAPI bool CheckCollisionBoxes(BoundingBox box1, BoundingBox box2); // Check collision between two bounding boxes 1481 | RLAPI bool CheckCollisionBoxSphere(BoundingBox box, Vector3 center, float radius); // Check collision between box and sphere 1482 | RLAPI RayCollision GetRayCollisionSphere(Ray ray, Vector3 center, float radius); // Get collision info between ray and sphere 1483 | RLAPI RayCollision GetRayCollisionBox(Ray ray, BoundingBox box); // Get collision info between ray and box 1484 | RLAPI RayCollision GetRayCollisionMesh(Ray ray, Mesh mesh, Matrix transform); // Get collision info between ray and mesh 1485 | RLAPI RayCollision GetRayCollisionTriangle(Ray ray, Vector3 p1, Vector3 p2, Vector3 p3); // Get collision info between ray and triangle 1486 | RLAPI RayCollision GetRayCollisionQuad(Ray ray, Vector3 p1, Vector3 p2, Vector3 p3, Vector3 p4); // Get collision info between ray and quad 1487 | 1488 | //------------------------------------------------------------------------------------ 1489 | // Audio Loading and Playing Functions (Module: audio) 1490 | //------------------------------------------------------------------------------------ 1491 | typedef void (*AudioCallback)(void *bufferData, unsigned int frames); 1492 | 1493 | // Audio device management functions 1494 | RLAPI void InitAudioDevice(void); // Initialize audio device and context 1495 | RLAPI void CloseAudioDevice(void); // Close the audio device and context 1496 | RLAPI bool IsAudioDeviceReady(void); // Check if audio device has been initialized successfully 1497 | RLAPI void SetMasterVolume(float volume); // Set master volume (listener) 1498 | 1499 | // Wave/Sound loading/unloading functions 1500 | RLAPI Wave LoadWave(const char *fileName); // Load wave data from file 1501 | RLAPI Wave LoadWaveFromMemory(const char *fileType, const unsigned char *fileData, int dataSize); // Load wave from memory buffer, fileType refers to extension: i.e. '.wav' 1502 | RLAPI Sound LoadSound(const char *fileName); // Load sound from file 1503 | RLAPI Sound LoadSoundFromWave(Wave wave); // Load sound from wave data 1504 | RLAPI void UpdateSound(Sound sound, const void *data, int sampleCount); // Update sound buffer with new data 1505 | RLAPI void UnloadWave(Wave wave); // Unload wave data 1506 | RLAPI void UnloadSound(Sound sound); // Unload sound 1507 | RLAPI bool ExportWave(Wave wave, const char *fileName); // Export wave data to file, returns true on success 1508 | RLAPI bool ExportWaveAsCode(Wave wave, const char *fileName); // Export wave sample data to code (.h), returns true on success 1509 | 1510 | // Wave/Sound management functions 1511 | RLAPI void PlaySound(Sound sound); // Play a sound 1512 | RLAPI void StopSound(Sound sound); // Stop playing a sound 1513 | RLAPI void PauseSound(Sound sound); // Pause a sound 1514 | RLAPI void ResumeSound(Sound sound); // Resume a paused sound 1515 | RLAPI void PlaySoundMulti(Sound sound); // Play a sound (using multichannel buffer pool) 1516 | RLAPI void StopSoundMulti(void); // Stop any sound playing (using multichannel buffer pool) 1517 | RLAPI int GetSoundsPlaying(void); // Get number of sounds playing in the multichannel 1518 | RLAPI bool IsSoundPlaying(Sound sound); // Check if a sound is currently playing 1519 | RLAPI void SetSoundVolume(Sound sound, float volume); // Set volume for a sound (1.0 is max level) 1520 | RLAPI void SetSoundPitch(Sound sound, float pitch); // Set pitch for a sound (1.0 is base level) 1521 | RLAPI void SetSoundPan(Sound sound, float pan); // Set pan for a sound (0.5 is center) 1522 | RLAPI Wave WaveCopy(Wave wave); // Copy a wave to a new wave 1523 | RLAPI void WaveCrop(Wave *wave, int initSample, int finalSample); // Crop a wave to defined samples range 1524 | RLAPI void WaveFormat(Wave *wave, int sampleRate, int sampleSize, int channels); // Convert wave data to desired format 1525 | RLAPI float *LoadWaveSamples(Wave wave); // Load samples data from wave as a 32bit float data array 1526 | RLAPI void UnloadWaveSamples(float *samples); // Unload samples data loaded with LoadWaveSamples() 1527 | 1528 | // Music management functions 1529 | RLAPI Music LoadMusicStream(const char *fileName); // Load music stream from file 1530 | RLAPI Music LoadMusicStreamFromMemory(const char *fileType, const unsigned char *data, int dataSize); // Load music stream from data 1531 | RLAPI void UnloadMusicStream(Music music); // Unload music stream 1532 | RLAPI void PlayMusicStream(Music music); // Start music playing 1533 | RLAPI bool IsMusicStreamPlaying(Music music); // Check if music is playing 1534 | RLAPI void UpdateMusicStream(Music music); // Updates buffers for music streaming 1535 | RLAPI void StopMusicStream(Music music); // Stop music playing 1536 | RLAPI void PauseMusicStream(Music music); // Pause music playing 1537 | RLAPI void ResumeMusicStream(Music music); // Resume playing paused music 1538 | RLAPI void SeekMusicStream(Music music, float position); // Seek music to a position (in seconds) 1539 | RLAPI void SetMusicVolume(Music music, float volume); // Set volume for music (1.0 is max level) 1540 | RLAPI void SetMusicPitch(Music music, float pitch); // Set pitch for a music (1.0 is base level) 1541 | RLAPI void SetMusicPan(Music music, float pan); // Set pan for a music (0.5 is center) 1542 | RLAPI float GetMusicTimeLength(Music music); // Get music time length (in seconds) 1543 | RLAPI float GetMusicTimePlayed(Music music); // Get current music time played (in seconds) 1544 | 1545 | // AudioStream management functions 1546 | RLAPI AudioStream LoadAudioStream(unsigned int sampleRate, unsigned int sampleSize, unsigned int channels); // Load audio stream (to stream raw audio pcm data) 1547 | RLAPI void UnloadAudioStream(AudioStream stream); // Unload audio stream and free memory 1548 | RLAPI void UpdateAudioStream(AudioStream stream, const void *data, int frameCount); // Update audio stream buffers with data 1549 | RLAPI bool IsAudioStreamProcessed(AudioStream stream); // Check if any audio stream buffers requires refill 1550 | RLAPI void PlayAudioStream(AudioStream stream); // Play audio stream 1551 | RLAPI void PauseAudioStream(AudioStream stream); // Pause audio stream 1552 | RLAPI void ResumeAudioStream(AudioStream stream); // Resume audio stream 1553 | RLAPI bool IsAudioStreamPlaying(AudioStream stream); // Check if audio stream is playing 1554 | RLAPI void StopAudioStream(AudioStream stream); // Stop audio stream 1555 | RLAPI void SetAudioStreamVolume(AudioStream stream, float volume); // Set volume for audio stream (1.0 is max level) 1556 | RLAPI void SetAudioStreamPitch(AudioStream stream, float pitch); // Set pitch for audio stream (1.0 is base level) 1557 | RLAPI void SetAudioStreamPan(AudioStream stream, float pan); // Set pan for audio stream (0.5 is centered) 1558 | RLAPI void SetAudioStreamBufferSizeDefault(int size); // Default size for new audio streams 1559 | RLAPI void SetAudioStreamCallback(AudioStream stream, AudioCallback callback); // Audio thread callback to request new data 1560 | 1561 | RLAPI void AttachAudioStreamProcessor(AudioStream stream, AudioCallback processor); // Attach audio stream processor to stream 1562 | RLAPI void DetachAudioStreamProcessor(AudioStream stream, AudioCallback processor); // Detach audio stream processor from stream 1563 | 1564 | #if defined(__cplusplus) 1565 | } 1566 | #endif 1567 | 1568 | #endif // RAYLIB_H 1569 | -------------------------------------------------------------------------------- /lib/raymath.h: -------------------------------------------------------------------------------- 1 | /********************************************************************************************** 2 | * 3 | * raymath v1.5 - Math functions to work with Vector2, Vector3, Matrix and Quaternions 4 | * 5 | * CONFIGURATION: 6 | * 7 | * #define RAYMATH_IMPLEMENTATION 8 | * Generates the implementation of the library into the included file. 9 | * If not defined, the library is in header only mode and can be included in other headers 10 | * or source files without problems. But only ONE file should hold the implementation. 11 | * 12 | * #define RAYMATH_STATIC_INLINE 13 | * Define static inline functions code, so #include header suffices for use. 14 | * This may use up lots of memory. 15 | * 16 | * CONVENTIONS: 17 | * 18 | * - Functions are always self-contained, no function use another raymath function inside, 19 | * required code is directly re-implemented inside 20 | * - Functions input parameters are always received by value (2 unavoidable exceptions) 21 | * - Functions use always a "result" variable for return 22 | * - Functions are always defined inline 23 | * - Angles are always in radians (DEG2RAD/RAD2DEG macros provided for convenience) 24 | * 25 | * 26 | * LICENSE: zlib/libpng 27 | * 28 | * Copyright (c) 2015-2022 Ramon Santamaria (@raysan5) 29 | * 30 | * This software is provided "as-is", without any express or implied warranty. In no event 31 | * will the authors be held liable for any damages arising from the use of this software. 32 | * 33 | * Permission is granted to anyone to use this software for any purpose, including commercial 34 | * applications, and to alter it and redistribute it freely, subject to the following restrictions: 35 | * 36 | * 1. The origin of this software must not be misrepresented; you must not claim that you 37 | * wrote the original software. If you use this software in a product, an acknowledgment 38 | * in the product documentation would be appreciated but is not required. 39 | * 40 | * 2. Altered source versions must be plainly marked as such, and must not be misrepresented 41 | * as being the original software. 42 | * 43 | * 3. This notice may not be removed or altered from any source distribution. 44 | * 45 | **********************************************************************************************/ 46 | 47 | #ifndef RAYMATH_H 48 | #define RAYMATH_H 49 | 50 | #if defined(RAYMATH_IMPLEMENTATION) && defined(RAYMATH_STATIC_INLINE) 51 | #error "Specifying both RAYMATH_IMPLEMENTATION and RAYMATH_STATIC_INLINE is contradictory" 52 | #endif 53 | 54 | // Function specifiers definition 55 | #if defined(RAYMATH_IMPLEMENTATION) 56 | #if defined(_WIN32) && defined(BUILD_LIBTYPE_SHARED) 57 | #define RMAPI __declspec(dllexport) extern inline // We are building raylib as a Win32 shared library (.dll). 58 | #elif defined(_WIN32) && defined(USE_LIBTYPE_SHARED) 59 | #define RMAPI __declspec(dllimport) // We are using raylib as a Win32 shared library (.dll) 60 | #else 61 | #define RMAPI extern inline // Provide external definition 62 | #endif 63 | #elif defined(RAYMATH_STATIC_INLINE) 64 | #define RMAPI static inline // Functions may be inlined, no external out-of-line definition 65 | #else 66 | #if defined(__TINYC__) 67 | #define RMAPI static inline // plain inline not supported by tinycc (See issue #435) 68 | #else 69 | #define RMAPI inline // Functions may be inlined or external definition used 70 | #endif 71 | #endif 72 | 73 | //---------------------------------------------------------------------------------- 74 | // Defines and Macros 75 | //---------------------------------------------------------------------------------- 76 | #ifndef PI 77 | #define PI 3.14159265358979323846f 78 | #endif 79 | 80 | #ifndef EPSILON 81 | #define EPSILON 0.000001f 82 | #endif 83 | 84 | #ifndef DEG2RAD 85 | #define DEG2RAD (PI/180.0f) 86 | #endif 87 | 88 | #ifndef RAD2DEG 89 | #define RAD2DEG (180.0f/PI) 90 | #endif 91 | 92 | // Get float vector for Matrix 93 | #ifndef MatrixToFloat 94 | #define MatrixToFloat(mat) (MatrixToFloatV(mat).v) 95 | #endif 96 | 97 | // Get float vector for Vector3 98 | #ifndef Vector3ToFloat 99 | #define Vector3ToFloat(vec) (Vector3ToFloatV(vec).v) 100 | #endif 101 | 102 | //---------------------------------------------------------------------------------- 103 | // Types and Structures Definition 104 | //---------------------------------------------------------------------------------- 105 | #if !defined(RL_VECTOR2_TYPE) 106 | // Vector2 type 107 | typedef struct Vector2 { 108 | float x; 109 | float y; 110 | } Vector2; 111 | #define RL_VECTOR2_TYPE 112 | #endif 113 | 114 | #if !defined(RL_VECTOR3_TYPE) 115 | // Vector3 type 116 | typedef struct Vector3 { 117 | float x; 118 | float y; 119 | float z; 120 | } Vector3; 121 | #define RL_VECTOR3_TYPE 122 | #endif 123 | 124 | #if !defined(RL_VECTOR4_TYPE) 125 | // Vector4 type 126 | typedef struct Vector4 { 127 | float x; 128 | float y; 129 | float z; 130 | float w; 131 | } Vector4; 132 | #define RL_VECTOR4_TYPE 133 | #endif 134 | 135 | #if !defined(RL_QUATERNION_TYPE) 136 | // Quaternion type 137 | typedef Vector4 Quaternion; 138 | #define RL_QUATERNION_TYPE 139 | #endif 140 | 141 | #if !defined(RL_MATRIX_TYPE) 142 | // Matrix type (OpenGL style 4x4 - right handed, column major) 143 | typedef struct Matrix { 144 | float m0, m4, m8, m12; // Matrix first row (4 components) 145 | float m1, m5, m9, m13; // Matrix second row (4 components) 146 | float m2, m6, m10, m14; // Matrix third row (4 components) 147 | float m3, m7, m11, m15; // Matrix fourth row (4 components) 148 | } Matrix; 149 | #define RL_MATRIX_TYPE 150 | #endif 151 | 152 | // NOTE: Helper types to be used instead of array return types for *ToFloat functions 153 | typedef struct float3 { 154 | float v[3]; 155 | } float3; 156 | 157 | typedef struct float16 { 158 | float v[16]; 159 | } float16; 160 | 161 | #include // Required for: sinf(), cosf(), tan(), atan2f(), sqrtf(), floor(), fminf(), fmaxf(), fabs() 162 | 163 | //---------------------------------------------------------------------------------- 164 | // Module Functions Definition - Utils math 165 | //---------------------------------------------------------------------------------- 166 | 167 | // Clamp float value 168 | RMAPI float Clamp(float value, float min, float max) 169 | { 170 | float result = (value < min)? min : value; 171 | 172 | if (result > max) result = max; 173 | 174 | return result; 175 | } 176 | 177 | // Calculate linear interpolation between two floats 178 | RMAPI float Lerp(float start, float end, float amount) 179 | { 180 | float result = start + amount*(end - start); 181 | 182 | return result; 183 | } 184 | 185 | // Normalize input value within input range 186 | RMAPI float Normalize(float value, float start, float end) 187 | { 188 | float result = (value - start)/(end - start); 189 | 190 | return result; 191 | } 192 | 193 | // Remap input value within input range to output range 194 | RMAPI float Remap(float value, float inputStart, float inputEnd, float outputStart, float outputEnd) 195 | { 196 | float result = (value - inputStart)/(inputEnd - inputStart)*(outputEnd - outputStart) + outputStart; 197 | 198 | return result; 199 | } 200 | 201 | // Wrap input value from min to max 202 | RMAPI float Wrap(float value, float min, float max) 203 | { 204 | float result = value - (max - min)*floorf((value - min)/(max - min)); 205 | 206 | return result; 207 | } 208 | 209 | // Check whether two given floats are almost equal 210 | RMAPI int FloatEquals(float x, float y) 211 | { 212 | int result = (fabsf(x - y)) <= (EPSILON*fmaxf(1.0f, fmaxf(fabsf(x), fabsf(y)))); 213 | 214 | return result; 215 | } 216 | 217 | //---------------------------------------------------------------------------------- 218 | // Module Functions Definition - Vector2 math 219 | //---------------------------------------------------------------------------------- 220 | 221 | // Vector with components value 0.0f 222 | RMAPI Vector2 Vector2Zero(void) 223 | { 224 | Vector2 result = { 0.0f, 0.0f }; 225 | 226 | return result; 227 | } 228 | 229 | // Vector with components value 1.0f 230 | RMAPI Vector2 Vector2One(void) 231 | { 232 | Vector2 result = { 1.0f, 1.0f }; 233 | 234 | return result; 235 | } 236 | 237 | // Add two vectors (v1 + v2) 238 | RMAPI Vector2 Vector2Add(Vector2 v1, Vector2 v2) 239 | { 240 | Vector2 result = { v1.x + v2.x, v1.y + v2.y }; 241 | 242 | return result; 243 | } 244 | 245 | // Add vector and float value 246 | RMAPI Vector2 Vector2AddValue(Vector2 v, float add) 247 | { 248 | Vector2 result = { v.x + add, v.y + add }; 249 | 250 | return result; 251 | } 252 | 253 | // Subtract two vectors (v1 - v2) 254 | RMAPI Vector2 Vector2Subtract(Vector2 v1, Vector2 v2) 255 | { 256 | Vector2 result = { v1.x - v2.x, v1.y - v2.y }; 257 | 258 | return result; 259 | } 260 | 261 | // Subtract vector by float value 262 | RMAPI Vector2 Vector2SubtractValue(Vector2 v, float sub) 263 | { 264 | Vector2 result = { v.x - sub, v.y - sub }; 265 | 266 | return result; 267 | } 268 | 269 | // Calculate vector length 270 | RMAPI float Vector2Length(Vector2 v) 271 | { 272 | float result = sqrtf((v.x*v.x) + (v.y*v.y)); 273 | 274 | return result; 275 | } 276 | 277 | // Calculate vector square length 278 | RMAPI float Vector2LengthSqr(Vector2 v) 279 | { 280 | float result = (v.x*v.x) + (v.y*v.y); 281 | 282 | return result; 283 | } 284 | 285 | // Calculate two vectors dot product 286 | RMAPI float Vector2DotProduct(Vector2 v1, Vector2 v2) 287 | { 288 | float result = (v1.x*v2.x + v1.y*v2.y); 289 | 290 | return result; 291 | } 292 | 293 | // Calculate distance between two vectors 294 | RMAPI float Vector2Distance(Vector2 v1, Vector2 v2) 295 | { 296 | float result = sqrtf((v1.x - v2.x)*(v1.x - v2.x) + (v1.y - v2.y)*(v1.y - v2.y)); 297 | 298 | return result; 299 | } 300 | 301 | //Calculate magnetude of vector 302 | RMAPI float Vector2Magnitude(Vector2 v1) 303 | { 304 | float result = sqrt(v1.x * v1.x + v1.y * v1.y); 305 | 306 | return result; 307 | } 308 | 309 | // Calculate square distance between two vectors 310 | RMAPI float Vector2DistanceSqr(Vector2 v1, Vector2 v2) 311 | { 312 | float result = ((v1.x - v2.x)*(v1.x - v2.x) + (v1.y - v2.y)*(v1.y - v2.y)); 313 | 314 | return result; 315 | } 316 | 317 | // Calculate angle from two vectors 318 | RMAPI float Vector2Angle(Vector2 v1, Vector2 v2) 319 | { 320 | float result = atan2f(v2.y, v2.x) - atan2f(v1.y, v1.x); 321 | 322 | return result; 323 | } 324 | 325 | // Scale vector (multiply by value) 326 | RMAPI Vector2 Vector2Scale(Vector2 v, float scale) 327 | { 328 | Vector2 result = { v.x*scale, v.y*scale }; 329 | 330 | return result; 331 | } 332 | 333 | // Multiply vector by vector 334 | RMAPI Vector2 Vector2Multiply(Vector2 v1, Vector2 v2) 335 | { 336 | Vector2 result = { v1.x*v2.x, v1.y*v2.y }; 337 | 338 | return result; 339 | } 340 | 341 | // Negate vector 342 | RMAPI Vector2 Vector2Negate(Vector2 v) 343 | { 344 | Vector2 result = { -v.x, -v.y }; 345 | 346 | return result; 347 | } 348 | 349 | // Divide vector by vector 350 | RMAPI Vector2 Vector2Divide(Vector2 v1, Vector2 v2) 351 | { 352 | Vector2 result = { v1.x/v2.x, v1.y/v2.y }; 353 | 354 | return result; 355 | } 356 | 357 | // Normalize provided vector 358 | RMAPI Vector2 Vector2Normalize(Vector2 v) 359 | { 360 | Vector2 result = { 0 }; 361 | float length = sqrtf((v.x*v.x) + (v.y*v.y)); 362 | 363 | if (length > 0) 364 | { 365 | float ilength = 1.0f/length; 366 | result.x = v.x*ilength; 367 | result.y = v.y*ilength; 368 | } 369 | 370 | return result; 371 | } 372 | 373 | // Transforms a Vector2 by a given Matrix 374 | RMAPI Vector2 Vector2Transform(Vector2 v, Matrix mat) 375 | { 376 | Vector2 result = { 0 }; 377 | 378 | float x = v.x; 379 | float y = v.y; 380 | float z = 0; 381 | 382 | result.x = mat.m0*x + mat.m4*y + mat.m8*z + mat.m12; 383 | result.y = mat.m1*x + mat.m5*y + mat.m9*z + mat.m13; 384 | 385 | return result; 386 | } 387 | 388 | // Calculate linear interpolation between two vectors 389 | RMAPI Vector2 Vector2Lerp(Vector2 v1, Vector2 v2, float amount) 390 | { 391 | Vector2 result = { 0 }; 392 | 393 | result.x = v1.x + amount*(v2.x - v1.x); 394 | result.y = v1.y + amount*(v2.y - v1.y); 395 | 396 | return result; 397 | } 398 | 399 | // Calculate reflected vector to normal 400 | RMAPI Vector2 Vector2Reflect(Vector2 v, Vector2 normal) 401 | { 402 | Vector2 result = { 0 }; 403 | 404 | float dotProduct = (v.x*normal.x + v.y*normal.y); // Dot product 405 | 406 | result.x = v.x - (2.0f*normal.x)*dotProduct; 407 | result.y = v.y - (2.0f*normal.y)*dotProduct; 408 | 409 | return result; 410 | } 411 | 412 | // Rotate vector by angle 413 | RMAPI Vector2 Vector2Rotate(Vector2 v, float angle) 414 | { 415 | Vector2 result = { 0 }; 416 | 417 | float cosres = cosf(angle); 418 | float sinres = sinf(angle); 419 | 420 | result.x = v.x*cosres - v.y*sinres; 421 | result.y = v.x*sinres + v.y*cosres; 422 | 423 | return result; 424 | } 425 | 426 | // Move Vector towards target 427 | RMAPI Vector2 Vector2MoveTowards(Vector2 v, Vector2 target, float maxDistance) 428 | { 429 | Vector2 result = { 0 }; 430 | 431 | float dx = target.x - v.x; 432 | float dy = target.y - v.y; 433 | float value = (dx*dx) + (dy*dy); 434 | 435 | if ((value == 0) || ((maxDistance >= 0) && (value <= maxDistance*maxDistance))) return target; 436 | 437 | float dist = sqrtf(value); 438 | 439 | result.x = v.x + dx/dist*maxDistance; 440 | result.y = v.y + dy/dist*maxDistance; 441 | 442 | return result; 443 | } 444 | 445 | // Invert the given vector 446 | RMAPI Vector2 Vector2Invert(Vector2 v) 447 | { 448 | Vector2 result = { 1.0f/v.x, 1.0f/v.y }; 449 | 450 | return result; 451 | } 452 | 453 | // Clamp the components of the vector between 454 | // min and max values specified by the given vectors 455 | RMAPI Vector2 Vector2Clamp(Vector2 v, Vector2 min, Vector2 max) 456 | { 457 | Vector2 result = { 0 }; 458 | 459 | result.x = fminf(max.x, fmaxf(min.x, v.x)); 460 | result.y = fminf(max.y, fmaxf(min.y, v.y)); 461 | 462 | return result; 463 | } 464 | 465 | // Clamp the magnitude of the vector between two min and max values 466 | RMAPI Vector2 Vector2ClampValue(Vector2 v, float min, float max) 467 | { 468 | Vector2 result = v; 469 | 470 | float length = (v.x*v.x) + (v.y*v.y); 471 | if (length > 0.0f) 472 | { 473 | length = sqrtf(length); 474 | 475 | if (length < min) 476 | { 477 | float scale = min/length; 478 | result.x = v.x*scale; 479 | result.y = v.y*scale; 480 | } 481 | else if (length > max) 482 | { 483 | float scale = max/length; 484 | result.x = v.x*scale; 485 | result.y = v.y*scale; 486 | } 487 | } 488 | 489 | return result; 490 | } 491 | 492 | // Check whether two given vectors are almost equal 493 | RMAPI int Vector2Equals(Vector2 p, Vector2 q) 494 | { 495 | int result = ((fabsf(p.x - q.x)) <= (EPSILON*fmaxf(1.0f, fmaxf(fabsf(p.x), fabsf(q.x))))) && 496 | ((fabsf(p.y - q.y)) <= (EPSILON*fmaxf(1.0f, fmaxf(fabsf(p.y), fabsf(q.y))))); 497 | 498 | return result; 499 | } 500 | 501 | //---------------------------------------------------------------------------------- 502 | // Module Functions Definition - Vector3 math 503 | //---------------------------------------------------------------------------------- 504 | 505 | // Vector with components value 0.0f 506 | RMAPI Vector3 Vector3Zero(void) 507 | { 508 | Vector3 result = { 0.0f, 0.0f, 0.0f }; 509 | 510 | return result; 511 | } 512 | 513 | // Vector with components value 1.0f 514 | RMAPI Vector3 Vector3One(void) 515 | { 516 | Vector3 result = { 1.0f, 1.0f, 1.0f }; 517 | 518 | return result; 519 | } 520 | 521 | // Add two vectors 522 | RMAPI Vector3 Vector3Add(Vector3 v1, Vector3 v2) 523 | { 524 | Vector3 result = { v1.x + v2.x, v1.y + v2.y, v1.z + v2.z }; 525 | 526 | return result; 527 | } 528 | 529 | // Add vector and float value 530 | RMAPI Vector3 Vector3AddValue(Vector3 v, float add) 531 | { 532 | Vector3 result = { v.x + add, v.y + add, v.z + add }; 533 | 534 | return result; 535 | } 536 | 537 | // Subtract two vectors 538 | RMAPI Vector3 Vector3Subtract(Vector3 v1, Vector3 v2) 539 | { 540 | Vector3 result = { v1.x - v2.x, v1.y - v2.y, v1.z - v2.z }; 541 | 542 | return result; 543 | } 544 | 545 | // Subtract vector by float value 546 | RMAPI Vector3 Vector3SubtractValue(Vector3 v, float sub) 547 | { 548 | Vector3 result = { v.x - sub, v.y - sub, v.z - sub }; 549 | 550 | return result; 551 | } 552 | 553 | // Multiply vector by scalar 554 | RMAPI Vector3 Vector3Scale(Vector3 v, float scalar) 555 | { 556 | Vector3 result = { v.x*scalar, v.y*scalar, v.z*scalar }; 557 | 558 | return result; 559 | } 560 | 561 | // Multiply vector by vector 562 | RMAPI Vector3 Vector3Multiply(Vector3 v1, Vector3 v2) 563 | { 564 | Vector3 result = { v1.x*v2.x, v1.y*v2.y, v1.z*v2.z }; 565 | 566 | return result; 567 | } 568 | 569 | // Calculate two vectors cross product 570 | RMAPI Vector3 Vector3CrossProduct(Vector3 v1, Vector3 v2) 571 | { 572 | Vector3 result = { v1.y*v2.z - v1.z*v2.y, v1.z*v2.x - v1.x*v2.z, v1.x*v2.y - v1.y*v2.x }; 573 | 574 | return result; 575 | } 576 | 577 | // Calculate one vector perpendicular vector 578 | RMAPI Vector3 Vector3Perpendicular(Vector3 v) 579 | { 580 | Vector3 result = { 0 }; 581 | 582 | float min = (float) fabs(v.x); 583 | Vector3 cardinalAxis = {1.0f, 0.0f, 0.0f}; 584 | 585 | if (fabsf(v.y) < min) 586 | { 587 | min = (float) fabs(v.y); 588 | Vector3 tmp = {0.0f, 1.0f, 0.0f}; 589 | cardinalAxis = tmp; 590 | } 591 | 592 | if (fabsf(v.z) < min) 593 | { 594 | Vector3 tmp = {0.0f, 0.0f, 1.0f}; 595 | cardinalAxis = tmp; 596 | } 597 | 598 | // Cross product between vectors 599 | result.x = v.y*cardinalAxis.z - v.z*cardinalAxis.y; 600 | result.y = v.z*cardinalAxis.x - v.x*cardinalAxis.z; 601 | result.z = v.x*cardinalAxis.y - v.y*cardinalAxis.x; 602 | 603 | return result; 604 | } 605 | 606 | // Calculate vector length 607 | RMAPI float Vector3Length(const Vector3 v) 608 | { 609 | float result = sqrtf(v.x*v.x + v.y*v.y + v.z*v.z); 610 | 611 | return result; 612 | } 613 | 614 | // Calculate vector square length 615 | RMAPI float Vector3LengthSqr(const Vector3 v) 616 | { 617 | float result = v.x*v.x + v.y*v.y + v.z*v.z; 618 | 619 | return result; 620 | } 621 | 622 | // Calculate two vectors dot product 623 | RMAPI float Vector3DotProduct(Vector3 v1, Vector3 v2) 624 | { 625 | float result = (v1.x*v2.x + v1.y*v2.y + v1.z*v2.z); 626 | 627 | return result; 628 | } 629 | 630 | // Calculate distance between two vectors 631 | RMAPI float Vector3Distance(Vector3 v1, Vector3 v2) 632 | { 633 | float result = 0.0f; 634 | 635 | float dx = v2.x - v1.x; 636 | float dy = v2.y - v1.y; 637 | float dz = v2.z - v1.z; 638 | result = sqrtf(dx*dx + dy*dy + dz*dz); 639 | 640 | return result; 641 | } 642 | 643 | // Calculate square distance between two vectors 644 | RMAPI float Vector3DistanceSqr(Vector3 v1, Vector3 v2) 645 | { 646 | float result = 0.0f; 647 | 648 | float dx = v2.x - v1.x; 649 | float dy = v2.y - v1.y; 650 | float dz = v2.z - v1.z; 651 | result = dx*dx + dy*dy + dz*dz; 652 | 653 | return result; 654 | } 655 | 656 | // Calculate angle between two vectors 657 | RMAPI float Vector3Angle(Vector3 v1, Vector3 v2) 658 | { 659 | float result = 0.0f; 660 | 661 | Vector3 cross = { v1.y*v2.z - v1.z*v2.y, v1.z*v2.x - v1.x*v2.z, v1.x*v2.y - v1.y*v2.x }; 662 | float len = sqrtf(cross.x*cross.x + cross.y*cross.y + cross.z*cross.z); 663 | float dot = (v1.x*v2.x + v1.y*v2.y + v1.z*v2.z); 664 | result = atan2f(len, dot); 665 | 666 | return result; 667 | } 668 | 669 | // Negate provided vector (invert direction) 670 | RMAPI Vector3 Vector3Negate(Vector3 v) 671 | { 672 | Vector3 result = { -v.x, -v.y, -v.z }; 673 | 674 | return result; 675 | } 676 | 677 | // Divide vector by vector 678 | RMAPI Vector3 Vector3Divide(Vector3 v1, Vector3 v2) 679 | { 680 | Vector3 result = { v1.x/v2.x, v1.y/v2.y, v1.z/v2.z }; 681 | 682 | return result; 683 | } 684 | 685 | // Normalize provided vector 686 | RMAPI Vector3 Vector3Normalize(Vector3 v) 687 | { 688 | Vector3 result = v; 689 | 690 | float length = sqrtf(v.x*v.x + v.y*v.y + v.z*v.z); 691 | if (length == 0.0f) length = 1.0f; 692 | float ilength = 1.0f/length; 693 | 694 | result.x *= ilength; 695 | result.y *= ilength; 696 | result.z *= ilength; 697 | 698 | return result; 699 | } 700 | 701 | // Orthonormalize provided vectors 702 | // Makes vectors normalized and orthogonal to each other 703 | // Gram-Schmidt function implementation 704 | RMAPI void Vector3OrthoNormalize(Vector3 *v1, Vector3 *v2) 705 | { 706 | float length = 0.0f; 707 | float ilength = 0.0f; 708 | 709 | // Vector3Normalize(*v1); 710 | Vector3 v = *v1; 711 | length = sqrtf(v.x*v.x + v.y*v.y + v.z*v.z); 712 | if (length == 0.0f) length = 1.0f; 713 | ilength = 1.0f/length; 714 | v1->x *= ilength; 715 | v1->y *= ilength; 716 | v1->z *= ilength; 717 | 718 | // Vector3CrossProduct(*v1, *v2) 719 | Vector3 vn1 = { v1->y*v2->z - v1->z*v2->y, v1->z*v2->x - v1->x*v2->z, v1->x*v2->y - v1->y*v2->x }; 720 | 721 | // Vector3Normalize(vn1); 722 | v = vn1; 723 | length = sqrtf(v.x*v.x + v.y*v.y + v.z*v.z); 724 | if (length == 0.0f) length = 1.0f; 725 | ilength = 1.0f/length; 726 | vn1.x *= ilength; 727 | vn1.y *= ilength; 728 | vn1.z *= ilength; 729 | 730 | // Vector3CrossProduct(vn1, *v1) 731 | Vector3 vn2 = { vn1.y*v1->z - vn1.z*v1->y, vn1.z*v1->x - vn1.x*v1->z, vn1.x*v1->y - vn1.y*v1->x }; 732 | 733 | *v2 = vn2; 734 | } 735 | 736 | // Transforms a Vector3 by a given Matrix 737 | RMAPI Vector3 Vector3Transform(Vector3 v, Matrix mat) 738 | { 739 | Vector3 result = { 0 }; 740 | 741 | float x = v.x; 742 | float y = v.y; 743 | float z = v.z; 744 | 745 | result.x = mat.m0*x + mat.m4*y + mat.m8*z + mat.m12; 746 | result.y = mat.m1*x + mat.m5*y + mat.m9*z + mat.m13; 747 | result.z = mat.m2*x + mat.m6*y + mat.m10*z + mat.m14; 748 | 749 | return result; 750 | } 751 | 752 | // Transform a vector by quaternion rotation 753 | RMAPI Vector3 Vector3RotateByQuaternion(Vector3 v, Quaternion q) 754 | { 755 | Vector3 result = { 0 }; 756 | 757 | result.x = v.x*(q.x*q.x + q.w*q.w - q.y*q.y - q.z*q.z) + v.y*(2*q.x*q.y - 2*q.w*q.z) + v.z*(2*q.x*q.z + 2*q.w*q.y); 758 | result.y = v.x*(2*q.w*q.z + 2*q.x*q.y) + v.y*(q.w*q.w - q.x*q.x + q.y*q.y - q.z*q.z) + v.z*(-2*q.w*q.x + 2*q.y*q.z); 759 | result.z = v.x*(-2*q.w*q.y + 2*q.x*q.z) + v.y*(2*q.w*q.x + 2*q.y*q.z)+ v.z*(q.w*q.w - q.x*q.x - q.y*q.y + q.z*q.z); 760 | 761 | return result; 762 | } 763 | 764 | // Rotates a vector around an axis 765 | RMAPI Vector3 Vector3RotateByAxisAngle(Vector3 v, Vector3 axis, float angle) 766 | { 767 | // Using Euler-Rodrigues Formula 768 | // Ref.: https://en.wikipedia.org/w/index.php?title=Euler%E2%80%93Rodrigues_formula 769 | 770 | Vector3 result = v; 771 | 772 | // Vector3Normalize(axis); 773 | float length = sqrtf(axis.x * axis.x + axis.y * axis.y + axis.z * axis.z); 774 | if (length == 0.0f) length = 1.0f; 775 | float ilength = 1.0f / length; 776 | axis.x *= ilength; 777 | axis.y *= ilength; 778 | axis.z *= ilength; 779 | 780 | angle /= 2.0f; 781 | float a = sinf(angle); 782 | float b = axis.x * a; 783 | float c = axis.y * a; 784 | float d = axis.z * a; 785 | a = cosf(angle); 786 | Vector3 w = { b, c, d }; 787 | 788 | // Vector3CrossProduct(w, v) 789 | Vector3 wv = { w.y * v.z - w.z * v.y, w.z * v.x - w.x * v.z, w.x * v.y - w.y * v.x }; 790 | 791 | // Vector3CrossProduct(w, wv) 792 | Vector3 wwv = { w.y * wv.z - w.z * wv.y, w.z * wv.x - w.x * wv.z, w.x * wv.y - w.y * wv.x }; 793 | 794 | // Vector3Scale(wv, 2 * a) 795 | a *= 2; 796 | wv.x *= a; 797 | wv.y *= a; 798 | wv.z *= a; 799 | 800 | // Vector3Scale(wwv, 2) 801 | wwv.x *= 2; 802 | wwv.y *= 2; 803 | wwv.z *= 2; 804 | 805 | result.x += wv.x; 806 | result.y += wv.y; 807 | result.z += wv.z; 808 | 809 | result.x += wwv.x; 810 | result.y += wwv.y; 811 | result.z += wwv.z; 812 | 813 | return result; 814 | } 815 | 816 | // Calculate linear interpolation between two vectors 817 | RMAPI Vector3 Vector3Lerp(Vector3 v1, Vector3 v2, float amount) 818 | { 819 | Vector3 result = { 0 }; 820 | 821 | result.x = v1.x + amount*(v2.x - v1.x); 822 | result.y = v1.y + amount*(v2.y - v1.y); 823 | result.z = v1.z + amount*(v2.z - v1.z); 824 | 825 | return result; 826 | } 827 | 828 | // Calculate reflected vector to normal 829 | RMAPI Vector3 Vector3Reflect(Vector3 v, Vector3 normal) 830 | { 831 | Vector3 result = { 0 }; 832 | 833 | // I is the original vector 834 | // N is the normal of the incident plane 835 | // R = I - (2*N*(DotProduct[I, N])) 836 | 837 | float dotProduct = (v.x*normal.x + v.y*normal.y + v.z*normal.z); 838 | 839 | result.x = v.x - (2.0f*normal.x)*dotProduct; 840 | result.y = v.y - (2.0f*normal.y)*dotProduct; 841 | result.z = v.z - (2.0f*normal.z)*dotProduct; 842 | 843 | return result; 844 | } 845 | 846 | // Get min value for each pair of components 847 | RMAPI Vector3 Vector3Min(Vector3 v1, Vector3 v2) 848 | { 849 | Vector3 result = { 0 }; 850 | 851 | result.x = fminf(v1.x, v2.x); 852 | result.y = fminf(v1.y, v2.y); 853 | result.z = fminf(v1.z, v2.z); 854 | 855 | return result; 856 | } 857 | 858 | // Get max value for each pair of components 859 | RMAPI Vector3 Vector3Max(Vector3 v1, Vector3 v2) 860 | { 861 | Vector3 result = { 0 }; 862 | 863 | result.x = fmaxf(v1.x, v2.x); 864 | result.y = fmaxf(v1.y, v2.y); 865 | result.z = fmaxf(v1.z, v2.z); 866 | 867 | return result; 868 | } 869 | 870 | // Compute barycenter coordinates (u, v, w) for point p with respect to triangle (a, b, c) 871 | // NOTE: Assumes P is on the plane of the triangle 872 | RMAPI Vector3 Vector3Barycenter(Vector3 p, Vector3 a, Vector3 b, Vector3 c) 873 | { 874 | Vector3 result = { 0 }; 875 | 876 | Vector3 v0 = { b.x - a.x, b.y - a.y, b.z - a.z }; // Vector3Subtract(b, a) 877 | Vector3 v1 = { c.x - a.x, c.y - a.y, c.z - a.z }; // Vector3Subtract(c, a) 878 | Vector3 v2 = { p.x - a.x, p.y - a.y, p.z - a.z }; // Vector3Subtract(p, a) 879 | float d00 = (v0.x*v0.x + v0.y*v0.y + v0.z*v0.z); // Vector3DotProduct(v0, v0) 880 | float d01 = (v0.x*v1.x + v0.y*v1.y + v0.z*v1.z); // Vector3DotProduct(v0, v1) 881 | float d11 = (v1.x*v1.x + v1.y*v1.y + v1.z*v1.z); // Vector3DotProduct(v1, v1) 882 | float d20 = (v2.x*v0.x + v2.y*v0.y + v2.z*v0.z); // Vector3DotProduct(v2, v0) 883 | float d21 = (v2.x*v1.x + v2.y*v1.y + v2.z*v1.z); // Vector3DotProduct(v2, v1) 884 | 885 | float denom = d00*d11 - d01*d01; 886 | 887 | result.y = (d11*d20 - d01*d21)/denom; 888 | result.z = (d00*d21 - d01*d20)/denom; 889 | result.x = 1.0f - (result.z + result.y); 890 | 891 | return result; 892 | } 893 | 894 | // Projects a Vector3 from screen space into object space 895 | // NOTE: We are avoiding calling other raymath functions despite available 896 | RMAPI Vector3 Vector3Unproject(Vector3 source, Matrix projection, Matrix view) 897 | { 898 | Vector3 result = { 0 }; 899 | 900 | // Calculate unproject matrix (multiply view patrix by projection matrix) and invert it 901 | Matrix matViewProj = { // MatrixMultiply(view, projection); 902 | view.m0*projection.m0 + view.m1*projection.m4 + view.m2*projection.m8 + view.m3*projection.m12, 903 | view.m0*projection.m1 + view.m1*projection.m5 + view.m2*projection.m9 + view.m3*projection.m13, 904 | view.m0*projection.m2 + view.m1*projection.m6 + view.m2*projection.m10 + view.m3*projection.m14, 905 | view.m0*projection.m3 + view.m1*projection.m7 + view.m2*projection.m11 + view.m3*projection.m15, 906 | view.m4*projection.m0 + view.m5*projection.m4 + view.m6*projection.m8 + view.m7*projection.m12, 907 | view.m4*projection.m1 + view.m5*projection.m5 + view.m6*projection.m9 + view.m7*projection.m13, 908 | view.m4*projection.m2 + view.m5*projection.m6 + view.m6*projection.m10 + view.m7*projection.m14, 909 | view.m4*projection.m3 + view.m5*projection.m7 + view.m6*projection.m11 + view.m7*projection.m15, 910 | view.m8*projection.m0 + view.m9*projection.m4 + view.m10*projection.m8 + view.m11*projection.m12, 911 | view.m8*projection.m1 + view.m9*projection.m5 + view.m10*projection.m9 + view.m11*projection.m13, 912 | view.m8*projection.m2 + view.m9*projection.m6 + view.m10*projection.m10 + view.m11*projection.m14, 913 | view.m8*projection.m3 + view.m9*projection.m7 + view.m10*projection.m11 + view.m11*projection.m15, 914 | view.m12*projection.m0 + view.m13*projection.m4 + view.m14*projection.m8 + view.m15*projection.m12, 915 | view.m12*projection.m1 + view.m13*projection.m5 + view.m14*projection.m9 + view.m15*projection.m13, 916 | view.m12*projection.m2 + view.m13*projection.m6 + view.m14*projection.m10 + view.m15*projection.m14, 917 | view.m12*projection.m3 + view.m13*projection.m7 + view.m14*projection.m11 + view.m15*projection.m15 }; 918 | 919 | // Calculate inverted matrix -> MatrixInvert(matViewProj); 920 | // Cache the matrix values (speed optimization) 921 | float a00 = matViewProj.m0, a01 = matViewProj.m1, a02 = matViewProj.m2, a03 = matViewProj.m3; 922 | float a10 = matViewProj.m4, a11 = matViewProj.m5, a12 = matViewProj.m6, a13 = matViewProj.m7; 923 | float a20 = matViewProj.m8, a21 = matViewProj.m9, a22 = matViewProj.m10, a23 = matViewProj.m11; 924 | float a30 = matViewProj.m12, a31 = matViewProj.m13, a32 = matViewProj.m14, a33 = matViewProj.m15; 925 | 926 | float b00 = a00*a11 - a01*a10; 927 | float b01 = a00*a12 - a02*a10; 928 | float b02 = a00*a13 - a03*a10; 929 | float b03 = a01*a12 - a02*a11; 930 | float b04 = a01*a13 - a03*a11; 931 | float b05 = a02*a13 - a03*a12; 932 | float b06 = a20*a31 - a21*a30; 933 | float b07 = a20*a32 - a22*a30; 934 | float b08 = a20*a33 - a23*a30; 935 | float b09 = a21*a32 - a22*a31; 936 | float b10 = a21*a33 - a23*a31; 937 | float b11 = a22*a33 - a23*a32; 938 | 939 | // Calculate the invert determinant (inlined to avoid double-caching) 940 | float invDet = 1.0f/(b00*b11 - b01*b10 + b02*b09 + b03*b08 - b04*b07 + b05*b06); 941 | 942 | Matrix matViewProjInv = { 943 | (a11*b11 - a12*b10 + a13*b09)*invDet, 944 | (-a01*b11 + a02*b10 - a03*b09)*invDet, 945 | (a31*b05 - a32*b04 + a33*b03)*invDet, 946 | (-a21*b05 + a22*b04 - a23*b03)*invDet, 947 | (-a10*b11 + a12*b08 - a13*b07)*invDet, 948 | (a00*b11 - a02*b08 + a03*b07)*invDet, 949 | (-a30*b05 + a32*b02 - a33*b01)*invDet, 950 | (a20*b05 - a22*b02 + a23*b01)*invDet, 951 | (a10*b10 - a11*b08 + a13*b06)*invDet, 952 | (-a00*b10 + a01*b08 - a03*b06)*invDet, 953 | (a30*b04 - a31*b02 + a33*b00)*invDet, 954 | (-a20*b04 + a21*b02 - a23*b00)*invDet, 955 | (-a10*b09 + a11*b07 - a12*b06)*invDet, 956 | (a00*b09 - a01*b07 + a02*b06)*invDet, 957 | (-a30*b03 + a31*b01 - a32*b00)*invDet, 958 | (a20*b03 - a21*b01 + a22*b00)*invDet }; 959 | 960 | // Create quaternion from source point 961 | Quaternion quat = { source.x, source.y, source.z, 1.0f }; 962 | 963 | // Multiply quat point by unproject matrix 964 | Quaternion qtransformed = { // QuaternionTransform(quat, matViewProjInv) 965 | matViewProjInv.m0*quat.x + matViewProjInv.m4*quat.y + matViewProjInv.m8*quat.z + matViewProjInv.m12*quat.w, 966 | matViewProjInv.m1*quat.x + matViewProjInv.m5*quat.y + matViewProjInv.m9*quat.z + matViewProjInv.m13*quat.w, 967 | matViewProjInv.m2*quat.x + matViewProjInv.m6*quat.y + matViewProjInv.m10*quat.z + matViewProjInv.m14*quat.w, 968 | matViewProjInv.m3*quat.x + matViewProjInv.m7*quat.y + matViewProjInv.m11*quat.z + matViewProjInv.m15*quat.w }; 969 | 970 | // Normalized world points in vectors 971 | result.x = qtransformed.x/qtransformed.w; 972 | result.y = qtransformed.y/qtransformed.w; 973 | result.z = qtransformed.z/qtransformed.w; 974 | 975 | return result; 976 | } 977 | 978 | // Get Vector3 as float array 979 | RMAPI float3 Vector3ToFloatV(Vector3 v) 980 | { 981 | float3 buffer = { 0 }; 982 | 983 | buffer.v[0] = v.x; 984 | buffer.v[1] = v.y; 985 | buffer.v[2] = v.z; 986 | 987 | return buffer; 988 | } 989 | 990 | // Invert the given vector 991 | RMAPI Vector3 Vector3Invert(Vector3 v) 992 | { 993 | Vector3 result = { 1.0f/v.x, 1.0f/v.y, 1.0f/v.z }; 994 | 995 | return result; 996 | } 997 | 998 | // Clamp the components of the vector between 999 | // min and max values specified by the given vectors 1000 | RMAPI Vector3 Vector3Clamp(Vector3 v, Vector3 min, Vector3 max) 1001 | { 1002 | Vector3 result = { 0 }; 1003 | 1004 | result.x = fminf(max.x, fmaxf(min.x, v.x)); 1005 | result.y = fminf(max.y, fmaxf(min.y, v.y)); 1006 | result.z = fminf(max.z, fmaxf(min.z, v.z)); 1007 | 1008 | return result; 1009 | } 1010 | 1011 | // Clamp the magnitude of the vector between two values 1012 | RMAPI Vector3 Vector3ClampValue(Vector3 v, float min, float max) 1013 | { 1014 | Vector3 result = v; 1015 | 1016 | float length = (v.x*v.x) + (v.y*v.y) + (v.z*v.z); 1017 | if (length > 0.0f) 1018 | { 1019 | length = sqrtf(length); 1020 | 1021 | if (length < min) 1022 | { 1023 | float scale = min/length; 1024 | result.x = v.x*scale; 1025 | result.y = v.y*scale; 1026 | result.z = v.z*scale; 1027 | } 1028 | else if (length > max) 1029 | { 1030 | float scale = max/length; 1031 | result.x = v.x*scale; 1032 | result.y = v.y*scale; 1033 | result.z = v.z*scale; 1034 | } 1035 | } 1036 | 1037 | return result; 1038 | } 1039 | 1040 | // Check whether two given vectors are almost equal 1041 | RMAPI int Vector3Equals(Vector3 p, Vector3 q) 1042 | { 1043 | int result = ((fabsf(p.x - q.x)) <= (EPSILON*fmaxf(1.0f, fmaxf(fabsf(p.x), fabsf(q.x))))) && 1044 | ((fabsf(p.y - q.y)) <= (EPSILON*fmaxf(1.0f, fmaxf(fabsf(p.y), fabsf(q.y))))) && 1045 | ((fabsf(p.z - q.z)) <= (EPSILON*fmaxf(1.0f, fmaxf(fabsf(p.z), fabsf(q.z))))); 1046 | 1047 | return result; 1048 | } 1049 | 1050 | // Compute the direction of a refracted ray where v specifies the 1051 | // normalized direction of the incoming ray, n specifies the 1052 | // normalized normal vector of the interface of two optical media, 1053 | // and r specifies the ratio of the refractive index of the medium 1054 | // from where the ray comes to the refractive index of the medium 1055 | // on the other side of the surface 1056 | RMAPI Vector3 Vector3Refract(Vector3 v, Vector3 n, float r) 1057 | { 1058 | Vector3 result = { 0 }; 1059 | 1060 | float dot = v.x*n.x + v.y*n.y + v.z*n.z; 1061 | float d = 1.0f - r*r*(1.0f - dot*dot); 1062 | 1063 | if (d >= 0.0f) 1064 | { 1065 | d = sqrtf(d); 1066 | v.x = r*v.x - (r*dot + d)*n.x; 1067 | v.y = r*v.y - (r*dot + d)*n.y; 1068 | v.z = r*v.z - (r*dot + d)*n.z; 1069 | 1070 | result = v; 1071 | } 1072 | 1073 | return result; 1074 | } 1075 | 1076 | //---------------------------------------------------------------------------------- 1077 | // Module Functions Definition - Matrix math 1078 | //---------------------------------------------------------------------------------- 1079 | 1080 | // Compute matrix determinant 1081 | RMAPI float MatrixDeterminant(Matrix mat) 1082 | { 1083 | float result = 0.0f; 1084 | 1085 | // Cache the matrix values (speed optimization) 1086 | float a00 = mat.m0, a01 = mat.m1, a02 = mat.m2, a03 = mat.m3; 1087 | float a10 = mat.m4, a11 = mat.m5, a12 = mat.m6, a13 = mat.m7; 1088 | float a20 = mat.m8, a21 = mat.m9, a22 = mat.m10, a23 = mat.m11; 1089 | float a30 = mat.m12, a31 = mat.m13, a32 = mat.m14, a33 = mat.m15; 1090 | 1091 | result = a30*a21*a12*a03 - a20*a31*a12*a03 - a30*a11*a22*a03 + a10*a31*a22*a03 + 1092 | a20*a11*a32*a03 - a10*a21*a32*a03 - a30*a21*a02*a13 + a20*a31*a02*a13 + 1093 | a30*a01*a22*a13 - a00*a31*a22*a13 - a20*a01*a32*a13 + a00*a21*a32*a13 + 1094 | a30*a11*a02*a23 - a10*a31*a02*a23 - a30*a01*a12*a23 + a00*a31*a12*a23 + 1095 | a10*a01*a32*a23 - a00*a11*a32*a23 - a20*a11*a02*a33 + a10*a21*a02*a33 + 1096 | a20*a01*a12*a33 - a00*a21*a12*a33 - a10*a01*a22*a33 + a00*a11*a22*a33; 1097 | 1098 | return result; 1099 | } 1100 | 1101 | // Get the trace of the matrix (sum of the values along the diagonal) 1102 | RMAPI float MatrixTrace(Matrix mat) 1103 | { 1104 | float result = (mat.m0 + mat.m5 + mat.m10 + mat.m15); 1105 | 1106 | return result; 1107 | } 1108 | 1109 | // Transposes provided matrix 1110 | RMAPI Matrix MatrixTranspose(Matrix mat) 1111 | { 1112 | Matrix result = { 0 }; 1113 | 1114 | result.m0 = mat.m0; 1115 | result.m1 = mat.m4; 1116 | result.m2 = mat.m8; 1117 | result.m3 = mat.m12; 1118 | result.m4 = mat.m1; 1119 | result.m5 = mat.m5; 1120 | result.m6 = mat.m9; 1121 | result.m7 = mat.m13; 1122 | result.m8 = mat.m2; 1123 | result.m9 = mat.m6; 1124 | result.m10 = mat.m10; 1125 | result.m11 = mat.m14; 1126 | result.m12 = mat.m3; 1127 | result.m13 = mat.m7; 1128 | result.m14 = mat.m11; 1129 | result.m15 = mat.m15; 1130 | 1131 | return result; 1132 | } 1133 | 1134 | // Invert provided matrix 1135 | RMAPI Matrix MatrixInvert(Matrix mat) 1136 | { 1137 | Matrix result = { 0 }; 1138 | 1139 | // Cache the matrix values (speed optimization) 1140 | float a00 = mat.m0, a01 = mat.m1, a02 = mat.m2, a03 = mat.m3; 1141 | float a10 = mat.m4, a11 = mat.m5, a12 = mat.m6, a13 = mat.m7; 1142 | float a20 = mat.m8, a21 = mat.m9, a22 = mat.m10, a23 = mat.m11; 1143 | float a30 = mat.m12, a31 = mat.m13, a32 = mat.m14, a33 = mat.m15; 1144 | 1145 | float b00 = a00*a11 - a01*a10; 1146 | float b01 = a00*a12 - a02*a10; 1147 | float b02 = a00*a13 - a03*a10; 1148 | float b03 = a01*a12 - a02*a11; 1149 | float b04 = a01*a13 - a03*a11; 1150 | float b05 = a02*a13 - a03*a12; 1151 | float b06 = a20*a31 - a21*a30; 1152 | float b07 = a20*a32 - a22*a30; 1153 | float b08 = a20*a33 - a23*a30; 1154 | float b09 = a21*a32 - a22*a31; 1155 | float b10 = a21*a33 - a23*a31; 1156 | float b11 = a22*a33 - a23*a32; 1157 | 1158 | // Calculate the invert determinant (inlined to avoid double-caching) 1159 | float invDet = 1.0f/(b00*b11 - b01*b10 + b02*b09 + b03*b08 - b04*b07 + b05*b06); 1160 | 1161 | result.m0 = (a11*b11 - a12*b10 + a13*b09)*invDet; 1162 | result.m1 = (-a01*b11 + a02*b10 - a03*b09)*invDet; 1163 | result.m2 = (a31*b05 - a32*b04 + a33*b03)*invDet; 1164 | result.m3 = (-a21*b05 + a22*b04 - a23*b03)*invDet; 1165 | result.m4 = (-a10*b11 + a12*b08 - a13*b07)*invDet; 1166 | result.m5 = (a00*b11 - a02*b08 + a03*b07)*invDet; 1167 | result.m6 = (-a30*b05 + a32*b02 - a33*b01)*invDet; 1168 | result.m7 = (a20*b05 - a22*b02 + a23*b01)*invDet; 1169 | result.m8 = (a10*b10 - a11*b08 + a13*b06)*invDet; 1170 | result.m9 = (-a00*b10 + a01*b08 - a03*b06)*invDet; 1171 | result.m10 = (a30*b04 - a31*b02 + a33*b00)*invDet; 1172 | result.m11 = (-a20*b04 + a21*b02 - a23*b00)*invDet; 1173 | result.m12 = (-a10*b09 + a11*b07 - a12*b06)*invDet; 1174 | result.m13 = (a00*b09 - a01*b07 + a02*b06)*invDet; 1175 | result.m14 = (-a30*b03 + a31*b01 - a32*b00)*invDet; 1176 | result.m15 = (a20*b03 - a21*b01 + a22*b00)*invDet; 1177 | 1178 | return result; 1179 | } 1180 | 1181 | // Get identity matrix 1182 | RMAPI Matrix MatrixIdentity(void) 1183 | { 1184 | Matrix result = { 1.0f, 0.0f, 0.0f, 0.0f, 1185 | 0.0f, 1.0f, 0.0f, 0.0f, 1186 | 0.0f, 0.0f, 1.0f, 0.0f, 1187 | 0.0f, 0.0f, 0.0f, 1.0f }; 1188 | 1189 | return result; 1190 | } 1191 | 1192 | // Add two matrices 1193 | RMAPI Matrix MatrixAdd(Matrix left, Matrix right) 1194 | { 1195 | Matrix result = { 0 }; 1196 | 1197 | result.m0 = left.m0 + right.m0; 1198 | result.m1 = left.m1 + right.m1; 1199 | result.m2 = left.m2 + right.m2; 1200 | result.m3 = left.m3 + right.m3; 1201 | result.m4 = left.m4 + right.m4; 1202 | result.m5 = left.m5 + right.m5; 1203 | result.m6 = left.m6 + right.m6; 1204 | result.m7 = left.m7 + right.m7; 1205 | result.m8 = left.m8 + right.m8; 1206 | result.m9 = left.m9 + right.m9; 1207 | result.m10 = left.m10 + right.m10; 1208 | result.m11 = left.m11 + right.m11; 1209 | result.m12 = left.m12 + right.m12; 1210 | result.m13 = left.m13 + right.m13; 1211 | result.m14 = left.m14 + right.m14; 1212 | result.m15 = left.m15 + right.m15; 1213 | 1214 | return result; 1215 | } 1216 | 1217 | // Subtract two matrices (left - right) 1218 | RMAPI Matrix MatrixSubtract(Matrix left, Matrix right) 1219 | { 1220 | Matrix result = { 0 }; 1221 | 1222 | result.m0 = left.m0 - right.m0; 1223 | result.m1 = left.m1 - right.m1; 1224 | result.m2 = left.m2 - right.m2; 1225 | result.m3 = left.m3 - right.m3; 1226 | result.m4 = left.m4 - right.m4; 1227 | result.m5 = left.m5 - right.m5; 1228 | result.m6 = left.m6 - right.m6; 1229 | result.m7 = left.m7 - right.m7; 1230 | result.m8 = left.m8 - right.m8; 1231 | result.m9 = left.m9 - right.m9; 1232 | result.m10 = left.m10 - right.m10; 1233 | result.m11 = left.m11 - right.m11; 1234 | result.m12 = left.m12 - right.m12; 1235 | result.m13 = left.m13 - right.m13; 1236 | result.m14 = left.m14 - right.m14; 1237 | result.m15 = left.m15 - right.m15; 1238 | 1239 | return result; 1240 | } 1241 | 1242 | // Get two matrix multiplication 1243 | // NOTE: When multiplying matrices... the order matters! 1244 | RMAPI Matrix MatrixMultiply(Matrix left, Matrix right) 1245 | { 1246 | Matrix result = { 0 }; 1247 | 1248 | result.m0 = left.m0*right.m0 + left.m1*right.m4 + left.m2*right.m8 + left.m3*right.m12; 1249 | result.m1 = left.m0*right.m1 + left.m1*right.m5 + left.m2*right.m9 + left.m3*right.m13; 1250 | result.m2 = left.m0*right.m2 + left.m1*right.m6 + left.m2*right.m10 + left.m3*right.m14; 1251 | result.m3 = left.m0*right.m3 + left.m1*right.m7 + left.m2*right.m11 + left.m3*right.m15; 1252 | result.m4 = left.m4*right.m0 + left.m5*right.m4 + left.m6*right.m8 + left.m7*right.m12; 1253 | result.m5 = left.m4*right.m1 + left.m5*right.m5 + left.m6*right.m9 + left.m7*right.m13; 1254 | result.m6 = left.m4*right.m2 + left.m5*right.m6 + left.m6*right.m10 + left.m7*right.m14; 1255 | result.m7 = left.m4*right.m3 + left.m5*right.m7 + left.m6*right.m11 + left.m7*right.m15; 1256 | result.m8 = left.m8*right.m0 + left.m9*right.m4 + left.m10*right.m8 + left.m11*right.m12; 1257 | result.m9 = left.m8*right.m1 + left.m9*right.m5 + left.m10*right.m9 + left.m11*right.m13; 1258 | result.m10 = left.m8*right.m2 + left.m9*right.m6 + left.m10*right.m10 + left.m11*right.m14; 1259 | result.m11 = left.m8*right.m3 + left.m9*right.m7 + left.m10*right.m11 + left.m11*right.m15; 1260 | result.m12 = left.m12*right.m0 + left.m13*right.m4 + left.m14*right.m8 + left.m15*right.m12; 1261 | result.m13 = left.m12*right.m1 + left.m13*right.m5 + left.m14*right.m9 + left.m15*right.m13; 1262 | result.m14 = left.m12*right.m2 + left.m13*right.m6 + left.m14*right.m10 + left.m15*right.m14; 1263 | result.m15 = left.m12*right.m3 + left.m13*right.m7 + left.m14*right.m11 + left.m15*right.m15; 1264 | 1265 | return result; 1266 | } 1267 | 1268 | // Get translation matrix 1269 | RMAPI Matrix MatrixTranslate(float x, float y, float z) 1270 | { 1271 | Matrix result = { 1.0f, 0.0f, 0.0f, x, 1272 | 0.0f, 1.0f, 0.0f, y, 1273 | 0.0f, 0.0f, 1.0f, z, 1274 | 0.0f, 0.0f, 0.0f, 1.0f }; 1275 | 1276 | return result; 1277 | } 1278 | 1279 | // Create rotation matrix from axis and angle 1280 | // NOTE: Angle should be provided in radians 1281 | RMAPI Matrix MatrixRotate(Vector3 axis, float angle) 1282 | { 1283 | Matrix result = { 0 }; 1284 | 1285 | float x = axis.x, y = axis.y, z = axis.z; 1286 | 1287 | float lengthSquared = x*x + y*y + z*z; 1288 | 1289 | if ((lengthSquared != 1.0f) && (lengthSquared != 0.0f)) 1290 | { 1291 | float ilength = 1.0f/sqrtf(lengthSquared); 1292 | x *= ilength; 1293 | y *= ilength; 1294 | z *= ilength; 1295 | } 1296 | 1297 | float sinres = sinf(angle); 1298 | float cosres = cosf(angle); 1299 | float t = 1.0f - cosres; 1300 | 1301 | result.m0 = x*x*t + cosres; 1302 | result.m1 = y*x*t + z*sinres; 1303 | result.m2 = z*x*t - y*sinres; 1304 | result.m3 = 0.0f; 1305 | 1306 | result.m4 = x*y*t - z*sinres; 1307 | result.m5 = y*y*t + cosres; 1308 | result.m6 = z*y*t + x*sinres; 1309 | result.m7 = 0.0f; 1310 | 1311 | result.m8 = x*z*t + y*sinres; 1312 | result.m9 = y*z*t - x*sinres; 1313 | result.m10 = z*z*t + cosres; 1314 | result.m11 = 0.0f; 1315 | 1316 | result.m12 = 0.0f; 1317 | result.m13 = 0.0f; 1318 | result.m14 = 0.0f; 1319 | result.m15 = 1.0f; 1320 | 1321 | return result; 1322 | } 1323 | 1324 | // Get x-rotation matrix 1325 | // NOTE: Angle must be provided in radians 1326 | RMAPI Matrix MatrixRotateX(float angle) 1327 | { 1328 | Matrix result = { 1.0f, 0.0f, 0.0f, 0.0f, 1329 | 0.0f, 1.0f, 0.0f, 0.0f, 1330 | 0.0f, 0.0f, 1.0f, 0.0f, 1331 | 0.0f, 0.0f, 0.0f, 1.0f }; // MatrixIdentity() 1332 | 1333 | float cosres = cosf(angle); 1334 | float sinres = sinf(angle); 1335 | 1336 | result.m5 = cosres; 1337 | result.m6 = sinres; 1338 | result.m9 = -sinres; 1339 | result.m10 = cosres; 1340 | 1341 | return result; 1342 | } 1343 | 1344 | // Get y-rotation matrix 1345 | // NOTE: Angle must be provided in radians 1346 | RMAPI Matrix MatrixRotateY(float angle) 1347 | { 1348 | Matrix result = { 1.0f, 0.0f, 0.0f, 0.0f, 1349 | 0.0f, 1.0f, 0.0f, 0.0f, 1350 | 0.0f, 0.0f, 1.0f, 0.0f, 1351 | 0.0f, 0.0f, 0.0f, 1.0f }; // MatrixIdentity() 1352 | 1353 | float cosres = cosf(angle); 1354 | float sinres = sinf(angle); 1355 | 1356 | result.m0 = cosres; 1357 | result.m2 = -sinres; 1358 | result.m8 = sinres; 1359 | result.m10 = cosres; 1360 | 1361 | return result; 1362 | } 1363 | 1364 | // Get z-rotation matrix 1365 | // NOTE: Angle must be provided in radians 1366 | RMAPI Matrix MatrixRotateZ(float angle) 1367 | { 1368 | Matrix result = { 1.0f, 0.0f, 0.0f, 0.0f, 1369 | 0.0f, 1.0f, 0.0f, 0.0f, 1370 | 0.0f, 0.0f, 1.0f, 0.0f, 1371 | 0.0f, 0.0f, 0.0f, 1.0f }; // MatrixIdentity() 1372 | 1373 | float cosres = cosf(angle); 1374 | float sinres = sinf(angle); 1375 | 1376 | result.m0 = cosres; 1377 | result.m1 = sinres; 1378 | result.m4 = -sinres; 1379 | result.m5 = cosres; 1380 | 1381 | return result; 1382 | } 1383 | 1384 | 1385 | // Get xyz-rotation matrix 1386 | // NOTE: Angle must be provided in radians 1387 | RMAPI Matrix MatrixRotateXYZ(Vector3 angle) 1388 | { 1389 | Matrix result = { 1.0f, 0.0f, 0.0f, 0.0f, 1390 | 0.0f, 1.0f, 0.0f, 0.0f, 1391 | 0.0f, 0.0f, 1.0f, 0.0f, 1392 | 0.0f, 0.0f, 0.0f, 1.0f }; // MatrixIdentity() 1393 | 1394 | float cosz = cosf(-angle.z); 1395 | float sinz = sinf(-angle.z); 1396 | float cosy = cosf(-angle.y); 1397 | float siny = sinf(-angle.y); 1398 | float cosx = cosf(-angle.x); 1399 | float sinx = sinf(-angle.x); 1400 | 1401 | result.m0 = cosz*cosy; 1402 | result.m1 = (cosz*siny*sinx) - (sinz*cosx); 1403 | result.m2 = (cosz*siny*cosx) + (sinz*sinx); 1404 | 1405 | result.m4 = sinz*cosy; 1406 | result.m5 = (sinz*siny*sinx) + (cosz*cosx); 1407 | result.m6 = (sinz*siny*cosx) - (cosz*sinx); 1408 | 1409 | result.m8 = -siny; 1410 | result.m9 = cosy*sinx; 1411 | result.m10= cosy*cosx; 1412 | 1413 | return result; 1414 | } 1415 | 1416 | // Get zyx-rotation matrix 1417 | // NOTE: Angle must be provided in radians 1418 | RMAPI Matrix MatrixRotateZYX(Vector3 angle) 1419 | { 1420 | Matrix result = { 0 }; 1421 | 1422 | float cz = cosf(angle.z); 1423 | float sz = sinf(angle.z); 1424 | float cy = cosf(angle.y); 1425 | float sy = sinf(angle.y); 1426 | float cx = cosf(angle.x); 1427 | float sx = sinf(angle.x); 1428 | 1429 | result.m0 = cz*cy; 1430 | result.m4 = cz*sy*sx - cx*sz; 1431 | result.m8 = sz*sx + cz*cx*sy; 1432 | result.m12 = 0; 1433 | 1434 | result.m1 = cy*sz; 1435 | result.m5 = cz*cx + sz*sy*sx; 1436 | result.m9 = cx*sz*sy - cz*sx; 1437 | result.m13 = 0; 1438 | 1439 | result.m2 = -sy; 1440 | result.m6 = cy*sx; 1441 | result.m10 = cy*cx; 1442 | result.m14 = 0; 1443 | 1444 | result.m3 = 0; 1445 | result.m7 = 0; 1446 | result.m11 = 0; 1447 | result.m15 = 1; 1448 | 1449 | return result; 1450 | } 1451 | 1452 | // Get scaling matrix 1453 | RMAPI Matrix MatrixScale(float x, float y, float z) 1454 | { 1455 | Matrix result = { x, 0.0f, 0.0f, 0.0f, 1456 | 0.0f, y, 0.0f, 0.0f, 1457 | 0.0f, 0.0f, z, 0.0f, 1458 | 0.0f, 0.0f, 0.0f, 1.0f }; 1459 | 1460 | return result; 1461 | } 1462 | 1463 | // Get perspective projection matrix 1464 | RMAPI Matrix MatrixFrustum(double left, double right, double bottom, double top, double near, double far) 1465 | { 1466 | Matrix result = { 0 }; 1467 | 1468 | float rl = (float)(right - left); 1469 | float tb = (float)(top - bottom); 1470 | float fn = (float)(far - near); 1471 | 1472 | result.m0 = ((float)near*2.0f)/rl; 1473 | result.m1 = 0.0f; 1474 | result.m2 = 0.0f; 1475 | result.m3 = 0.0f; 1476 | 1477 | result.m4 = 0.0f; 1478 | result.m5 = ((float)near*2.0f)/tb; 1479 | result.m6 = 0.0f; 1480 | result.m7 = 0.0f; 1481 | 1482 | result.m8 = ((float)right + (float)left)/rl; 1483 | result.m9 = ((float)top + (float)bottom)/tb; 1484 | result.m10 = -((float)far + (float)near)/fn; 1485 | result.m11 = -1.0f; 1486 | 1487 | result.m12 = 0.0f; 1488 | result.m13 = 0.0f; 1489 | result.m14 = -((float)far*(float)near*2.0f)/fn; 1490 | result.m15 = 0.0f; 1491 | 1492 | return result; 1493 | } 1494 | 1495 | // Get perspective projection matrix 1496 | // NOTE: Fovy angle must be provided in radians 1497 | RMAPI Matrix MatrixPerspective(double fovy, double aspect, double near, double far) 1498 | { 1499 | Matrix result = { 0 }; 1500 | 1501 | double top = near*tan(fovy*0.5); 1502 | double bottom = -top; 1503 | double right = top*aspect; 1504 | double left = -right; 1505 | 1506 | // MatrixFrustum(-right, right, -top, top, near, far); 1507 | float rl = (float)(right - left); 1508 | float tb = (float)(top - bottom); 1509 | float fn = (float)(far - near); 1510 | 1511 | result.m0 = ((float)near*2.0f)/rl; 1512 | result.m5 = ((float)near*2.0f)/tb; 1513 | result.m8 = ((float)right + (float)left)/rl; 1514 | result.m9 = ((float)top + (float)bottom)/tb; 1515 | result.m10 = -((float)far + (float)near)/fn; 1516 | result.m11 = -1.0f; 1517 | result.m14 = -((float)far*(float)near*2.0f)/fn; 1518 | 1519 | return result; 1520 | } 1521 | 1522 | // Get orthographic projection matrix 1523 | RMAPI Matrix MatrixOrtho(double left, double right, double bottom, double top, double near, double far) 1524 | { 1525 | Matrix result = { 0 }; 1526 | 1527 | float rl = (float)(right - left); 1528 | float tb = (float)(top - bottom); 1529 | float fn = (float)(far - near); 1530 | 1531 | result.m0 = 2.0f/rl; 1532 | result.m1 = 0.0f; 1533 | result.m2 = 0.0f; 1534 | result.m3 = 0.0f; 1535 | result.m4 = 0.0f; 1536 | result.m5 = 2.0f/tb; 1537 | result.m6 = 0.0f; 1538 | result.m7 = 0.0f; 1539 | result.m8 = 0.0f; 1540 | result.m9 = 0.0f; 1541 | result.m10 = -2.0f/fn; 1542 | result.m11 = 0.0f; 1543 | result.m12 = -((float)left + (float)right)/rl; 1544 | result.m13 = -((float)top + (float)bottom)/tb; 1545 | result.m14 = -((float)far + (float)near)/fn; 1546 | result.m15 = 1.0f; 1547 | 1548 | return result; 1549 | } 1550 | 1551 | // Get camera look-at matrix (view matrix) 1552 | RMAPI Matrix MatrixLookAt(Vector3 eye, Vector3 target, Vector3 up) 1553 | { 1554 | Matrix result = { 0 }; 1555 | 1556 | float length = 0.0f; 1557 | float ilength = 0.0f; 1558 | 1559 | // Vector3Subtract(eye, target) 1560 | Vector3 vz = { eye.x - target.x, eye.y - target.y, eye.z - target.z }; 1561 | 1562 | // Vector3Normalize(vz) 1563 | Vector3 v = vz; 1564 | length = sqrtf(v.x*v.x + v.y*v.y + v.z*v.z); 1565 | if (length == 0.0f) length = 1.0f; 1566 | ilength = 1.0f/length; 1567 | vz.x *= ilength; 1568 | vz.y *= ilength; 1569 | vz.z *= ilength; 1570 | 1571 | // Vector3CrossProduct(up, vz) 1572 | Vector3 vx = { up.y*vz.z - up.z*vz.y, up.z*vz.x - up.x*vz.z, up.x*vz.y - up.y*vz.x }; 1573 | 1574 | // Vector3Normalize(x) 1575 | v = vx; 1576 | length = sqrtf(v.x*v.x + v.y*v.y + v.z*v.z); 1577 | if (length == 0.0f) length = 1.0f; 1578 | ilength = 1.0f/length; 1579 | vx.x *= ilength; 1580 | vx.y *= ilength; 1581 | vx.z *= ilength; 1582 | 1583 | // Vector3CrossProduct(vz, vx) 1584 | Vector3 vy = { vz.y*vx.z - vz.z*vx.y, vz.z*vx.x - vz.x*vx.z, vz.x*vx.y - vz.y*vx.x }; 1585 | 1586 | result.m0 = vx.x; 1587 | result.m1 = vy.x; 1588 | result.m2 = vz.x; 1589 | result.m3 = 0.0f; 1590 | result.m4 = vx.y; 1591 | result.m5 = vy.y; 1592 | result.m6 = vz.y; 1593 | result.m7 = 0.0f; 1594 | result.m8 = vx.z; 1595 | result.m9 = vy.z; 1596 | result.m10 = vz.z; 1597 | result.m11 = 0.0f; 1598 | result.m12 = -(vx.x*eye.x + vx.y*eye.y + vx.z*eye.z); // Vector3DotProduct(vx, eye) 1599 | result.m13 = -(vy.x*eye.x + vy.y*eye.y + vy.z*eye.z); // Vector3DotProduct(vy, eye) 1600 | result.m14 = -(vz.x*eye.x + vz.y*eye.y + vz.z*eye.z); // Vector3DotProduct(vz, eye) 1601 | result.m15 = 1.0f; 1602 | 1603 | return result; 1604 | } 1605 | 1606 | // Get float array of matrix data 1607 | RMAPI float16 MatrixToFloatV(Matrix mat) 1608 | { 1609 | float16 result = { 0 }; 1610 | 1611 | result.v[0] = mat.m0; 1612 | result.v[1] = mat.m1; 1613 | result.v[2] = mat.m2; 1614 | result.v[3] = mat.m3; 1615 | result.v[4] = mat.m4; 1616 | result.v[5] = mat.m5; 1617 | result.v[6] = mat.m6; 1618 | result.v[7] = mat.m7; 1619 | result.v[8] = mat.m8; 1620 | result.v[9] = mat.m9; 1621 | result.v[10] = mat.m10; 1622 | result.v[11] = mat.m11; 1623 | result.v[12] = mat.m12; 1624 | result.v[13] = mat.m13; 1625 | result.v[14] = mat.m14; 1626 | result.v[15] = mat.m15; 1627 | 1628 | return result; 1629 | } 1630 | 1631 | //---------------------------------------------------------------------------------- 1632 | // Module Functions Definition - Quaternion math 1633 | //---------------------------------------------------------------------------------- 1634 | 1635 | // Add two quaternions 1636 | RMAPI Quaternion QuaternionAdd(Quaternion q1, Quaternion q2) 1637 | { 1638 | Quaternion result = {q1.x + q2.x, q1.y + q2.y, q1.z + q2.z, q1.w + q2.w}; 1639 | 1640 | return result; 1641 | } 1642 | 1643 | // Add quaternion and float value 1644 | RMAPI Quaternion QuaternionAddValue(Quaternion q, float add) 1645 | { 1646 | Quaternion result = {q.x + add, q.y + add, q.z + add, q.w + add}; 1647 | 1648 | return result; 1649 | } 1650 | 1651 | // Subtract two quaternions 1652 | RMAPI Quaternion QuaternionSubtract(Quaternion q1, Quaternion q2) 1653 | { 1654 | Quaternion result = {q1.x - q2.x, q1.y - q2.y, q1.z - q2.z, q1.w - q2.w}; 1655 | 1656 | return result; 1657 | } 1658 | 1659 | // Subtract quaternion and float value 1660 | RMAPI Quaternion QuaternionSubtractValue(Quaternion q, float sub) 1661 | { 1662 | Quaternion result = {q.x - sub, q.y - sub, q.z - sub, q.w - sub}; 1663 | 1664 | return result; 1665 | } 1666 | 1667 | // Get identity quaternion 1668 | RMAPI Quaternion QuaternionIdentity(void) 1669 | { 1670 | Quaternion result = { 0.0f, 0.0f, 0.0f, 1.0f }; 1671 | 1672 | return result; 1673 | } 1674 | 1675 | // Computes the length of a quaternion 1676 | RMAPI float QuaternionLength(Quaternion q) 1677 | { 1678 | float result = sqrtf(q.x*q.x + q.y*q.y + q.z*q.z + q.w*q.w); 1679 | 1680 | return result; 1681 | } 1682 | 1683 | // Normalize provided quaternion 1684 | RMAPI Quaternion QuaternionNormalize(Quaternion q) 1685 | { 1686 | Quaternion result = { 0 }; 1687 | 1688 | float length = sqrtf(q.x*q.x + q.y*q.y + q.z*q.z + q.w*q.w); 1689 | if (length == 0.0f) length = 1.0f; 1690 | float ilength = 1.0f/length; 1691 | 1692 | result.x = q.x*ilength; 1693 | result.y = q.y*ilength; 1694 | result.z = q.z*ilength; 1695 | result.w = q.w*ilength; 1696 | 1697 | return result; 1698 | } 1699 | 1700 | // Invert provided quaternion 1701 | RMAPI Quaternion QuaternionInvert(Quaternion q) 1702 | { 1703 | Quaternion result = q; 1704 | 1705 | float lengthSq = q.x*q.x + q.y*q.y + q.z*q.z + q.w*q.w; 1706 | 1707 | if (lengthSq != 0.0f) 1708 | { 1709 | float invLength = 1.0f/lengthSq; 1710 | 1711 | result.x *= -invLength; 1712 | result.y *= -invLength; 1713 | result.z *= -invLength; 1714 | result.w *= invLength; 1715 | } 1716 | 1717 | return result; 1718 | } 1719 | 1720 | // Calculate two quaternion multiplication 1721 | RMAPI Quaternion QuaternionMultiply(Quaternion q1, Quaternion q2) 1722 | { 1723 | Quaternion result = { 0 }; 1724 | 1725 | float qax = q1.x, qay = q1.y, qaz = q1.z, qaw = q1.w; 1726 | float qbx = q2.x, qby = q2.y, qbz = q2.z, qbw = q2.w; 1727 | 1728 | result.x = qax*qbw + qaw*qbx + qay*qbz - qaz*qby; 1729 | result.y = qay*qbw + qaw*qby + qaz*qbx - qax*qbz; 1730 | result.z = qaz*qbw + qaw*qbz + qax*qby - qay*qbx; 1731 | result.w = qaw*qbw - qax*qbx - qay*qby - qaz*qbz; 1732 | 1733 | return result; 1734 | } 1735 | 1736 | // Scale quaternion by float value 1737 | RMAPI Quaternion QuaternionScale(Quaternion q, float mul) 1738 | { 1739 | Quaternion result = { 0 }; 1740 | 1741 | result.x = q.x*mul; 1742 | result.y = q.y*mul; 1743 | result.z = q.z*mul; 1744 | result.w = q.w*mul; 1745 | 1746 | return result; 1747 | } 1748 | 1749 | // Divide two quaternions 1750 | RMAPI Quaternion QuaternionDivide(Quaternion q1, Quaternion q2) 1751 | { 1752 | Quaternion result = { q1.x/q2.x, q1.y/q2.y, q1.z/q2.z, q1.w/q2.w }; 1753 | 1754 | return result; 1755 | } 1756 | 1757 | // Calculate linear interpolation between two quaternions 1758 | RMAPI Quaternion QuaternionLerp(Quaternion q1, Quaternion q2, float amount) 1759 | { 1760 | Quaternion result = { 0 }; 1761 | 1762 | result.x = q1.x + amount*(q2.x - q1.x); 1763 | result.y = q1.y + amount*(q2.y - q1.y); 1764 | result.z = q1.z + amount*(q2.z - q1.z); 1765 | result.w = q1.w + amount*(q2.w - q1.w); 1766 | 1767 | return result; 1768 | } 1769 | 1770 | // Calculate slerp-optimized interpolation between two quaternions 1771 | RMAPI Quaternion QuaternionNlerp(Quaternion q1, Quaternion q2, float amount) 1772 | { 1773 | Quaternion result = { 0 }; 1774 | 1775 | // QuaternionLerp(q1, q2, amount) 1776 | result.x = q1.x + amount*(q2.x - q1.x); 1777 | result.y = q1.y + amount*(q2.y - q1.y); 1778 | result.z = q1.z + amount*(q2.z - q1.z); 1779 | result.w = q1.w + amount*(q2.w - q1.w); 1780 | 1781 | // QuaternionNormalize(q); 1782 | Quaternion q = result; 1783 | float length = sqrtf(q.x*q.x + q.y*q.y + q.z*q.z + q.w*q.w); 1784 | if (length == 0.0f) length = 1.0f; 1785 | float ilength = 1.0f/length; 1786 | 1787 | result.x = q.x*ilength; 1788 | result.y = q.y*ilength; 1789 | result.z = q.z*ilength; 1790 | result.w = q.w*ilength; 1791 | 1792 | return result; 1793 | } 1794 | 1795 | // Calculates spherical linear interpolation between two quaternions 1796 | RMAPI Quaternion QuaternionSlerp(Quaternion q1, Quaternion q2, float amount) 1797 | { 1798 | Quaternion result = { 0 }; 1799 | 1800 | float cosHalfTheta = q1.x*q2.x + q1.y*q2.y + q1.z*q2.z + q1.w*q2.w; 1801 | 1802 | if (cosHalfTheta < 0) 1803 | { 1804 | q2.x = -q2.x; q2.y = -q2.y; q2.z = -q2.z; q2.w = -q2.w; 1805 | cosHalfTheta = -cosHalfTheta; 1806 | } 1807 | 1808 | if (fabsf(cosHalfTheta) >= 1.0f) result = q1; 1809 | else if (cosHalfTheta > 0.95f) result = QuaternionNlerp(q1, q2, amount); 1810 | else 1811 | { 1812 | float halfTheta = acosf(cosHalfTheta); 1813 | float sinHalfTheta = sqrtf(1.0f - cosHalfTheta*cosHalfTheta); 1814 | 1815 | if (fabsf(sinHalfTheta) < 0.001f) 1816 | { 1817 | result.x = (q1.x*0.5f + q2.x*0.5f); 1818 | result.y = (q1.y*0.5f + q2.y*0.5f); 1819 | result.z = (q1.z*0.5f + q2.z*0.5f); 1820 | result.w = (q1.w*0.5f + q2.w*0.5f); 1821 | } 1822 | else 1823 | { 1824 | float ratioA = sinf((1 - amount)*halfTheta)/sinHalfTheta; 1825 | float ratioB = sinf(amount*halfTheta)/sinHalfTheta; 1826 | 1827 | result.x = (q1.x*ratioA + q2.x*ratioB); 1828 | result.y = (q1.y*ratioA + q2.y*ratioB); 1829 | result.z = (q1.z*ratioA + q2.z*ratioB); 1830 | result.w = (q1.w*ratioA + q2.w*ratioB); 1831 | } 1832 | } 1833 | 1834 | return result; 1835 | } 1836 | 1837 | // Calculate quaternion based on the rotation from one vector to another 1838 | RMAPI Quaternion QuaternionFromVector3ToVector3(Vector3 from, Vector3 to) 1839 | { 1840 | Quaternion result = { 0 }; 1841 | 1842 | float cos2Theta = (from.x*to.x + from.y*to.y + from.z*to.z); // Vector3DotProduct(from, to) 1843 | Vector3 cross = { from.y*to.z - from.z*to.y, from.z*to.x - from.x*to.z, from.x*to.y - from.y*to.x }; // Vector3CrossProduct(from, to) 1844 | 1845 | result.x = cross.x; 1846 | result.y = cross.y; 1847 | result.z = cross.z; 1848 | result.w = 1.0f + cos2Theta; 1849 | 1850 | // QuaternionNormalize(q); 1851 | // NOTE: Normalize to essentially nlerp the original and identity to 0.5 1852 | Quaternion q = result; 1853 | float length = sqrtf(q.x*q.x + q.y*q.y + q.z*q.z + q.w*q.w); 1854 | if (length == 0.0f) length = 1.0f; 1855 | float ilength = 1.0f/length; 1856 | 1857 | result.x = q.x*ilength; 1858 | result.y = q.y*ilength; 1859 | result.z = q.z*ilength; 1860 | result.w = q.w*ilength; 1861 | 1862 | return result; 1863 | } 1864 | 1865 | // Get a quaternion for a given rotation matrix 1866 | RMAPI Quaternion QuaternionFromMatrix(Matrix mat) 1867 | { 1868 | Quaternion result = { 0 }; 1869 | 1870 | float fourWSquaredMinus1 = mat.m0 + mat.m5 + mat.m10; 1871 | float fourXSquaredMinus1 = mat.m0 - mat.m5 - mat.m10; 1872 | float fourYSquaredMinus1 = mat.m5 - mat.m0 - mat.m10; 1873 | float fourZSquaredMinus1 = mat.m10 - mat.m0 - mat.m5; 1874 | 1875 | int biggestIndex = 0; 1876 | float fourBiggestSquaredMinus1 = fourWSquaredMinus1; 1877 | if (fourXSquaredMinus1 > fourBiggestSquaredMinus1) 1878 | { 1879 | fourBiggestSquaredMinus1 = fourXSquaredMinus1; 1880 | biggestIndex = 1; 1881 | } 1882 | 1883 | if (fourYSquaredMinus1 > fourBiggestSquaredMinus1) 1884 | { 1885 | fourBiggestSquaredMinus1 = fourYSquaredMinus1; 1886 | biggestIndex = 2; 1887 | } 1888 | 1889 | if (fourZSquaredMinus1 > fourBiggestSquaredMinus1) 1890 | { 1891 | fourBiggestSquaredMinus1 = fourZSquaredMinus1; 1892 | biggestIndex = 3; 1893 | } 1894 | 1895 | float biggestVal = sqrtf(fourBiggestSquaredMinus1 + 1.0f) * 0.5f; 1896 | float mult = 0.25f / biggestVal; 1897 | 1898 | switch (biggestIndex) 1899 | { 1900 | case 0: 1901 | result.w = biggestVal; 1902 | result.x = (mat.m6 - mat.m9) * mult; 1903 | result.y = (mat.m8 - mat.m2) * mult; 1904 | result.z = (mat.m1 - mat.m4) * mult; 1905 | break; 1906 | case 1: 1907 | result.x = biggestVal; 1908 | result.w = (mat.m6 - mat.m9) * mult; 1909 | result.y = (mat.m1 + mat.m4) * mult; 1910 | result.z = (mat.m8 + mat.m2) * mult; 1911 | break; 1912 | case 2: 1913 | result.y = biggestVal; 1914 | result.w = (mat.m8 - mat.m2) * mult; 1915 | result.x = (mat.m1 + mat.m4) * mult; 1916 | result.z = (mat.m6 + mat.m9) * mult; 1917 | break; 1918 | case 3: 1919 | result.z = biggestVal; 1920 | result.w = (mat.m1 - mat.m4) * mult; 1921 | result.x = (mat.m8 + mat.m2) * mult; 1922 | result.y = (mat.m6 + mat.m9) * mult; 1923 | break; 1924 | } 1925 | 1926 | return result; 1927 | } 1928 | 1929 | // Get a matrix for a given quaternion 1930 | RMAPI Matrix QuaternionToMatrix(Quaternion q) 1931 | { 1932 | Matrix result = { 1.0f, 0.0f, 0.0f, 0.0f, 1933 | 0.0f, 1.0f, 0.0f, 0.0f, 1934 | 0.0f, 0.0f, 1.0f, 0.0f, 1935 | 0.0f, 0.0f, 0.0f, 1.0f }; // MatrixIdentity() 1936 | 1937 | float a2 = q.x*q.x; 1938 | float b2 = q.y*q.y; 1939 | float c2 = q.z*q.z; 1940 | float ac = q.x*q.z; 1941 | float ab = q.x*q.y; 1942 | float bc = q.y*q.z; 1943 | float ad = q.w*q.x; 1944 | float bd = q.w*q.y; 1945 | float cd = q.w*q.z; 1946 | 1947 | result.m0 = 1 - 2*(b2 + c2); 1948 | result.m1 = 2*(ab + cd); 1949 | result.m2 = 2*(ac - bd); 1950 | 1951 | result.m4 = 2*(ab - cd); 1952 | result.m5 = 1 - 2*(a2 + c2); 1953 | result.m6 = 2*(bc + ad); 1954 | 1955 | result.m8 = 2*(ac + bd); 1956 | result.m9 = 2*(bc - ad); 1957 | result.m10 = 1 - 2*(a2 + b2); 1958 | 1959 | return result; 1960 | } 1961 | 1962 | // Get rotation quaternion for an angle and axis 1963 | // NOTE: Angle must be provided in radians 1964 | RMAPI Quaternion QuaternionFromAxisAngle(Vector3 axis, float angle) 1965 | { 1966 | Quaternion result = { 0.0f, 0.0f, 0.0f, 1.0f }; 1967 | 1968 | float axisLength = sqrtf(axis.x*axis.x + axis.y*axis.y + axis.z*axis.z); 1969 | 1970 | if (axisLength != 0.0f) 1971 | { 1972 | angle *= 0.5f; 1973 | 1974 | float length = 0.0f; 1975 | float ilength = 0.0f; 1976 | 1977 | // Vector3Normalize(axis) 1978 | Vector3 v = axis; 1979 | length = sqrtf(v.x*v.x + v.y*v.y + v.z*v.z); 1980 | if (length == 0.0f) length = 1.0f; 1981 | ilength = 1.0f/length; 1982 | axis.x *= ilength; 1983 | axis.y *= ilength; 1984 | axis.z *= ilength; 1985 | 1986 | float sinres = sinf(angle); 1987 | float cosres = cosf(angle); 1988 | 1989 | result.x = axis.x*sinres; 1990 | result.y = axis.y*sinres; 1991 | result.z = axis.z*sinres; 1992 | result.w = cosres; 1993 | 1994 | // QuaternionNormalize(q); 1995 | Quaternion q = result; 1996 | length = sqrtf(q.x*q.x + q.y*q.y + q.z*q.z + q.w*q.w); 1997 | if (length == 0.0f) length = 1.0f; 1998 | ilength = 1.0f/length; 1999 | result.x = q.x*ilength; 2000 | result.y = q.y*ilength; 2001 | result.z = q.z*ilength; 2002 | result.w = q.w*ilength; 2003 | } 2004 | 2005 | return result; 2006 | } 2007 | 2008 | // Get the rotation angle and axis for a given quaternion 2009 | RMAPI void QuaternionToAxisAngle(Quaternion q, Vector3 *outAxis, float *outAngle) 2010 | { 2011 | if (fabsf(q.w) > 1.0f) 2012 | { 2013 | // QuaternionNormalize(q); 2014 | float length = sqrtf(q.x*q.x + q.y*q.y + q.z*q.z + q.w*q.w); 2015 | if (length == 0.0f) length = 1.0f; 2016 | float ilength = 1.0f/length; 2017 | 2018 | q.x = q.x*ilength; 2019 | q.y = q.y*ilength; 2020 | q.z = q.z*ilength; 2021 | q.w = q.w*ilength; 2022 | } 2023 | 2024 | Vector3 resAxis = { 0.0f, 0.0f, 0.0f }; 2025 | float resAngle = 2.0f*acosf(q.w); 2026 | float den = sqrtf(1.0f - q.w*q.w); 2027 | 2028 | if (den > 0.0001f) 2029 | { 2030 | resAxis.x = q.x/den; 2031 | resAxis.y = q.y/den; 2032 | resAxis.z = q.z/den; 2033 | } 2034 | else 2035 | { 2036 | // This occurs when the angle is zero. 2037 | // Not a problem: just set an arbitrary normalized axis. 2038 | resAxis.x = 1.0f; 2039 | } 2040 | 2041 | *outAxis = resAxis; 2042 | *outAngle = resAngle; 2043 | } 2044 | 2045 | // Get the quaternion equivalent to Euler angles 2046 | // NOTE: Rotation order is ZYX 2047 | RMAPI Quaternion QuaternionFromEuler(float pitch, float yaw, float roll) 2048 | { 2049 | Quaternion result = { 0 }; 2050 | 2051 | float x0 = cosf(pitch*0.5f); 2052 | float x1 = sinf(pitch*0.5f); 2053 | float y0 = cosf(yaw*0.5f); 2054 | float y1 = sinf(yaw*0.5f); 2055 | float z0 = cosf(roll*0.5f); 2056 | float z1 = sinf(roll*0.5f); 2057 | 2058 | result.x = x1*y0*z0 - x0*y1*z1; 2059 | result.y = x0*y1*z0 + x1*y0*z1; 2060 | result.z = x0*y0*z1 - x1*y1*z0; 2061 | result.w = x0*y0*z0 + x1*y1*z1; 2062 | 2063 | return result; 2064 | } 2065 | 2066 | // Get the Euler angles equivalent to quaternion (roll, pitch, yaw) 2067 | // NOTE: Angles are returned in a Vector3 struct in radians 2068 | RMAPI Vector3 QuaternionToEuler(Quaternion q) 2069 | { 2070 | Vector3 result = { 0 }; 2071 | 2072 | // Roll (x-axis rotation) 2073 | float x0 = 2.0f*(q.w*q.x + q.y*q.z); 2074 | float x1 = 1.0f - 2.0f*(q.x*q.x + q.y*q.y); 2075 | result.x = atan2f(x0, x1); 2076 | 2077 | // Pitch (y-axis rotation) 2078 | float y0 = 2.0f*(q.w*q.y - q.z*q.x); 2079 | y0 = y0 > 1.0f ? 1.0f : y0; 2080 | y0 = y0 < -1.0f ? -1.0f : y0; 2081 | result.y = asinf(y0); 2082 | 2083 | // Yaw (z-axis rotation) 2084 | float z0 = 2.0f*(q.w*q.z + q.x*q.y); 2085 | float z1 = 1.0f - 2.0f*(q.y*q.y + q.z*q.z); 2086 | result.z = atan2f(z0, z1); 2087 | 2088 | return result; 2089 | } 2090 | 2091 | // Transform a quaternion given a transformation matrix 2092 | RMAPI Quaternion QuaternionTransform(Quaternion q, Matrix mat) 2093 | { 2094 | Quaternion result = { 0 }; 2095 | 2096 | result.x = mat.m0*q.x + mat.m4*q.y + mat.m8*q.z + mat.m12*q.w; 2097 | result.y = mat.m1*q.x + mat.m5*q.y + mat.m9*q.z + mat.m13*q.w; 2098 | result.z = mat.m2*q.x + mat.m6*q.y + mat.m10*q.z + mat.m14*q.w; 2099 | result.w = mat.m3*q.x + mat.m7*q.y + mat.m11*q.z + mat.m15*q.w; 2100 | 2101 | return result; 2102 | } 2103 | 2104 | // Check whether two given quaternions are almost equal 2105 | RMAPI int QuaternionEquals(Quaternion p, Quaternion q) 2106 | { 2107 | int result = (((fabsf(p.x - q.x)) <= (EPSILON*fmaxf(1.0f, fmaxf(fabsf(p.x), fabsf(q.x))))) && 2108 | ((fabsf(p.y - q.y)) <= (EPSILON*fmaxf(1.0f, fmaxf(fabsf(p.y), fabsf(q.y))))) && 2109 | ((fabsf(p.z - q.z)) <= (EPSILON*fmaxf(1.0f, fmaxf(fabsf(p.z), fabsf(q.z))))) && 2110 | ((fabsf(p.w - q.w)) <= (EPSILON*fmaxf(1.0f, fmaxf(fabsf(p.w), fabsf(q.w)))))) || 2111 | (((fabsf(p.x + q.x)) <= (EPSILON*fmaxf(1.0f, fmaxf(fabsf(p.x), fabsf(q.x))))) && 2112 | ((fabsf(p.y + q.y)) <= (EPSILON*fmaxf(1.0f, fmaxf(fabsf(p.y), fabsf(q.y))))) && 2113 | ((fabsf(p.z + q.z)) <= (EPSILON*fmaxf(1.0f, fmaxf(fabsf(p.z), fabsf(q.z))))) && 2114 | ((fabsf(p.w + q.w)) <= (EPSILON*fmaxf(1.0f, fmaxf(fabsf(p.w), fabsf(q.w)))))); 2115 | 2116 | return result; 2117 | } 2118 | 2119 | #endif // RAYMATH_H 2120 | -------------------------------------------------------------------------------- /lib/spring.h: -------------------------------------------------------------------------------- 1 | #ifndef SPRING_H 2 | #define SPRING_H 3 | 4 | #include "raylib.h" 5 | #include "raymath.h" 6 | #include "particle.h" 7 | 8 | using namespace std; 9 | 10 | class Spring 11 | { 12 | public: 13 | Spring(); 14 | Spring(float k, float springLength, Particle *a, Particle *b); 15 | ~Spring(); 16 | void Update(); 17 | void Draw(); 18 | void SetDrawInfo(float stroke, Color color); 19 | Particle* GetParticleA(); 20 | Particle* GetParticleB(); 21 | float GetSpringLength(); 22 | private: 23 | Particle* _a; 24 | Particle* _b; 25 | //Spring constant 26 | float _k; 27 | //Spring length not effected by weight 28 | float _springLength; 29 | //extention 30 | float _x = 0; 31 | //spring force 32 | Vector2 _force = Vector2Zero(); 33 | 34 | //Draw 35 | float _stroke = 2; 36 | Color _color = BLACK; 37 | }; 38 | 39 | Spring::Spring(float k, float springLength, Particle *a, Particle *b) 40 | { 41 | _k = k; 42 | _springLength = springLength; 43 | _a = a; 44 | _b = b; 45 | } 46 | 47 | //Delete pointers 48 | Spring::~Spring() 49 | { 50 | delete(_a); 51 | delete(_b); 52 | } 53 | 54 | void Spring::Update() 55 | { 56 | //Get vector from a to b 57 | Vector2 vec = Vector2Subtract(_b->GetPosition(), _a->GetPosition()); 58 | //Get extention 59 | _x = (Vector2Magnitude(vec) - _springLength); 60 | //get direction 61 | _force = Vector2Normalize(vec); 62 | //apply F = -k * x * dir 63 | //Note: we don't -_k straight away, because one particle should go to other position 64 | _force = Vector2Scale(_force, _k * _x); 65 | //add force to particles 66 | _a->AddForce(_force); 67 | //reverse direction 68 | _force = Vector2Scale(_force, -1); 69 | //aad force to another particle 70 | _b->AddForce(_force); 71 | } 72 | 73 | //Draw spring 74 | void Spring::Draw() 75 | { 76 | DrawLineEx(_a->GetPosition(), _b->GetPosition(), _stroke, _color); 77 | } 78 | 79 | //Sets spring draw info 80 | void Spring::SetDrawInfo(float stroke, Color color) 81 | { 82 | _stroke = stroke; 83 | _color = color; 84 | } 85 | 86 | //Returns particle a, that is connected to spring 87 | Particle* Spring::GetParticleA() 88 | { 89 | return _a; 90 | } 91 | 92 | //Returns particle b, that is connected to spring 93 | Particle* Spring::GetParticleB() 94 | { 95 | return _b; 96 | } 97 | 98 | //Returns spring length, between connected particles 99 | float Spring::GetSpringLength() 100 | { 101 | Vector2 vec = Vector2Subtract(_b->GetPosition(), _a->GetPosition()); 102 | return Vector2Length(vec); 103 | } 104 | 105 | #endif -------------------------------------------------------------------------------- /lib/stb_perlin.h: -------------------------------------------------------------------------------- 1 | // stb_perlin.h - v0.2 - perlin noise 2 | // public domain single-file C implementation by Sean Barrett 3 | // 4 | // LICENSE 5 | // 6 | // This software is in the public domain. Where that dedication is not 7 | // recognized, you are granted a perpetual, irrevocable license to copy, 8 | // distribute, and modify this file as you see fit. 9 | // 10 | // 11 | // to create the implementation, 12 | // #define STB_PERLIN_IMPLEMENTATION 13 | // in *one* C/CPP file that includes this file. 14 | 15 | 16 | // Documentation: 17 | // 18 | // float stb_perlin_noise3( float x, 19 | // float y, 20 | // float z, 21 | // int x_wrap=0, 22 | // int y_wrap=0, 23 | // int z_wrap=0) 24 | // 25 | // This function computes a random value at the coordinate (x,y,z). 26 | // Adjacent random values are continuous but the noise fluctuates 27 | // its randomness with period 1, i.e. takes on wholly unrelated values 28 | // at integer points. Specifically, this implements Ken Perlin's 29 | // revised noise function from 2002. 30 | // 31 | // The "wrap" parameters can be used to create wraparound noise that 32 | // wraps at powers of two. The numbers MUST be powers of two. Specify 33 | // 0 to mean "don't care". (The noise always wraps every 256 due 34 | // details of the implementation, even if you ask for larger or no 35 | // wrapping.) 36 | 37 | 38 | #ifdef __cplusplus 39 | extern "C" float stb_perlin_noise3(float x, float y, float z, int x_wrap=0, int y_wrap=0, int z_wrap=0); 40 | #else 41 | extern float stb_perlin_noise3(float x, float y, float z, int x_wrap, int y_wrap, int z_wrap); 42 | #endif 43 | 44 | #include // floor() 45 | 46 | // not same permutation table as Perlin's reference to avoid copyright issues; 47 | // Perlin's table can be found at http://mrl.nyu.edu/~perlin/noise/ 48 | // @OPTIMIZE: should this be unsigned char instead of int for cache? 49 | static int stb__perlin_randtab[512] = 50 | { 51 | 23, 125, 161, 52, 103, 117, 70, 37, 247, 101, 203, 169, 124, 126, 44, 123, 52 | 152, 238, 145, 45, 171, 114, 253, 10, 192, 136, 4, 157, 249, 30, 35, 72, 53 | 175, 63, 77, 90, 181, 16, 96, 111, 133, 104, 75, 162, 93, 56, 66, 240, 54 | 8, 50, 84, 229, 49, 210, 173, 239, 141, 1, 87, 18, 2, 198, 143, 57, 55 | 225, 160, 58, 217, 168, 206, 245, 204, 199, 6, 73, 60, 20, 230, 211, 233, 56 | 94, 200, 88, 9, 74, 155, 33, 15, 219, 130, 226, 202, 83, 236, 42, 172, 57 | 165, 218, 55, 222, 46, 107, 98, 154, 109, 67, 196, 178, 127, 158, 13, 243, 58 | 65, 79, 166, 248, 25, 224, 115, 80, 68, 51, 184, 128, 232, 208, 151, 122, 59 | 26, 212, 105, 43, 179, 213, 235, 148, 146, 89, 14, 195, 28, 78, 112, 76, 60 | 250, 47, 24, 251, 140, 108, 186, 190, 228, 170, 183, 139, 39, 188, 244, 246, 61 | 132, 48, 119, 144, 180, 138, 134, 193, 82, 182, 120, 121, 86, 220, 209, 3, 62 | 91, 241, 149, 85, 205, 150, 113, 216, 31, 100, 41, 164, 177, 214, 153, 231, 63 | 38, 71, 185, 174, 97, 201, 29, 95, 7, 92, 54, 254, 191, 118, 34, 221, 64 | 131, 11, 163, 99, 234, 81, 227, 147, 156, 176, 17, 142, 69, 12, 110, 62, 65 | 27, 255, 0, 194, 59, 116, 242, 252, 19, 21, 187, 53, 207, 129, 64, 135, 66 | 61, 40, 167, 237, 102, 223, 106, 159, 197, 189, 215, 137, 36, 32, 22, 5, 67 | 68 | // and a second copy so we don't need an extra mask or static initializer 69 | 23, 125, 161, 52, 103, 117, 70, 37, 247, 101, 203, 169, 124, 126, 44, 123, 70 | 152, 238, 145, 45, 171, 114, 253, 10, 192, 136, 4, 157, 249, 30, 35, 72, 71 | 175, 63, 77, 90, 181, 16, 96, 111, 133, 104, 75, 162, 93, 56, 66, 240, 72 | 8, 50, 84, 229, 49, 210, 173, 239, 141, 1, 87, 18, 2, 198, 143, 57, 73 | 225, 160, 58, 217, 168, 206, 245, 204, 199, 6, 73, 60, 20, 230, 211, 233, 74 | 94, 200, 88, 9, 74, 155, 33, 15, 219, 130, 226, 202, 83, 236, 42, 172, 75 | 165, 218, 55, 222, 46, 107, 98, 154, 109, 67, 196, 178, 127, 158, 13, 243, 76 | 65, 79, 166, 248, 25, 224, 115, 80, 68, 51, 184, 128, 232, 208, 151, 122, 77 | 26, 212, 105, 43, 179, 213, 235, 148, 146, 89, 14, 195, 28, 78, 112, 76, 78 | 250, 47, 24, 251, 140, 108, 186, 190, 228, 170, 183, 139, 39, 188, 244, 246, 79 | 132, 48, 119, 144, 180, 138, 134, 193, 82, 182, 120, 121, 86, 220, 209, 3, 80 | 91, 241, 149, 85, 205, 150, 113, 216, 31, 100, 41, 164, 177, 214, 153, 231, 81 | 38, 71, 185, 174, 97, 201, 29, 95, 7, 92, 54, 254, 191, 118, 34, 221, 82 | 131, 11, 163, 99, 234, 81, 227, 147, 156, 176, 17, 142, 69, 12, 110, 62, 83 | 27, 255, 0, 194, 59, 116, 242, 252, 19, 21, 187, 53, 207, 129, 64, 135, 84 | 61, 40, 167, 237, 102, 223, 106, 159, 197, 189, 215, 137, 36, 32, 22, 5, 85 | }; 86 | 87 | static float stb__perlin_lerp(float a, float b, float t) 88 | { 89 | return a + (b-a) * t; 90 | } 91 | 92 | // different grad function from Perlin's, but easy to modify to match reference 93 | static float stb__perlin_grad(int hash, float x, float y, float z) 94 | { 95 | static float basis[12][4] = 96 | { 97 | { 1, 1, 0 }, 98 | { -1, 1, 0 }, 99 | { 1,-1, 0 }, 100 | { -1,-1, 0 }, 101 | { 1, 0, 1 }, 102 | { -1, 0, 1 }, 103 | { 1, 0,-1 }, 104 | { -1, 0,-1 }, 105 | { 0, 1, 1 }, 106 | { 0,-1, 1 }, 107 | { 0, 1,-1 }, 108 | { 0,-1,-1 }, 109 | }; 110 | 111 | // perlin's gradient has 12 cases so some get used 1/16th of the time 112 | // and some 2/16ths. We reduce bias by changing those fractions 113 | // to 5/16ths and 6/16ths, and the same 4 cases get the extra weight. 114 | static unsigned char indices[64] = 115 | { 116 | 0,1,2,3,4,5,6,7,8,9,10,11, 117 | 0,9,1,11, 118 | 0,1,2,3,4,5,6,7,8,9,10,11, 119 | 0,1,2,3,4,5,6,7,8,9,10,11, 120 | 0,1,2,3,4,5,6,7,8,9,10,11, 121 | 0,1,2,3,4,5,6,7,8,9,10,11, 122 | }; 123 | 124 | // if you use reference permutation table, change 63 below to 15 to match reference 125 | float *grad = basis[indices[hash & 63]]; 126 | return grad[0]*x + grad[1]*y + grad[2]*z; 127 | } 128 | 129 | float stb_perlin_noise3(float x, float y, float z, int x_wrap, int y_wrap, int z_wrap) 130 | { 131 | float u,v,w; 132 | float n000,n001,n010,n011,n100,n101,n110,n111; 133 | float n00,n01,n10,n11; 134 | float n0,n1; 135 | 136 | unsigned int x_mask = (x_wrap-1) & 255; 137 | unsigned int y_mask = (y_wrap-1) & 255; 138 | unsigned int z_mask = (z_wrap-1) & 255; 139 | int px = (int) floor(x); 140 | int py = (int) floor(y); 141 | int pz = (int) floor(z); 142 | int x0 = px & x_mask, x1 = (px+1) & x_mask; 143 | int y0 = py & y_mask, y1 = (py+1) & y_mask; 144 | int z0 = pz & z_mask, z1 = (pz+1) & z_mask; 145 | int r0,r1, r00,r01,r10,r11; 146 | 147 | #define stb__perlin_ease(a) (((a*6-15)*a + 10) * a * a * a) 148 | 149 | x -= px; u = stb__perlin_ease(x); 150 | y -= py; v = stb__perlin_ease(y); 151 | z -= pz; w = stb__perlin_ease(z); 152 | 153 | r0 = stb__perlin_randtab[x0]; 154 | r1 = stb__perlin_randtab[x1]; 155 | 156 | r00 = stb__perlin_randtab[r0+y0]; 157 | r01 = stb__perlin_randtab[r0+y1]; 158 | r10 = stb__perlin_randtab[r1+y0]; 159 | r11 = stb__perlin_randtab[r1+y1]; 160 | 161 | n000 = stb__perlin_grad(stb__perlin_randtab[r00+z0], x , y , z ); 162 | n001 = stb__perlin_grad(stb__perlin_randtab[r00+z1], x , y , z-1 ); 163 | n010 = stb__perlin_grad(stb__perlin_randtab[r01+z0], x , y-1, z ); 164 | n011 = stb__perlin_grad(stb__perlin_randtab[r01+z1], x , y-1, z-1 ); 165 | n100 = stb__perlin_grad(stb__perlin_randtab[r10+z0], x-1, y , z ); 166 | n101 = stb__perlin_grad(stb__perlin_randtab[r10+z1], x-1, y , z-1 ); 167 | n110 = stb__perlin_grad(stb__perlin_randtab[r11+z0], x-1, y-1, z ); 168 | n111 = stb__perlin_grad(stb__perlin_randtab[r11+z1], x-1, y-1, z-1 ); 169 | 170 | n00 = stb__perlin_lerp(n000,n001,w); 171 | n01 = stb__perlin_lerp(n010,n011,w); 172 | n10 = stb__perlin_lerp(n100,n101,w); 173 | n11 = stb__perlin_lerp(n110,n111,w); 174 | 175 | n0 = stb__perlin_lerp(n00,n01,v); 176 | n1 = stb__perlin_lerp(n10,n11,v); 177 | 178 | return stb__perlin_lerp(n0,n1,u); 179 | } 180 | -------------------------------------------------------------------------------- /src/main.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include "../lib/raylib.h" 4 | #include "../lib/raymath.h" 5 | #include "../lib/particle.h" 6 | #include "../lib/spring.h" 7 | #include "../lib/stb_perlin.h" 8 | 9 | using namespace std; 10 | 11 | int main(void) 12 | { 13 | //Screen variables 14 | const int screenWidth = 1600; 15 | const int screenHeight = 900; 16 | 17 | //Particle and spring instantiation variables 18 | //how many particles per row 19 | int rowCount= 73; 20 | //how many particles per column 21 | int colCount = 15; 22 | //distance between particles in x axis 23 | int paddingX = 20; 24 | //distance between particles in x axis 25 | int paddingY = 8; 26 | //ofset of particles in world position 27 | Vector2 particleOffset = {80, 30}; 28 | 29 | InitWindow(screenWidth, screenHeight, "Cloth Simulation"); 30 | 31 | Particle *particles[rowCount][colCount]; 32 | //Selected particle for draging particles 33 | Particle *selectedParticle = NULL; 34 | vector springs; 35 | 36 | //spring constant, how stiff the string should be 37 | float springK = 0.5; 38 | //max spring length, if it reaches the spring breaks 39 | float maxSpringLength = 220; 40 | Vector2 gravity = {0, 3}; 41 | //Wind variables 42 | Vector2 windDirection = {2, 2}; 43 | float windScale = 0.1; 44 | float windOffsetSpeed = 1; 45 | 46 | SetTargetFPS(144); 47 | 48 | #pragma region Init 49 | 50 | //create grid of particles 51 | for(int x = 0; x < rowCount; x++) 52 | { 53 | for(int y = 0; y < colCount; y++) 54 | { 55 | //if it's top particles, make them static 56 | bool staticParticle = y == 0; 57 | 58 | Particle* particle = new Particle(x * paddingX + particleOffset.x, y * paddingY + particleOffset.y, staticParticle); 59 | particles[x][y] = particle; 60 | } 61 | } 62 | 63 | //create springs for each particles 64 | for(int x = 0; x < rowCount; x++) 65 | { 66 | for(int y = 0; y < colCount; y++) 67 | { 68 | Spring* spring1; 69 | Spring* spring2; 70 | 71 | //if right edge particle , don't add spring on particle right side 72 | if(x != rowCount - 1) 73 | spring1 = new Spring(springK, paddingX, particles[x][y], particles[x+1][y]); 74 | 75 | //if lower edge particles, don't add spring on the down side 76 | if(y != colCount - 1) 77 | spring2 = new Spring(springK, paddingY, particles[x][y], particles[x][y+1]); 78 | 79 | springs.push_back(spring1); 80 | springs.push_back(spring2); 81 | } 82 | } 83 | 84 | #pragma endregion Init 85 | 86 | // Main game loop 87 | while (!WindowShouldClose()) 88 | { 89 | 90 | #pragma region Update 91 | 92 | //Handle string cut logic 93 | if(IsMouseButtonDown(MOUSE_BUTTON_RIGHT)) 94 | { 95 | //iterate through strings 96 | for (int i = 0; i < springs.size(); i++) 97 | { 98 | if(springs[i] == NULL) 99 | continue; 100 | 101 | //get particle positions 102 | Vector2 posA = springs[i]->GetParticleA()->GetPosition(); 103 | Vector2 posB = springs[i]->GetParticleB()->GetPosition(); 104 | 105 | //remove string if mouse collides string 106 | //20 - collisios treshold 107 | if(CheckCollisionPointLine(GetMousePosition(), posA, posB, 5)) 108 | { 109 | springs[i] = NULL; 110 | delete(springs[i]); 111 | break; 112 | } 113 | } 114 | } 115 | 116 | //Handle select particle click logic 117 | if(IsMouseButtonPressed(MOUSE_BUTTON_LEFT)) 118 | { 119 | //Some big dinstance 120 | float distance = 1000; 121 | 122 | //iterate through particles 123 | for(int x = 0; x < rowCount; x++) 124 | { 125 | for(int y = 0; y < colCount; y++) 126 | { 127 | //get ndistance between particle and mouse 128 | float newDis = Vector2Distance(particles[x][y]->GetPosition(), GetMousePosition()); 129 | 130 | //if the new distance is smaller then last distance, select particle 131 | if(newDis < distance) 132 | { 133 | distance = newDis; 134 | selectedParticle = particles[x][y]; 135 | } 136 | } 137 | } 138 | } 139 | 140 | //Handle drag particle logic 141 | if(IsMouseButtonDown(MOUSE_BUTTON_LEFT)) 142 | { 143 | selectedParticle->SetPosition(GetMousePosition().x, GetMousePosition().y); 144 | } 145 | 146 | //Update strings 147 | for (int i = 0; i < springs.size(); i++) 148 | { 149 | if(springs[i] == NULL) 150 | continue; 151 | 152 | //if the string length is more than max, destroy it 153 | if(springs[i]->GetSpringLength() > maxSpringLength) 154 | { 155 | springs[i] = NULL; 156 | delete(springs[i]); 157 | continue; 158 | } 159 | 160 | //update string calculation 161 | springs[i]->Update(); 162 | } 163 | 164 | //Update particles 165 | for(int x = 0; x < rowCount; x++) 166 | { 167 | for(int y = 0; y < colCount; y++) 168 | { 169 | //Add gravity to particles 170 | particles[x][y]->AddForce(gravity); 171 | 172 | //Wind force 173 | float noise = stb_perlin_noise3((float)x * windScale + GetTime() * windOffsetSpeed, (float)y * windScale + GetTime() * windOffsetSpeed, 0, 0, 0, 0); 174 | Vector2 wind = Vector2Scale(windDirection, noise); 175 | particles[x][y]->AddForce(wind); 176 | 177 | //Update particle 178 | particles[x][y]->Update(); 179 | } 180 | } 181 | 182 | #pragma endregion Update 183 | 184 | #pragma region Draw 185 | 186 | BeginDrawing(); 187 | 188 | ClearBackground(RAYWHITE); 189 | 190 | //draw spring visuals 191 | for(auto spring : springs) 192 | { 193 | if(spring == NULL) 194 | continue; 195 | 196 | spring->Draw(); 197 | } 198 | 199 | //draw particle visuals 200 | for(int x = 0; x < rowCount; x++) 201 | { 202 | for(int y = 0; y < colCount; y++) 203 | { 204 | if(y == 0) 205 | particles[x][y]->Draw(); 206 | } 207 | } 208 | 209 | EndDrawing(); 210 | 211 | #pragma endregion Draw 212 | 213 | } 214 | 215 | // Close window and OpenGL context 216 | CloseWindow(); 217 | 218 | return 0; 219 | } --------------------------------------------------------------------------------