├── .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 |
17 |
18 |
19 |
20 |
21 |
22 |
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 | }
--------------------------------------------------------------------------------