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