first commit
commit
222e08b155
@ -0,0 +1,592 @@
|
|||||||
|
/**********************************************************************************************
|
||||||
|
*
|
||||||
|
* raymath v1.5 - Math functions to work with Vector2, Vector3, Matrix and Quaternions
|
||||||
|
*
|
||||||
|
* CONFIGURATION:
|
||||||
|
*
|
||||||
|
* #define RAYMATH_IMPLEMENTATION
|
||||||
|
* Generates the implementation of the library into the included file.
|
||||||
|
* If not defined, the library is in header only mode and can be included in other headers
|
||||||
|
* or source files without problems. But only ONE file should hold the implementation.
|
||||||
|
*
|
||||||
|
* #define RAYMATH_STATIC_INLINE
|
||||||
|
* Define static inline functions code, so #include header suffices for use.
|
||||||
|
* This may use up lots of memory.
|
||||||
|
*
|
||||||
|
* CONVENTIONS:
|
||||||
|
*
|
||||||
|
* - Functions are always self-contained, no function use another raymath function inside,
|
||||||
|
* required code is directly re-implemented inside
|
||||||
|
* - Functions input parameters are always received by value (2 unavoidable exceptions);
|
||||||
|
* - Functions use always a "result" variable for return
|
||||||
|
* - Functions are always defined inline
|
||||||
|
* - Angles are always in radians (DEG2RAD/RAD2DEG macros provided for convenience);
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* LICENSE: zlib/libpng
|
||||||
|
*
|
||||||
|
* Copyright (c); 2015-2023 Ramon Santamaria (@raysan5);
|
||||||
|
*
|
||||||
|
* This software is provided "as-is", without any express or implied warranty. In no event
|
||||||
|
* will the authors be held liable for any damages arising from the use of this software.
|
||||||
|
*
|
||||||
|
* Permission is granted to anyone to use this software for any purpose, including commercial
|
||||||
|
* applications, and to alter it and redistribute it freely, subject to the following restrictions:
|
||||||
|
*
|
||||||
|
* 1. The origin of this software must not be misrepresented; you must not claim that you
|
||||||
|
* wrote the original software. If you use this software in a product, an acknowledgment
|
||||||
|
* in the product documentation would be appreciated but is not required.
|
||||||
|
*
|
||||||
|
* 2. Altered source versions must be plainly marked as such, and must not be misrepresented
|
||||||
|
* as being the original software.
|
||||||
|
*
|
||||||
|
* 3. This notice may not be removed or altered from any source distribution.
|
||||||
|
*
|
||||||
|
**********************************************************************************************/
|
||||||
|
|
||||||
|
#ifndef RAYMATH_H
|
||||||
|
#define RAYMATH_H
|
||||||
|
|
||||||
|
#if defined(RAYMATH_IMPLEMENTATION) && defined(RAYMATH_STATIC_INLINE)
|
||||||
|
#error "Specifying both RAYMATH_IMPLEMENTATION and RAYMATH_STATIC_INLINE is contradictory"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// Function specifiers definition
|
||||||
|
#if defined(RAYMATH_IMPLEMENTATION)
|
||||||
|
#if defined(_WIN32); && defined(BUILD_LIBTYPE_SHARED);
|
||||||
|
#define RMAPI __declspec(dllexport); extern inline // We are building raylib as a Win32 shared library (.dll);.
|
||||||
|
#elif defined(_WIN32); && defined(USE_LIBTYPE_SHARED);
|
||||||
|
#define RMAPI __declspec(dllimport); // We are using raylib as a Win32 shared library (.dll);
|
||||||
|
#else
|
||||||
|
#define RMAPI extern inline // Provide external definition
|
||||||
|
#endif
|
||||||
|
#elif defined(RAYMATH_STATIC_INLINE)
|
||||||
|
#define RMAPI static inline // Functions may be inlined, no external out-of-line definition
|
||||||
|
#else
|
||||||
|
#if defined(__TINYC__)
|
||||||
|
#define RMAPI static inline // plain inline not supported by tinycc (See issue #435);
|
||||||
|
#else
|
||||||
|
#define RMAPI inline // Functions may be inlined or external definition used
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------------
|
||||||
|
// Defines and Macros
|
||||||
|
//----------------------------------------------------------------------------------
|
||||||
|
#ifndef PI
|
||||||
|
#define PI 3.14159265358979323846f
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef EPSILON
|
||||||
|
#define EPSILON 0.000001f
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef DEG2RAD
|
||||||
|
#define DEG2RAD (PI/180.0f)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef RAD2DEG
|
||||||
|
#define RAD2DEG (180.0f/PI)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// Get float vector for Matrix
|
||||||
|
#ifndef MatrixToFloat
|
||||||
|
#define MatrixToFloat(mat) (MatrixToFloatV(mat).v)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// Get float vector for Vector3
|
||||||
|
#ifndef Vector3ToFloat
|
||||||
|
#define Vector3ToFloat(vec) (Vector3ToFloatV(vec).v)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------------
|
||||||
|
// Types and Structures Definition
|
||||||
|
//----------------------------------------------------------------------------------
|
||||||
|
#if !defined(RL_VECTOR2_TYPE)
|
||||||
|
// Vector2 type
|
||||||
|
typedef struct Vector2 {
|
||||||
|
float x;
|
||||||
|
float y;
|
||||||
|
} Vector2;
|
||||||
|
#define RL_VECTOR2_TYPE
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if !defined(RL_VECTOR3_TYPE)
|
||||||
|
// Vector3 type
|
||||||
|
typedef struct Vector3 {
|
||||||
|
float x;
|
||||||
|
float y;
|
||||||
|
float z;
|
||||||
|
} Vector3;
|
||||||
|
#define RL_VECTOR3_TYPE
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if !defined(RL_VECTOR4_TYPE)
|
||||||
|
// Vector4 type
|
||||||
|
typedef struct Vector4 {
|
||||||
|
float x;
|
||||||
|
float y;
|
||||||
|
float z;
|
||||||
|
float w;
|
||||||
|
} Vector4;
|
||||||
|
#define RL_VECTOR4_TYPE
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if !defined(RL_QUATERNION_TYPE)
|
||||||
|
// Quaternion type
|
||||||
|
typedef Vector4 Quaternion;
|
||||||
|
#define RL_QUATERNION_TYPE
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if !defined(RL_MATRIX_TYPE)
|
||||||
|
// Matrix type (OpenGL style 4x4 - right handed, column major);
|
||||||
|
typedef struct Matrix {
|
||||||
|
float m0, m4, m8, m12; // Matrix first row (4 components);
|
||||||
|
float m1, m5, m9, m13; // Matrix second row (4 components);
|
||||||
|
float m2, m6, m10, m14; // Matrix third row (4 components);
|
||||||
|
float m3, m7, m11, m15; // Matrix fourth row (4 components);
|
||||||
|
} Matrix;
|
||||||
|
#define RL_MATRIX_TYPE
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// NOTE: Helper types to be used instead of array return types for *ToFloat functions
|
||||||
|
typedef struct float3 {
|
||||||
|
float v[3];
|
||||||
|
} float3;
|
||||||
|
|
||||||
|
typedef struct float16 {
|
||||||
|
float v[16];
|
||||||
|
} float16;
|
||||||
|
|
||||||
|
#include <math.h> // Required for: sinf();, cosf();, tan();, atan2f();, sqrtf();, floor();, fminf();, fmaxf();, fabs();
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------------
|
||||||
|
// Module Functions Definition - Utils math
|
||||||
|
//----------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
// Clamp float value
|
||||||
|
RMAPI float Clamp(float value, float min, float max);;
|
||||||
|
|
||||||
|
// Calculate linear interpolation between two floats
|
||||||
|
RMAPI float Lerp(float start, float end, float amount);;
|
||||||
|
|
||||||
|
// Normalize input value within input range
|
||||||
|
RMAPI float Normalize(float value, float start, float end);;
|
||||||
|
|
||||||
|
// Remap input value within input range to output range
|
||||||
|
RMAPI float Remap(float value, float inputStart, float inputEnd, float outputStart, float outputEnd);;
|
||||||
|
|
||||||
|
// Wrap input value from min to max
|
||||||
|
RMAPI float Wrap(float value, float min, float max);;
|
||||||
|
|
||||||
|
// Check whether two given floats are almost equal
|
||||||
|
RMAPI int FloatEquals(float x, float y);;
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------------
|
||||||
|
// Module Functions Definition - Vector2 math
|
||||||
|
//----------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
// Vector with components value 0.0f
|
||||||
|
RMAPI Vector2 Vector2Zero(void);;
|
||||||
|
|
||||||
|
// Vector with components value 1.0f
|
||||||
|
RMAPI Vector2 Vector2One(void);;
|
||||||
|
|
||||||
|
// Add two vectors (v1 + v2);
|
||||||
|
RMAPI Vector2 Vector2Add(Vector2 v1, Vector2 v2);;
|
||||||
|
|
||||||
|
// Add vector and float value
|
||||||
|
RMAPI Vector2 Vector2AddValue(Vector2 v, float add);
|
||||||
|
|
||||||
|
// Subtract two vectors (v1 - v2);
|
||||||
|
RMAPI Vector2 Vector2Subtract(Vector2 v1, Vector2 v2);
|
||||||
|
|
||||||
|
// Subtract vector by float value
|
||||||
|
RMAPI Vector2 Vector2SubtractValue(Vector2 v, float sub);
|
||||||
|
|
||||||
|
// Calculate vector length
|
||||||
|
RMAPI float Vector2Length(Vector2 v);
|
||||||
|
|
||||||
|
// Calculate vector square length
|
||||||
|
RMAPI float Vector2LengthSqr(Vector2 v);
|
||||||
|
|
||||||
|
// Calculate two vectors dot product
|
||||||
|
RMAPI float Vector2DotProduct(Vector2 v1, Vector2 v2);
|
||||||
|
|
||||||
|
// Calculate distance between two vectors
|
||||||
|
RMAPI float Vector2Distance(Vector2 v1, Vector2 v2);
|
||||||
|
|
||||||
|
// Calculate square distance between two vectors
|
||||||
|
RMAPI float Vector2DistanceSqr(Vector2 v1, Vector2 v2);
|
||||||
|
|
||||||
|
// Calculate angle between two vectors
|
||||||
|
// NOTE: Angle is calculated from origin point (0, 0);
|
||||||
|
RMAPI float Vector2Angle(Vector2 v1, Vector2 v2);
|
||||||
|
|
||||||
|
// Calculate angle defined by a two vectors line
|
||||||
|
// NOTE: Parameters need to be normalized
|
||||||
|
// Current implementation should be aligned with glm::angle
|
||||||
|
RMAPI float Vector2LineAngle(Vector2 start, Vector2 end);
|
||||||
|
|
||||||
|
// Scale vector (multiply by value);
|
||||||
|
RMAPI Vector2 Vector2Scale(Vector2 v, float scale);
|
||||||
|
|
||||||
|
// Multiply vector by vector
|
||||||
|
RMAPI Vector2 Vector2Multiply(Vector2 v1, Vector2 v2);
|
||||||
|
|
||||||
|
// Negate vector
|
||||||
|
RMAPI Vector2 Vector2Negate(Vector2 v);
|
||||||
|
// Divide vector by vector
|
||||||
|
RMAPI Vector2 Vector2Divide(Vector2 v1, Vector2 v2);
|
||||||
|
// Normalize provided vector
|
||||||
|
RMAPI Vector2 Vector2Normalize(Vector2 v);
|
||||||
|
|
||||||
|
// Transforms a Vector2 by a given Matrix
|
||||||
|
RMAPI Vector2 Vector2Transform(Vector2 v, Matrix mat);
|
||||||
|
|
||||||
|
// Calculate linear interpolation between two vectors
|
||||||
|
RMAPI Vector2 Vector2Lerp(Vector2 v1, Vector2 v2, float amount);
|
||||||
|
|
||||||
|
// Calculate reflected vector to normal
|
||||||
|
RMAPI Vector2 Vector2Reflect(Vector2 v, Vector2 normal);
|
||||||
|
|
||||||
|
// Rotate vector by angle
|
||||||
|
RMAPI Vector2 Vector2Rotate(Vector2 v, float angle);
|
||||||
|
|
||||||
|
// Move Vector towards target
|
||||||
|
RMAPI Vector2 Vector2MoveTowards(Vector2 v, Vector2 target, float maxDistance);
|
||||||
|
|
||||||
|
// Invert the given vector
|
||||||
|
RMAPI Vector2 Vector2Invert(Vector2 v);
|
||||||
|
// Clamp the components of the vector between
|
||||||
|
// min and max values specified by the given vectors
|
||||||
|
RMAPI Vector2 Vector2Clamp(Vector2 v, Vector2 min, Vector2 max);
|
||||||
|
|
||||||
|
// Clamp the magnitude of the vector between two min and max values
|
||||||
|
RMAPI Vector2 Vector2ClampValue(Vector2 v, float min, float max);
|
||||||
|
|
||||||
|
// Check whether two given vectors are almost equal
|
||||||
|
RMAPI int Vector2Equals(Vector2 p, Vector2 q);
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------------
|
||||||
|
// Module Functions Definition - Vector3 math
|
||||||
|
//----------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
// Vector with components value 0.0f
|
||||||
|
RMAPI Vector3 Vector3Zero(void);
|
||||||
|
|
||||||
|
// Vector with components value 1.0f
|
||||||
|
RMAPI Vector3 Vector3One(void);
|
||||||
|
|
||||||
|
// Add two vectors
|
||||||
|
RMAPI Vector3 Vector3Add(Vector3 v1, Vector3 v2);
|
||||||
|
|
||||||
|
// Add vector and float value
|
||||||
|
RMAPI Vector3 Vector3AddValue(Vector3 v, float add);
|
||||||
|
|
||||||
|
// Subtract two vectors
|
||||||
|
RMAPI Vector3 Vector3Subtract(Vector3 v1, Vector3 v2);
|
||||||
|
|
||||||
|
// Subtract vector by float value
|
||||||
|
RMAPI Vector3 Vector3SubtractValue(Vector3 v, float sub);
|
||||||
|
|
||||||
|
// Multiply vector by scalar
|
||||||
|
RMAPI Vector3 Vector3Scale(Vector3 v, float scalar);
|
||||||
|
|
||||||
|
// Multiply vector by vector
|
||||||
|
RMAPI Vector3 Vector3Multiply(Vector3 v1, Vector3 v2);
|
||||||
|
|
||||||
|
// Calculate two vectors cross product
|
||||||
|
RMAPI Vector3 Vector3CrossProduct(Vector3 v1, Vector3 v2);
|
||||||
|
|
||||||
|
// Calculate one vector perpendicular vector
|
||||||
|
RMAPI Vector3 Vector3Perpendicular(Vector3 v);
|
||||||
|
|
||||||
|
// Calculate vector length
|
||||||
|
RMAPI float Vector3Length(const Vector3 v);
|
||||||
|
|
||||||
|
// Calculate vector square length
|
||||||
|
RMAPI float Vector3LengthSqr(const Vector3 v);
|
||||||
|
|
||||||
|
// Calculate two vectors dot product
|
||||||
|
RMAPI float Vector3DotProduct(Vector3 v1, Vector3 v2);
|
||||||
|
|
||||||
|
// Calculate distance between two vectors
|
||||||
|
RMAPI float Vector3Distance(Vector3 v1, Vector3 v2);
|
||||||
|
|
||||||
|
// Calculate square distance between two vectors
|
||||||
|
RMAPI float Vector3DistanceSqr(Vector3 v1, Vector3 v2);
|
||||||
|
|
||||||
|
// Calculate angle between two vectors
|
||||||
|
RMAPI float Vector3Angle(Vector3 v1, Vector3 v2);
|
||||||
|
|
||||||
|
// Negate provided vector (invert direction);
|
||||||
|
RMAPI Vector3 Vector3Negate(Vector3 v);
|
||||||
|
|
||||||
|
// Divide vector by vector
|
||||||
|
RMAPI Vector3 Vector3Divide(Vector3 v1, Vector3 v2);
|
||||||
|
|
||||||
|
// Normalize provided vector
|
||||||
|
RMAPI Vector3 Vector3Normalize(Vector3 v);
|
||||||
|
|
||||||
|
// Orthonormalize provided vectors
|
||||||
|
// Makes vectors normalized and orthogonal to each other
|
||||||
|
// Gram-Schmidt function implementation
|
||||||
|
RMAPI void Vector3OrthoNormalize(Vector3 *v1, Vector3 *v2);
|
||||||
|
|
||||||
|
// Transforms a Vector3 by a given Matrix
|
||||||
|
RMAPI Vector3 Vector3Transform(Vector3 v, Matrix mat);
|
||||||
|
|
||||||
|
// Transform a vector by quaternion rotation
|
||||||
|
RMAPI Vector3 Vector3RotateByQuaternion(Vector3 v, Quaternion q);
|
||||||
|
|
||||||
|
// Rotates a vector around an axis
|
||||||
|
RMAPI Vector3 Vector3RotateByAxisAngle(Vector3 v, Vector3 axis, float angle);
|
||||||
|
|
||||||
|
// Calculate linear interpolation between two vectors
|
||||||
|
RMAPI Vector3 Vector3Lerp(Vector3 v1, Vector3 v2, float amount);
|
||||||
|
|
||||||
|
// Calculate reflected vector to normal
|
||||||
|
RMAPI Vector3 Vector3Reflect(Vector3 v, Vector3 normal);
|
||||||
|
|
||||||
|
// Get min value for each pair of components
|
||||||
|
RMAPI Vector3 Vector3Min(Vector3 v1, Vector3 v2);
|
||||||
|
// Get max value for each pair of components
|
||||||
|
RMAPI Vector3 Vector3Max(Vector3 v1, Vector3 v2);
|
||||||
|
|
||||||
|
// Compute barycenter coordinates (u, v, w); for point p with respect to triangle (a, b, c);
|
||||||
|
// NOTE: Assumes P is on the plane of the triangle
|
||||||
|
RMAPI Vector3 Vector3Barycenter(Vector3 p, Vector3 a, Vector3 b, Vector3 c);
|
||||||
|
|
||||||
|
// Projects a Vector3 from screen space into object space
|
||||||
|
// NOTE: We are avoiding calling other raymath functions despite available
|
||||||
|
RMAPI Vector3 Vector3Unproject(Vector3 source, Matrix projection, Matrix view);
|
||||||
|
|
||||||
|
// Get Vector3 as float array
|
||||||
|
RMAPI float3 Vector3ToFloatV(Vector3 v);
|
||||||
|
|
||||||
|
// Invert the given vector
|
||||||
|
RMAPI Vector3 Vector3Invert(Vector3 v);
|
||||||
|
|
||||||
|
// Clamp the components of the vector between
|
||||||
|
// min and max values specified by the given vectors
|
||||||
|
RMAPI Vector3 Vector3Clamp(Vector3 v, Vector3 min, Vector3 max);
|
||||||
|
|
||||||
|
// Clamp the magnitude of the vector between two values
|
||||||
|
RMAPI Vector3 Vector3ClampValue(Vector3 v, float min, float max);
|
||||||
|
|
||||||
|
// Check whether two given vectors are almost equal
|
||||||
|
RMAPI int Vector3Equals(Vector3 p, Vector3 q);
|
||||||
|
|
||||||
|
// Compute the direction of a refracted ray where v specifies the
|
||||||
|
// normalized direction of the incoming ray, n specifies the
|
||||||
|
// normalized normal vector of the interface of two optical media,
|
||||||
|
// and r specifies the ratio of the refractive index of the medium
|
||||||
|
// from where the ray comes to the refractive index of the medium
|
||||||
|
// on the other side of the surface
|
||||||
|
RMAPI Vector3 Vector3Refract(Vector3 v, Vector3 n, float r);
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------------
|
||||||
|
// Module Functions Definition - Matrix math
|
||||||
|
//----------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
// Compute matrix determinant
|
||||||
|
RMAPI float MatrixDeterminant(Matrix mat);
|
||||||
|
|
||||||
|
// Get the trace of the matrix (sum of the values along the diagonal);
|
||||||
|
RMAPI float MatrixTrace(Matrix mat);
|
||||||
|
|
||||||
|
// Transposes provided matrix
|
||||||
|
RMAPI Matrix MatrixTranspose(Matrix mat);
|
||||||
|
|
||||||
|
// Invert provided matrix
|
||||||
|
RMAPI Matrix MatrixInvert(Matrix mat);
|
||||||
|
|
||||||
|
// Get identity matrix
|
||||||
|
RMAPI Matrix MatrixIdentity(void);
|
||||||
|
|
||||||
|
// Add two matrices
|
||||||
|
RMAPI Matrix MatrixAdd(Matrix left, Matrix right);
|
||||||
|
|
||||||
|
// Subtract two matrices (left - right);
|
||||||
|
RMAPI Matrix MatrixSubtract(Matrix left, Matrix right);
|
||||||
|
|
||||||
|
// Get two matrix multiplication
|
||||||
|
// NOTE: When multiplying matrices... the order matters!
|
||||||
|
RMAPI Matrix MatrixMultiply(Matrix left, Matrix right);
|
||||||
|
|
||||||
|
// Get translation matrix
|
||||||
|
RMAPI Matrix MatrixTranslate(float x, float y, float z);
|
||||||
|
|
||||||
|
// Create rotation matrix from axis and angle
|
||||||
|
// NOTE: Angle should be provided in radians
|
||||||
|
RMAPI Matrix MatrixRotate(Vector3 axis, float angle);
|
||||||
|
|
||||||
|
// Get x-rotation matrix
|
||||||
|
// NOTE: Angle must be provided in radians
|
||||||
|
RMAPI Matrix MatrixRotateX(float angle);
|
||||||
|
|
||||||
|
// Get y-rotation matrix
|
||||||
|
// NOTE: Angle must be provided in radians
|
||||||
|
RMAPI Matrix MatrixRotateY(float angle);
|
||||||
|
|
||||||
|
// Get z-rotation matrix
|
||||||
|
// NOTE: Angle must be provided in radians
|
||||||
|
RMAPI Matrix MatrixRotateZ(float angle);
|
||||||
|
|
||||||
|
|
||||||
|
// Get xyz-rotation matrix
|
||||||
|
// NOTE: Angle must be provided in radians
|
||||||
|
RMAPI Matrix MatrixRotateXYZ(Vector3 angle);
|
||||||
|
|
||||||
|
// Get zyx-rotation matrix
|
||||||
|
// NOTE: Angle must be provided in radians
|
||||||
|
RMAPI Matrix MatrixRotateZYX(Vector3 angle);
|
||||||
|
|
||||||
|
// Get scaling matrix
|
||||||
|
RMAPI Matrix MatrixScale(float x, float y, float z);
|
||||||
|
|
||||||
|
// Get perspective projection matrix
|
||||||
|
RMAPI Matrix MatrixFrustum(double left, double right, double bottom, double top, double near, double far);
|
||||||
|
|
||||||
|
// Get perspective projection matrix
|
||||||
|
// NOTE: Fovy angle must be provided in radians
|
||||||
|
RMAPI Matrix MatrixPerspective(double fovy, double aspect, double near, double far);
|
||||||
|
|
||||||
|
// Get orthographic projection matrix
|
||||||
|
RMAPI Matrix MatrixOrtho(double left, double right, double bottom, double top, double near, double far);
|
||||||
|
|
||||||
|
// Get camera look-at matrix (view matrix);
|
||||||
|
RMAPI Matrix MatrixLookAt(Vector3 eye, Vector3 target, Vector3 up);
|
||||||
|
|
||||||
|
// Get float array of matrix data
|
||||||
|
RMAPI float16 MatrixToFloatV(Matrix mat);
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------------
|
||||||
|
// Module Functions Definition - Quaternion math
|
||||||
|
//----------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
// Add two quaternions
|
||||||
|
RMAPI Quaternion QuaternionAdd(Quaternion q1, Quaternion q2);
|
||||||
|
|
||||||
|
// Add quaternion and float value
|
||||||
|
RMAPI Quaternion QuaternionAddValue(Quaternion q, float add);
|
||||||
|
|
||||||
|
// Subtract two quaternions
|
||||||
|
RMAPI Quaternion QuaternionSubtract(Quaternion q1, Quaternion q2);
|
||||||
|
|
||||||
|
// Subtract quaternion and float value
|
||||||
|
RMAPI Quaternion QuaternionSubtractValue(Quaternion q, float sub);
|
||||||
|
|
||||||
|
// Get identity quaternion
|
||||||
|
RMAPI Quaternion QuaternionIdentity(void);
|
||||||
|
|
||||||
|
// Computes the length of a quaternion
|
||||||
|
RMAPI float QuaternionLength(Quaternion q);
|
||||||
|
|
||||||
|
// Normalize provided quaternion
|
||||||
|
RMAPI Quaternion QuaternionNormalize(Quaternion q);
|
||||||
|
|
||||||
|
// Invert provided quaternion
|
||||||
|
RMAPI Quaternion QuaternionInvert(Quaternion q);
|
||||||
|
|
||||||
|
// Calculate two quaternion multiplication
|
||||||
|
RMAPI Quaternion QuaternionMultiply(Quaternion q1, Quaternion q2);
|
||||||
|
// Scale quaternion by float value
|
||||||
|
RMAPI Quaternion QuaternionScale(Quaternion q, float mul);
|
||||||
|
|
||||||
|
// Divide two quaternions
|
||||||
|
RMAPI Quaternion QuaternionDivide(Quaternion q1, Quaternion q2);
|
||||||
|
|
||||||
|
// Calculate linear interpolation between two quaternions
|
||||||
|
RMAPI Quaternion QuaternionLerp(Quaternion q1, Quaternion q2, float amount);
|
||||||
|
|
||||||
|
// Calculate slerp-optimized interpolation between two quaternions
|
||||||
|
RMAPI Quaternion QuaternionNlerp(Quaternion q1, Quaternion q2, float amount);
|
||||||
|
|
||||||
|
// Calculates spherical linear interpolation between two quaternions
|
||||||
|
RMAPI Quaternion QuaternionSlerp(Quaternion q1, Quaternion q2, float amount);
|
||||||
|
|
||||||
|
// Calculate quaternion based on the rotation from one vector to another
|
||||||
|
RMAPI Quaternion QuaternionFromVector3ToVector3(Vector3 from, Vector3 to);
|
||||||
|
|
||||||
|
// Get a quaternion for a given rotation matrix
|
||||||
|
RMAPI Quaternion QuaternionFromMatrix(Matrix mat);
|
||||||
|
|
||||||
|
// Get a matrix for a given quaternion
|
||||||
|
RMAPI Matrix QuaternionToMatrix(Quaternion q);
|
||||||
|
|
||||||
|
// Get rotation quaternion for an angle and axis
|
||||||
|
// NOTE: Angle must be provided in radians
|
||||||
|
RMAPI Quaternion QuaternionFromAxisAngle(Vector3 axis, float angle);
|
||||||
|
|
||||||
|
// Get the rotation angle and axis for a given quaternion
|
||||||
|
RMAPI void QuaternionToAxisAngle(Quaternion q, Vector3 *outAxis, float *outAngle);
|
||||||
|
// Get the quaternion equivalent to Euler angles
|
||||||
|
// NOTE: Rotation order is ZYX
|
||||||
|
RMAPI Quaternion QuaternionFromEuler(float pitch, float yaw, float roll);
|
||||||
|
|
||||||
|
// Get the Euler angles equivalent to quaternion (roll, pitch, yaw);
|
||||||
|
// NOTE: Angles are returned in a Vector3 struct in radians
|
||||||
|
RMAPI Vector3 QuaternionToEuler(Quaternion q);
|
||||||
|
|
||||||
|
// Transform a quaternion given a transformation matrix
|
||||||
|
RMAPI Quaternion QuaternionTransform(Quaternion q, Matrix mat);
|
||||||
|
|
||||||
|
// Check whether two given quaternions are almost equal
|
||||||
|
RMAPI int QuaternionEquals(Quaternion p, Quaternion q);
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef YESMATH
|
||||||
|
// Ray, ray for raycasting
|
||||||
|
typedef struct Ray {
|
||||||
|
Vector3 position; // Ray position (origin)
|
||||||
|
Vector3 direction; // Ray direction (normalized)
|
||||||
|
} Ray;
|
||||||
|
|
||||||
|
// RayCollision, ray hit information
|
||||||
|
typedef struct RayCollision {
|
||||||
|
bool hit; // Did the ray hit something?
|
||||||
|
float distance; // Distance to the nearest hit
|
||||||
|
Vector3 point; // Point of the nearest hit
|
||||||
|
Vector3 normal; // Surface normal of hit
|
||||||
|
} RayCollision;
|
||||||
|
|
||||||
|
// BoundingBox
|
||||||
|
typedef struct BoundingBox {
|
||||||
|
Vector3 min; // Minimum vertex box-corner
|
||||||
|
Vector3 max; // Maximum vertex box-corner
|
||||||
|
} BoundingBox;
|
||||||
|
|
||||||
|
// Camera type, defines a camera position/orientation in 3d space
|
||||||
|
typedef struct Camera3D {
|
||||||
|
Vector3 position; // Camera position
|
||||||
|
Vector3 target; // Camera target it looks-at
|
||||||
|
Vector3 up; // Camera up vector (rotation over its axis)
|
||||||
|
float fovy; // Camera field-of-view apperture in Y (degrees) in perspective, used as near plane width in orthographic
|
||||||
|
int projection; // Camera projection type: CAMERA_PERSPECTIVE or CAMERA_ORTHOGRAPHIC
|
||||||
|
} Camera3D;
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
RayCollision ObjectiveCBugFixRaycast(Camera3D camera, BoundingBox bbox);
|
||||||
|
Vector3 MidpointBoundingBox(BoundingBox bbox);
|
||||||
|
RLAPI Vector3 GetCameraForward(Camera *camera);
|
||||||
|
RLAPI Vector3 GetCameraUp(Camera *camera);
|
||||||
|
RLAPI Vector3 GetCameraRight(Camera *camera);
|
||||||
|
|
||||||
|
// Camera movement
|
||||||
|
RLAPI void CameraMoveForward(Camera *camera, float distance, bool moveInWorldPlane);
|
||||||
|
RLAPI void CameraMoveUp(Camera *camera, float distance);
|
||||||
|
RLAPI void CameraMoveRight(Camera *camera, float distance, bool moveInWorldPlane);
|
||||||
|
RLAPI void CameraMoveToTarget(Camera *camera, float delta);
|
||||||
|
|
||||||
|
// Camera rotation
|
||||||
|
RLAPI void CameraYaw(Camera *camera, float angle, bool rotateAroundTarget);
|
||||||
|
RLAPI void CameraPitch(Camera *camera, float angle, bool lockView, bool rotateAroundTarget, bool rotateUp);
|
||||||
|
RLAPI void CameraRoll(Camera *camera, float angle);
|
||||||
|
|
||||||
|
RLAPI Matrix GetCameraViewMatrix(Camera *camera);
|
||||||
|
RLAPI Matrix GetCameraProjectionMatrix(Camera* camera, float aspect);
|
||||||
|
|
||||||
|
#endif // RAYMATH_H
|
||||||
@ -0,0 +1,35 @@
|
|||||||
|
#ifndef CAMERA_H
|
||||||
|
#define CAMERA_H
|
||||||
|
|
||||||
|
#import <stdio.h>
|
||||||
|
#import <Foundation/Foundation.h>
|
||||||
|
#import <raylib.h>
|
||||||
|
#import <yesmath.h>
|
||||||
|
#import "Player.h"
|
||||||
|
|
||||||
|
@class Player;
|
||||||
|
|
||||||
|
@interface GameCamera : NSObject {
|
||||||
|
Camera3D camera;
|
||||||
|
int mode;
|
||||||
|
Player *attachedPlayer;
|
||||||
|
|
||||||
|
Vector2 crosshair;
|
||||||
|
Color crosshairColor;
|
||||||
|
float crosshairSize;
|
||||||
|
}
|
||||||
|
@property Camera3D camera;
|
||||||
|
@property int mode;
|
||||||
|
|
||||||
|
-(id) init;
|
||||||
|
-(void) update;
|
||||||
|
-(void) attach: (Player *) player;
|
||||||
|
-(void) showPos;
|
||||||
|
-(void) showTarget;
|
||||||
|
-(void) drawCrosshair;
|
||||||
|
-(void) drawWeapon;
|
||||||
|
-(bool) raycast;
|
||||||
|
-(Camera3D *) addressOfCamera;
|
||||||
|
@end
|
||||||
|
|
||||||
|
#endif
|
||||||
@ -0,0 +1,87 @@
|
|||||||
|
#import "Camera.h"
|
||||||
|
#import "properties.h"
|
||||||
|
|
||||||
|
@implementation GameCamera
|
||||||
|
@synthesize camera;
|
||||||
|
@synthesize mode;
|
||||||
|
|
||||||
|
-(id) init {
|
||||||
|
if ((self = [super init])) {
|
||||||
|
camera.position = (Vector3){0.0f, 2.0f, 0.0f};
|
||||||
|
camera.target = (Vector3){0.0f, 0.0f, 1.0f};
|
||||||
|
camera.up = (Vector3){0.0f, 1.0f, 0.0f};
|
||||||
|
camera.fovy = 90.0f;
|
||||||
|
camera.projection = CAMERA_PERSPECTIVE;
|
||||||
|
mode = CAMERA_CUSTOM;
|
||||||
|
|
||||||
|
crosshair = (Vector2){default_properties.width/2, default_properties.height/2};
|
||||||
|
crosshairColor = WHITE;
|
||||||
|
crosshairSize = 2.0f;
|
||||||
|
}
|
||||||
|
|
||||||
|
return self;
|
||||||
|
}
|
||||||
|
|
||||||
|
-(void) update {
|
||||||
|
Vector2 mouseDelta = GetMouseDelta();
|
||||||
|
|
||||||
|
CameraYaw(&camera, -mouseDelta.x * 0.008, false);
|
||||||
|
CameraPitch(&camera, -mouseDelta.y * 0.008, true, false, false);
|
||||||
|
|
||||||
|
camera.position = [attachedPlayer pos];
|
||||||
|
}
|
||||||
|
|
||||||
|
-(void) attach: (Player *) player {
|
||||||
|
attachedPlayer = player;
|
||||||
|
[attachedPlayer setAttachedCamera: self];
|
||||||
|
}
|
||||||
|
|
||||||
|
-(void) showPos {
|
||||||
|
char buffer[50];
|
||||||
|
sprintf(buffer, "pos: (%.02f, %.02f, %.02f)", camera.position.x, camera.position.y, camera.position.z);
|
||||||
|
DrawText(buffer, 0, 0, 20, BLACK);
|
||||||
|
}
|
||||||
|
|
||||||
|
-(void) showTarget {
|
||||||
|
char buffer[50];
|
||||||
|
sprintf(buffer, "tgt: (%.02f, %.02f, %.02f)", camera.target.x, camera.target.y, camera.target.z);
|
||||||
|
DrawText(buffer, 0, 30, 20, BLACK);
|
||||||
|
}
|
||||||
|
|
||||||
|
-(void) drawCrosshair {
|
||||||
|
DrawCircleV(crosshair, crosshairSize, crosshairColor);
|
||||||
|
}
|
||||||
|
|
||||||
|
-(void) drawWeapon {
|
||||||
|
if (attachedPlayer != nil) {
|
||||||
|
Texture2D texture = [attachedPlayer weapon];
|
||||||
|
DrawTexture(texture, 0.0f, 0.0f, WHITE);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
-(bool) raycast {
|
||||||
|
BoundingBox bbox = {(Vector3){-1.0f, -1.0f, -1.0f}, (Vector3){2.0f, 2.0f, 2.0f}};
|
||||||
|
|
||||||
|
//i called them both raycast to maximize confusion
|
||||||
|
if ( ObjectiveCBugFixRaycast(camera, bbox).hit ) {
|
||||||
|
crosshairColor = RED;
|
||||||
|
} else {
|
||||||
|
crosshairColor = WHITE;
|
||||||
|
}
|
||||||
|
|
||||||
|
#define DEBUG
|
||||||
|
|
||||||
|
#ifdef DEBUG
|
||||||
|
BeginMode3D(camera);
|
||||||
|
DrawBoundingBox(bbox, BLUE);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
EndMode3D();
|
||||||
|
return ObjectiveCBugFixRaycast(camera, bbox).hit;
|
||||||
|
}
|
||||||
|
|
||||||
|
-(Camera3D *) addressOfCamera {
|
||||||
|
return &camera;
|
||||||
|
}
|
||||||
|
|
||||||
|
@end
|
||||||
@ -0,0 +1,10 @@
|
|||||||
|
#ifndef CHARACTER_H
|
||||||
|
#define CHARACTER_H
|
||||||
|
|
||||||
|
#import <raylib.h>
|
||||||
|
#import <yesmath.h>
|
||||||
|
|
||||||
|
@interface Character : NSObject {
|
||||||
|
BoundingBox bbox;
|
||||||
|
}
|
||||||
|
@end
|
||||||
@ -0,0 +1,22 @@
|
|||||||
|
#ifndef ENEMY_H
|
||||||
|
#define ENEMY_H
|
||||||
|
|
||||||
|
#import <Foundation/Foundation.h>
|
||||||
|
#import <raylib.h>
|
||||||
|
#import <yesmath.h>
|
||||||
|
|
||||||
|
//just a simple enemy that follows the player for now
|
||||||
|
@interface Enemy : NSObject {
|
||||||
|
Texture2D texture;
|
||||||
|
Vector3 pos;
|
||||||
|
BoundingBox bbox;
|
||||||
|
}
|
||||||
|
|
||||||
|
-(id) init;
|
||||||
|
//-(void) Attack;
|
||||||
|
//-(void) Moan;
|
||||||
|
-(void) Render: (Camera3D) camera;
|
||||||
|
|
||||||
|
@end
|
||||||
|
|
||||||
|
#endif
|
||||||
@ -0,0 +1,19 @@
|
|||||||
|
#import "Enemy.h"
|
||||||
|
|
||||||
|
@implementation Enemy
|
||||||
|
|
||||||
|
-(id) init {
|
||||||
|
if ( (self = [super init]) ) {
|
||||||
|
Image image = LoadImage("star.png");
|
||||||
|
texture = LoadTextureFromImage(image);
|
||||||
|
UnloadImage(image);
|
||||||
|
}
|
||||||
|
|
||||||
|
return self;
|
||||||
|
}
|
||||||
|
|
||||||
|
-(void) Render: (Camera3D) camera {
|
||||||
|
DrawBillboard(camera, texture, (Vector3){0.0f, 0.0f, 0.0f}, 2.0f, WHITE);
|
||||||
|
}
|
||||||
|
|
||||||
|
@end
|
||||||
@ -0,0 +1,15 @@
|
|||||||
|
#ifndef INPUTHANDLER_H
|
||||||
|
#define INPUTHANDLER_H
|
||||||
|
|
||||||
|
#import <raylib.h>
|
||||||
|
#import "Player.h"
|
||||||
|
|
||||||
|
@interface InputHandler : NSObject {
|
||||||
|
Player *controllable;
|
||||||
|
}
|
||||||
|
@property (assign) Player *controllable;
|
||||||
|
|
||||||
|
-(void) handleInput;
|
||||||
|
@end
|
||||||
|
|
||||||
|
#endif
|
||||||
@ -0,0 +1,29 @@
|
|||||||
|
#import "InputHandler.h"
|
||||||
|
|
||||||
|
@implementation InputHandler
|
||||||
|
|
||||||
|
@synthesize controllable;
|
||||||
|
|
||||||
|
-(void) handleInput {
|
||||||
|
static unsigned int set;
|
||||||
|
|
||||||
|
if (set == 0) {
|
||||||
|
set = IsKeyDown(KEY_W);
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( set - IsKeyDown(KEY_W) ) {
|
||||||
|
[controllable moveForward];
|
||||||
|
} else if ( set - IsKeyDown(KEY_S) ) {
|
||||||
|
[controllable moveBack];
|
||||||
|
} else if ( set - IsKeyDown(KEY_A) ) {
|
||||||
|
[controllable moveLeft];
|
||||||
|
} else if ( set - IsKeyDown(KEY_D) ) {
|
||||||
|
[controllable moveRight];
|
||||||
|
}
|
||||||
|
|
||||||
|
if (IsMouseButtonPressed(MOUSE_BUTTON_LEFT)) {
|
||||||
|
[controllable attack];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@end
|
||||||
@ -0,0 +1,33 @@
|
|||||||
|
#ifndef PLAYER_H
|
||||||
|
#define PLAYER_H
|
||||||
|
|
||||||
|
#import <Foundation/Foundation.h>
|
||||||
|
#import <raylib.h>
|
||||||
|
#import <yesmath.h>
|
||||||
|
#import "Camera.h"
|
||||||
|
#import "SoundPlayer.h"
|
||||||
|
|
||||||
|
@class GameCamera;
|
||||||
|
|
||||||
|
@interface Player : NSObject {
|
||||||
|
BoundingBox bbox;
|
||||||
|
Vector3 pos;
|
||||||
|
GameCamera *attachedCamera;
|
||||||
|
SoundPlayer *soundPlayer;
|
||||||
|
Texture2D weapon;
|
||||||
|
}
|
||||||
|
@property Vector3 pos;
|
||||||
|
@property (assign) GameCamera *attachedCamera;
|
||||||
|
@property Texture2D weapon;
|
||||||
|
@property (assign) SoundPlayer *soundPlayer;
|
||||||
|
|
||||||
|
-(id) init;
|
||||||
|
-(void) showPos;
|
||||||
|
-(void) attack;
|
||||||
|
-(void) moveForward;
|
||||||
|
-(void) moveBack;
|
||||||
|
-(void) moveLeft;
|
||||||
|
-(void) moveRight;
|
||||||
|
@end
|
||||||
|
|
||||||
|
#endif
|
||||||
@ -0,0 +1,67 @@
|
|||||||
|
#import "Player.h"
|
||||||
|
|
||||||
|
@implementation Player
|
||||||
|
@synthesize pos;
|
||||||
|
@synthesize attachedCamera;
|
||||||
|
@synthesize soundPlayer;
|
||||||
|
@synthesize weapon;
|
||||||
|
|
||||||
|
-(id) init {
|
||||||
|
if ( (self = [super init] ) ) {
|
||||||
|
pos = (Vector3){0.0f, 2.0f, 0.0f};
|
||||||
|
}
|
||||||
|
|
||||||
|
return self;
|
||||||
|
}
|
||||||
|
|
||||||
|
-(void) showPos {
|
||||||
|
char buffer[50];
|
||||||
|
sprintf(buffer, "pos: (%.02f, %.02f, %.02f)", pos.x, pos.y, pos.z);
|
||||||
|
DrawText(buffer, 0, 50, 20, BLACK);
|
||||||
|
}
|
||||||
|
|
||||||
|
-(void) attack {
|
||||||
|
if ( [attachedCamera raycast] ) {
|
||||||
|
|
||||||
|
//how to get the object it hit?
|
||||||
|
[soundPlayer play];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
-(void) moveForward {
|
||||||
|
Camera *cam = [attachedCamera addressOfCamera];
|
||||||
|
Vector3 forward = GetCameraForward( cam );
|
||||||
|
float distance = 0.1;
|
||||||
|
|
||||||
|
forward = Vector3Scale(forward, distance);
|
||||||
|
|
||||||
|
pos = Vector3Add(pos, forward);
|
||||||
|
cam->target = Vector3Add(cam->target, forward);
|
||||||
|
}
|
||||||
|
|
||||||
|
-(void) moveBack {
|
||||||
|
Camera *cam = [attachedCamera addressOfCamera];
|
||||||
|
Vector3 forward = GetCameraForward( cam );
|
||||||
|
float distance = 0.1;
|
||||||
|
forward = Vector3Scale(forward, distance);
|
||||||
|
pos = Vector3Subtract(pos, forward);
|
||||||
|
cam->target = Vector3Subtract(cam->target, forward);
|
||||||
|
}
|
||||||
|
|
||||||
|
-(void) moveLeft {
|
||||||
|
Camera *cam = [attachedCamera addressOfCamera];
|
||||||
|
Vector3 right = GetCameraRight( cam );
|
||||||
|
right = Vector3Scale(right, 0.1);
|
||||||
|
pos = Vector3Subtract(pos, right);
|
||||||
|
cam->target = Vector3Subtract(cam->target, right);
|
||||||
|
}
|
||||||
|
|
||||||
|
-(void) moveRight {
|
||||||
|
Camera *cam = [attachedCamera addressOfCamera];
|
||||||
|
Vector3 right = GetCameraRight( cam );
|
||||||
|
right = Vector3Scale(right, 0.1);
|
||||||
|
pos = Vector3Add(pos, right);
|
||||||
|
cam->target = Vector3Add(cam->target, right);
|
||||||
|
}
|
||||||
|
|
||||||
|
@end
|
||||||
@ -0,0 +1,26 @@
|
|||||||
|
#ifndef SOUNDPLAYER_H
|
||||||
|
#define SOUNDPLAYER_H
|
||||||
|
|
||||||
|
#import <Foundation/Foundation.h>
|
||||||
|
#include <raylib.h>
|
||||||
|
|
||||||
|
/*
|
||||||
|
different things should have different sounds
|
||||||
|
|
||||||
|
the soundplayer needs a way to load all and only
|
||||||
|
the sounds it will need to play
|
||||||
|
|
||||||
|
should every object that plays a sound be a soundplayer?
|
||||||
|
or should there be one soundplayer that plays all sounds
|
||||||
|
*/
|
||||||
|
|
||||||
|
@interface SoundPlayer : NSObject {
|
||||||
|
Sound wav;
|
||||||
|
}
|
||||||
|
|
||||||
|
-(id) init;
|
||||||
|
-(void) dealloc;
|
||||||
|
-(void) play;
|
||||||
|
|
||||||
|
@end
|
||||||
|
#endif
|
||||||
@ -0,0 +1,23 @@
|
|||||||
|
#import "SoundPlayer.h"
|
||||||
|
|
||||||
|
@implementation SoundPlayer
|
||||||
|
|
||||||
|
-(id) init {
|
||||||
|
if ( (self = [super init] ) ) {
|
||||||
|
InitAudioDevice();
|
||||||
|
wav = LoadSound("gun-gunshot-02.wav");
|
||||||
|
}
|
||||||
|
|
||||||
|
return self;
|
||||||
|
}
|
||||||
|
|
||||||
|
-(void) dealloc {
|
||||||
|
UnloadSound(wav);
|
||||||
|
CloseAudioDevice();
|
||||||
|
[super dealloc];
|
||||||
|
}
|
||||||
|
|
||||||
|
-(void) play {
|
||||||
|
PlaySound(wav);
|
||||||
|
}
|
||||||
|
@end
|
||||||
@ -0,0 +1,68 @@
|
|||||||
|
#import <Foundation/Foundation.h>
|
||||||
|
#include <raylib.h>
|
||||||
|
|
||||||
|
#include "Enemy.h"
|
||||||
|
#include "Camera.h"
|
||||||
|
#include "SoundPlayer.h"
|
||||||
|
#include "InputHandler.h"
|
||||||
|
#include "properties.h"
|
||||||
|
|
||||||
|
const int winWidth = 800;
|
||||||
|
const int winHeight = 600;
|
||||||
|
|
||||||
|
int main(int argc, const char *argv[]) {
|
||||||
|
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
|
||||||
|
|
||||||
|
//insert custom properties loader here
|
||||||
|
|
||||||
|
InitWindow(default_properties.width, default_properties.height, "Game :3");
|
||||||
|
SetTargetFPS(60);
|
||||||
|
DisableCursor();
|
||||||
|
|
||||||
|
GameCamera *camera = [[GameCamera alloc] init];
|
||||||
|
Player *player = [[Player alloc] init];
|
||||||
|
SoundPlayer *sp = [[SoundPlayer alloc] init];
|
||||||
|
Enemy *enemy = [[Enemy alloc] init];
|
||||||
|
InputHandler *input = [[InputHandler alloc] init];
|
||||||
|
input.controllable = player;
|
||||||
|
player.soundPlayer = sp;
|
||||||
|
|
||||||
|
[camera attach: player];
|
||||||
|
|
||||||
|
Image image = LoadImage("gun.png");
|
||||||
|
Texture2D tex = LoadTextureFromImage(image);
|
||||||
|
[player setWeapon: tex];
|
||||||
|
|
||||||
|
|
||||||
|
while (!WindowShouldClose()) {
|
||||||
|
[camera update];
|
||||||
|
|
||||||
|
//hard coded input handler
|
||||||
|
[input handleInput];
|
||||||
|
|
||||||
|
BeginDrawing();
|
||||||
|
ClearBackground(RAYWHITE);
|
||||||
|
|
||||||
|
BeginMode3D([camera camera]);
|
||||||
|
DrawPlane((Vector3){ 0.0f, 0.0f, 0.0f }, (Vector2){ 32.0f, 32.0f }, LIGHTGRAY);
|
||||||
|
DrawCube((Vector3){ -16.0f, 2.5f, 0.0f }, 1.0f, 5.0f, 32.0f, BLUE); // Draw a blue wall
|
||||||
|
DrawCube((Vector3){ 16.0f, 2.5f, 0.0f }, 1.0f, 5.0f, 32.0f, LIME); // Draw a green wall
|
||||||
|
DrawCube((Vector3){ 0.0f, 2.5f, 16.0f }, 32.0f, 5.0f, 1.0f, GOLD);
|
||||||
|
DrawCube((Vector3){ 0.0f, 2.5f, -16.0f }, 32.0f, 5.0f, 1.0f, RED);
|
||||||
|
EndMode3D();
|
||||||
|
|
||||||
|
[camera showPos];
|
||||||
|
[camera showTarget];
|
||||||
|
[player showPos];
|
||||||
|
[camera drawCrosshair];
|
||||||
|
[camera raycast];
|
||||||
|
[enemy Render: [camera camera]];
|
||||||
|
DrawTexture(tex, default_properties.width - tex.width, default_properties.height - tex.height, WHITE);
|
||||||
|
|
||||||
|
EndDrawing();
|
||||||
|
}
|
||||||
|
|
||||||
|
CloseWindow();
|
||||||
|
[pool drain];
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
@ -0,0 +1,6 @@
|
|||||||
|
//game specific headers
|
||||||
|
#include "Player.h"
|
||||||
|
#include "Camera.h"
|
||||||
|
#include "SoundPlayer.h"
|
||||||
|
#include "Enemy.h"
|
||||||
|
|
||||||
@ -0,0 +1,14 @@
|
|||||||
|
#ifndef PROPERTIES_H
|
||||||
|
#define PROPERTIES_H
|
||||||
|
|
||||||
|
//properties of window and stuff
|
||||||
|
|
||||||
|
static struct window_properties {
|
||||||
|
int width, height;
|
||||||
|
} default_properties = {800, 600};
|
||||||
|
typedef struct window_properties window_properties;
|
||||||
|
|
||||||
|
//insert global instance of custom properties here
|
||||||
|
//if no custom properties, global instance is set to default
|
||||||
|
|
||||||
|
#endif
|
||||||
@ -0,0 +1,9 @@
|
|||||||
|
SHELL=/bin/sh
|
||||||
|
|
||||||
|
#i turned raymath into a library to avoid redefinition errors
|
||||||
|
|
||||||
|
libyesmath.a: raymath.o
|
||||||
|
ar rcs libyesmath.a raymath.o
|
||||||
|
|
||||||
|
raymath.o: raymath.c
|
||||||
|
gcc -DYESMATH -c raymath.c
|
||||||
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,585 @@
|
|||||||
|
/**********************************************************************************************
|
||||||
|
*
|
||||||
|
* raymath v1.5 - Math functions to work with Vector2, Vector3, Matrix and Quaternions
|
||||||
|
*
|
||||||
|
* CONFIGURATION:
|
||||||
|
*
|
||||||
|
* #define RAYMATH_IMPLEMENTATION
|
||||||
|
* Generates the implementation of the library into the included file.
|
||||||
|
* If not defined, the library is in header only mode and can be included in other headers
|
||||||
|
* or source files without problems. But only ONE file should hold the implementation.
|
||||||
|
*
|
||||||
|
* #define RAYMATH_STATIC_INLINE
|
||||||
|
* Define static inline functions code, so #include header suffices for use.
|
||||||
|
* This may use up lots of memory.
|
||||||
|
*
|
||||||
|
* CONVENTIONS:
|
||||||
|
*
|
||||||
|
* - Functions are always self-contained, no function use another raymath function inside,
|
||||||
|
* required code is directly re-implemented inside
|
||||||
|
* - Functions input parameters are always received by value (2 unavoidable exceptions);
|
||||||
|
* - Functions use always a "result" variable for return
|
||||||
|
* - Functions are always defined inline
|
||||||
|
* - Angles are always in radians (DEG2RAD/RAD2DEG macros provided for convenience);
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* LICENSE: zlib/libpng
|
||||||
|
*
|
||||||
|
* Copyright (c); 2015-2023 Ramon Santamaria (@raysan5);
|
||||||
|
*
|
||||||
|
* This software is provided "as-is", without any express or implied warranty. In no event
|
||||||
|
* will the authors be held liable for any damages arising from the use of this software.
|
||||||
|
*
|
||||||
|
* Permission is granted to anyone to use this software for any purpose, including commercial
|
||||||
|
* applications, and to alter it and redistribute it freely, subject to the following restrictions:
|
||||||
|
*
|
||||||
|
* 1. The origin of this software must not be misrepresented; you must not claim that you
|
||||||
|
* wrote the original software. If you use this software in a product, an acknowledgment
|
||||||
|
* in the product documentation would be appreciated but is not required.
|
||||||
|
*
|
||||||
|
* 2. Altered source versions must be plainly marked as such, and must not be misrepresented
|
||||||
|
* as being the original software.
|
||||||
|
*
|
||||||
|
* 3. This notice may not be removed or altered from any source distribution.
|
||||||
|
*
|
||||||
|
**********************************************************************************************/
|
||||||
|
|
||||||
|
#ifndef RAYMATH_H
|
||||||
|
#define RAYMATH_H
|
||||||
|
|
||||||
|
#if defined(RAYMATH_IMPLEMENTATION) && defined(RAYMATH_STATIC_INLINE)
|
||||||
|
#error "Specifying both RAYMATH_IMPLEMENTATION and RAYMATH_STATIC_INLINE is contradictory"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// Function specifiers definition
|
||||||
|
#if defined(RAYMATH_IMPLEMENTATION)
|
||||||
|
#if defined(_WIN32); && defined(BUILD_LIBTYPE_SHARED);
|
||||||
|
#define RMAPI __declspec(dllexport); extern inline // We are building raylib as a Win32 shared library (.dll);.
|
||||||
|
#elif defined(_WIN32); && defined(USE_LIBTYPE_SHARED);
|
||||||
|
#define RMAPI __declspec(dllimport); // We are using raylib as a Win32 shared library (.dll);
|
||||||
|
#else
|
||||||
|
#define RMAPI extern inline // Provide external definition
|
||||||
|
#endif
|
||||||
|
#elif defined(RAYMATH_STATIC_INLINE)
|
||||||
|
#define RMAPI static inline // Functions may be inlined, no external out-of-line definition
|
||||||
|
#else
|
||||||
|
#if defined(__TINYC__)
|
||||||
|
#define RMAPI static inline // plain inline not supported by tinycc (See issue #435);
|
||||||
|
#else
|
||||||
|
#define RMAPI inline // Functions may be inlined or external definition used
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------------
|
||||||
|
// Defines and Macros
|
||||||
|
//----------------------------------------------------------------------------------
|
||||||
|
#ifndef PI
|
||||||
|
#define PI 3.14159265358979323846f
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef EPSILON
|
||||||
|
#define EPSILON 0.000001f
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef DEG2RAD
|
||||||
|
#define DEG2RAD (PI/180.0f)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef RAD2DEG
|
||||||
|
#define RAD2DEG (180.0f/PI)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// Get float vector for Matrix
|
||||||
|
#ifndef MatrixToFloat
|
||||||
|
#define MatrixToFloat(mat) (MatrixToFloatV(mat).v)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// Get float vector for Vector3
|
||||||
|
#ifndef Vector3ToFloat
|
||||||
|
#define Vector3ToFloat(vec) (Vector3ToFloatV(vec).v)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------------
|
||||||
|
// Types and Structures Definition
|
||||||
|
//----------------------------------------------------------------------------------
|
||||||
|
#if !defined(RL_VECTOR2_TYPE)
|
||||||
|
// Vector2 type
|
||||||
|
typedef struct Vector2 {
|
||||||
|
float x;
|
||||||
|
float y;
|
||||||
|
} Vector2;
|
||||||
|
#define RL_VECTOR2_TYPE
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if !defined(RL_VECTOR3_TYPE)
|
||||||
|
// Vector3 type
|
||||||
|
typedef struct Vector3 {
|
||||||
|
float x;
|
||||||
|
float y;
|
||||||
|
float z;
|
||||||
|
} Vector3;
|
||||||
|
#define RL_VECTOR3_TYPE
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if !defined(RL_VECTOR4_TYPE)
|
||||||
|
// Vector4 type
|
||||||
|
typedef struct Vector4 {
|
||||||
|
float x;
|
||||||
|
float y;
|
||||||
|
float z;
|
||||||
|
float w;
|
||||||
|
} Vector4;
|
||||||
|
#define RL_VECTOR4_TYPE
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if !defined(RL_QUATERNION_TYPE)
|
||||||
|
// Quaternion type
|
||||||
|
typedef Vector4 Quaternion;
|
||||||
|
#define RL_QUATERNION_TYPE
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if !defined(RL_MATRIX_TYPE)
|
||||||
|
// Matrix type (OpenGL style 4x4 - right handed, column major);
|
||||||
|
typedef struct Matrix {
|
||||||
|
float m0, m4, m8, m12; // Matrix first row (4 components);
|
||||||
|
float m1, m5, m9, m13; // Matrix second row (4 components);
|
||||||
|
float m2, m6, m10, m14; // Matrix third row (4 components);
|
||||||
|
float m3, m7, m11, m15; // Matrix fourth row (4 components);
|
||||||
|
} Matrix;
|
||||||
|
#define RL_MATRIX_TYPE
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// NOTE: Helper types to be used instead of array return types for *ToFloat functions
|
||||||
|
typedef struct float3 {
|
||||||
|
float v[3];
|
||||||
|
} float3;
|
||||||
|
|
||||||
|
typedef struct float16 {
|
||||||
|
float v[16];
|
||||||
|
} float16;
|
||||||
|
|
||||||
|
#include <math.h> // Required for: sinf();, cosf();, tan();, atan2f();, sqrtf();, floor();, fminf();, fmaxf();, fabs();
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------------
|
||||||
|
// Module Functions Definition - Utils math
|
||||||
|
//----------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
// Clamp float value
|
||||||
|
RMAPI float Clamp(float value, float min, float max);;
|
||||||
|
|
||||||
|
// Calculate linear interpolation between two floats
|
||||||
|
RMAPI float Lerp(float start, float end, float amount);;
|
||||||
|
|
||||||
|
// Normalize input value within input range
|
||||||
|
RMAPI float Normalize(float value, float start, float end);;
|
||||||
|
|
||||||
|
// Remap input value within input range to output range
|
||||||
|
RMAPI float Remap(float value, float inputStart, float inputEnd, float outputStart, float outputEnd);;
|
||||||
|
|
||||||
|
// Wrap input value from min to max
|
||||||
|
RMAPI float Wrap(float value, float min, float max);;
|
||||||
|
|
||||||
|
// Check whether two given floats are almost equal
|
||||||
|
RMAPI int FloatEquals(float x, float y);;
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------------
|
||||||
|
// Module Functions Definition - Vector2 math
|
||||||
|
//----------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
// Vector with components value 0.0f
|
||||||
|
RMAPI Vector2 Vector2Zero(void);;
|
||||||
|
|
||||||
|
// Vector with components value 1.0f
|
||||||
|
RMAPI Vector2 Vector2One(void);;
|
||||||
|
|
||||||
|
// Add two vectors (v1 + v2);
|
||||||
|
RMAPI Vector2 Vector2Add(Vector2 v1, Vector2 v2);;
|
||||||
|
|
||||||
|
// Add vector and float value
|
||||||
|
RMAPI Vector2 Vector2AddValue(Vector2 v, float add);
|
||||||
|
|
||||||
|
// Subtract two vectors (v1 - v2);
|
||||||
|
RMAPI Vector2 Vector2Subtract(Vector2 v1, Vector2 v2);
|
||||||
|
|
||||||
|
// Subtract vector by float value
|
||||||
|
RMAPI Vector2 Vector2SubtractValue(Vector2 v, float sub);
|
||||||
|
|
||||||
|
// Calculate vector length
|
||||||
|
RMAPI float Vector2Length(Vector2 v);
|
||||||
|
|
||||||
|
// Calculate vector square length
|
||||||
|
RMAPI float Vector2LengthSqr(Vector2 v);
|
||||||
|
|
||||||
|
// Calculate two vectors dot product
|
||||||
|
RMAPI float Vector2DotProduct(Vector2 v1, Vector2 v2);
|
||||||
|
|
||||||
|
// Calculate distance between two vectors
|
||||||
|
RMAPI float Vector2Distance(Vector2 v1, Vector2 v2);
|
||||||
|
|
||||||
|
// Calculate square distance between two vectors
|
||||||
|
RMAPI float Vector2DistanceSqr(Vector2 v1, Vector2 v2);
|
||||||
|
|
||||||
|
// Calculate angle between two vectors
|
||||||
|
// NOTE: Angle is calculated from origin point (0, 0);
|
||||||
|
RMAPI float Vector2Angle(Vector2 v1, Vector2 v2);
|
||||||
|
|
||||||
|
// Calculate angle defined by a two vectors line
|
||||||
|
// NOTE: Parameters need to be normalized
|
||||||
|
// Current implementation should be aligned with glm::angle
|
||||||
|
RMAPI float Vector2LineAngle(Vector2 start, Vector2 end);
|
||||||
|
|
||||||
|
// Scale vector (multiply by value);
|
||||||
|
RMAPI Vector2 Vector2Scale(Vector2 v, float scale);
|
||||||
|
|
||||||
|
// Multiply vector by vector
|
||||||
|
RMAPI Vector2 Vector2Multiply(Vector2 v1, Vector2 v2);
|
||||||
|
|
||||||
|
// Negate vector
|
||||||
|
RMAPI Vector2 Vector2Negate(Vector2 v);
|
||||||
|
// Divide vector by vector
|
||||||
|
RMAPI Vector2 Vector2Divide(Vector2 v1, Vector2 v2);
|
||||||
|
// Normalize provided vector
|
||||||
|
RMAPI Vector2 Vector2Normalize(Vector2 v);
|
||||||
|
|
||||||
|
// Transforms a Vector2 by a given Matrix
|
||||||
|
RMAPI Vector2 Vector2Transform(Vector2 v, Matrix mat);
|
||||||
|
|
||||||
|
// Calculate linear interpolation between two vectors
|
||||||
|
RMAPI Vector2 Vector2Lerp(Vector2 v1, Vector2 v2, float amount);
|
||||||
|
|
||||||
|
// Calculate reflected vector to normal
|
||||||
|
RMAPI Vector2 Vector2Reflect(Vector2 v, Vector2 normal);
|
||||||
|
|
||||||
|
// Rotate vector by angle
|
||||||
|
RMAPI Vector2 Vector2Rotate(Vector2 v, float angle);
|
||||||
|
|
||||||
|
// Move Vector towards target
|
||||||
|
RMAPI Vector2 Vector2MoveTowards(Vector2 v, Vector2 target, float maxDistance);
|
||||||
|
|
||||||
|
// Invert the given vector
|
||||||
|
RMAPI Vector2 Vector2Invert(Vector2 v);
|
||||||
|
// Clamp the components of the vector between
|
||||||
|
// min and max values specified by the given vectors
|
||||||
|
RMAPI Vector2 Vector2Clamp(Vector2 v, Vector2 min, Vector2 max);
|
||||||
|
|
||||||
|
// Clamp the magnitude of the vector between two min and max values
|
||||||
|
RMAPI Vector2 Vector2ClampValue(Vector2 v, float min, float max);
|
||||||
|
|
||||||
|
// Check whether two given vectors are almost equal
|
||||||
|
RMAPI int Vector2Equals(Vector2 p, Vector2 q);
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------------
|
||||||
|
// Module Functions Definition - Vector3 math
|
||||||
|
//----------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
// Vector with components value 0.0f
|
||||||
|
RMAPI Vector3 Vector3Zero(void);
|
||||||
|
|
||||||
|
// Vector with components value 1.0f
|
||||||
|
RMAPI Vector3 Vector3One(void);
|
||||||
|
|
||||||
|
// Add two vectors
|
||||||
|
RMAPI Vector3 Vector3Add(Vector3 v1, Vector3 v2);
|
||||||
|
|
||||||
|
// Add vector and float value
|
||||||
|
RMAPI Vector3 Vector3AddValue(Vector3 v, float add);
|
||||||
|
|
||||||
|
// Subtract two vectors
|
||||||
|
RMAPI Vector3 Vector3Subtract(Vector3 v1, Vector3 v2);
|
||||||
|
|
||||||
|
// Subtract vector by float value
|
||||||
|
RMAPI Vector3 Vector3SubtractValue(Vector3 v, float sub);
|
||||||
|
|
||||||
|
// Multiply vector by scalar
|
||||||
|
RMAPI Vector3 Vector3Scale(Vector3 v, float scalar);
|
||||||
|
|
||||||
|
// Multiply vector by vector
|
||||||
|
RMAPI Vector3 Vector3Multiply(Vector3 v1, Vector3 v2);
|
||||||
|
|
||||||
|
// Calculate two vectors cross product
|
||||||
|
RMAPI Vector3 Vector3CrossProduct(Vector3 v1, Vector3 v2);
|
||||||
|
|
||||||
|
// Calculate one vector perpendicular vector
|
||||||
|
RMAPI Vector3 Vector3Perpendicular(Vector3 v);
|
||||||
|
|
||||||
|
// Calculate vector length
|
||||||
|
RMAPI float Vector3Length(const Vector3 v);
|
||||||
|
|
||||||
|
// Calculate vector square length
|
||||||
|
RMAPI float Vector3LengthSqr(const Vector3 v);
|
||||||
|
|
||||||
|
// Calculate two vectors dot product
|
||||||
|
RMAPI float Vector3DotProduct(Vector3 v1, Vector3 v2);
|
||||||
|
|
||||||
|
// Calculate distance between two vectors
|
||||||
|
RMAPI float Vector3Distance(Vector3 v1, Vector3 v2);
|
||||||
|
|
||||||
|
// Calculate square distance between two vectors
|
||||||
|
RMAPI float Vector3DistanceSqr(Vector3 v1, Vector3 v2);
|
||||||
|
|
||||||
|
// Calculate angle between two vectors
|
||||||
|
RMAPI float Vector3Angle(Vector3 v1, Vector3 v2);
|
||||||
|
|
||||||
|
// Negate provided vector (invert direction);
|
||||||
|
RMAPI Vector3 Vector3Negate(Vector3 v);
|
||||||
|
|
||||||
|
// Divide vector by vector
|
||||||
|
RMAPI Vector3 Vector3Divide(Vector3 v1, Vector3 v2);
|
||||||
|
|
||||||
|
// Normalize provided vector
|
||||||
|
RMAPI Vector3 Vector3Normalize(Vector3 v);
|
||||||
|
|
||||||
|
// Orthonormalize provided vectors
|
||||||
|
// Makes vectors normalized and orthogonal to each other
|
||||||
|
// Gram-Schmidt function implementation
|
||||||
|
RMAPI void Vector3OrthoNormalize(Vector3 *v1, Vector3 *v2);
|
||||||
|
|
||||||
|
// Transforms a Vector3 by a given Matrix
|
||||||
|
RMAPI Vector3 Vector3Transform(Vector3 v, Matrix mat);
|
||||||
|
|
||||||
|
// Transform a vector by quaternion rotation
|
||||||
|
RMAPI Vector3 Vector3RotateByQuaternion(Vector3 v, Quaternion q);
|
||||||
|
|
||||||
|
// Rotates a vector around an axis
|
||||||
|
RMAPI Vector3 Vector3RotateByAxisAngle(Vector3 v, Vector3 axis, float angle);
|
||||||
|
|
||||||
|
// Calculate linear interpolation between two vectors
|
||||||
|
RMAPI Vector3 Vector3Lerp(Vector3 v1, Vector3 v2, float amount);
|
||||||
|
|
||||||
|
// Calculate reflected vector to normal
|
||||||
|
RMAPI Vector3 Vector3Reflect(Vector3 v, Vector3 normal);
|
||||||
|
|
||||||
|
// Get min value for each pair of components
|
||||||
|
RMAPI Vector3 Vector3Min(Vector3 v1, Vector3 v2);
|
||||||
|
// Get max value for each pair of components
|
||||||
|
RMAPI Vector3 Vector3Max(Vector3 v1, Vector3 v2);
|
||||||
|
|
||||||
|
// Compute barycenter coordinates (u, v, w); for point p with respect to triangle (a, b, c);
|
||||||
|
// NOTE: Assumes P is on the plane of the triangle
|
||||||
|
RMAPI Vector3 Vector3Barycenter(Vector3 p, Vector3 a, Vector3 b, Vector3 c);
|
||||||
|
|
||||||
|
// Projects a Vector3 from screen space into object space
|
||||||
|
// NOTE: We are avoiding calling other raymath functions despite available
|
||||||
|
RMAPI Vector3 Vector3Unproject(Vector3 source, Matrix projection, Matrix view);
|
||||||
|
|
||||||
|
// Get Vector3 as float array
|
||||||
|
RMAPI float3 Vector3ToFloatV(Vector3 v);
|
||||||
|
|
||||||
|
// Invert the given vector
|
||||||
|
RMAPI Vector3 Vector3Invert(Vector3 v);
|
||||||
|
|
||||||
|
// Clamp the components of the vector between
|
||||||
|
// min and max values specified by the given vectors
|
||||||
|
RMAPI Vector3 Vector3Clamp(Vector3 v, Vector3 min, Vector3 max);
|
||||||
|
|
||||||
|
// Clamp the magnitude of the vector between two values
|
||||||
|
RMAPI Vector3 Vector3ClampValue(Vector3 v, float min, float max);
|
||||||
|
|
||||||
|
// Check whether two given vectors are almost equal
|
||||||
|
RMAPI int Vector3Equals(Vector3 p, Vector3 q);
|
||||||
|
|
||||||
|
// Compute the direction of a refracted ray where v specifies the
|
||||||
|
// normalized direction of the incoming ray, n specifies the
|
||||||
|
// normalized normal vector of the interface of two optical media,
|
||||||
|
// and r specifies the ratio of the refractive index of the medium
|
||||||
|
// from where the ray comes to the refractive index of the medium
|
||||||
|
// on the other side of the surface
|
||||||
|
RMAPI Vector3 Vector3Refract(Vector3 v, Vector3 n, float r);
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------------
|
||||||
|
// Module Functions Definition - Matrix math
|
||||||
|
//----------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
// Compute matrix determinant
|
||||||
|
RMAPI float MatrixDeterminant(Matrix mat);
|
||||||
|
|
||||||
|
// Get the trace of the matrix (sum of the values along the diagonal);
|
||||||
|
RMAPI float MatrixTrace(Matrix mat);
|
||||||
|
|
||||||
|
// Transposes provided matrix
|
||||||
|
RMAPI Matrix MatrixTranspose(Matrix mat);
|
||||||
|
|
||||||
|
// Invert provided matrix
|
||||||
|
RMAPI Matrix MatrixInvert(Matrix mat);
|
||||||
|
|
||||||
|
// Get identity matrix
|
||||||
|
RMAPI Matrix MatrixIdentity(void);
|
||||||
|
|
||||||
|
// Add two matrices
|
||||||
|
RMAPI Matrix MatrixAdd(Matrix left, Matrix right);
|
||||||
|
|
||||||
|
// Subtract two matrices (left - right);
|
||||||
|
RMAPI Matrix MatrixSubtract(Matrix left, Matrix right);
|
||||||
|
|
||||||
|
// Get two matrix multiplication
|
||||||
|
// NOTE: When multiplying matrices... the order matters!
|
||||||
|
RMAPI Matrix MatrixMultiply(Matrix left, Matrix right);
|
||||||
|
|
||||||
|
// Get translation matrix
|
||||||
|
RMAPI Matrix MatrixTranslate(float x, float y, float z);
|
||||||
|
|
||||||
|
// Create rotation matrix from axis and angle
|
||||||
|
// NOTE: Angle should be provided in radians
|
||||||
|
RMAPI Matrix MatrixRotate(Vector3 axis, float angle);
|
||||||
|
|
||||||
|
// Get x-rotation matrix
|
||||||
|
// NOTE: Angle must be provided in radians
|
||||||
|
RMAPI Matrix MatrixRotateX(float angle);
|
||||||
|
|
||||||
|
// Get y-rotation matrix
|
||||||
|
// NOTE: Angle must be provided in radians
|
||||||
|
RMAPI Matrix MatrixRotateY(float angle);
|
||||||
|
|
||||||
|
// Get z-rotation matrix
|
||||||
|
// NOTE: Angle must be provided in radians
|
||||||
|
RMAPI Matrix MatrixRotateZ(float angle);
|
||||||
|
|
||||||
|
|
||||||
|
// Get xyz-rotation matrix
|
||||||
|
// NOTE: Angle must be provided in radians
|
||||||
|
RMAPI Matrix MatrixRotateXYZ(Vector3 angle);
|
||||||
|
|
||||||
|
// Get zyx-rotation matrix
|
||||||
|
// NOTE: Angle must be provided in radians
|
||||||
|
RMAPI Matrix MatrixRotateZYX(Vector3 angle);
|
||||||
|
|
||||||
|
// Get scaling matrix
|
||||||
|
RMAPI Matrix MatrixScale(float x, float y, float z);
|
||||||
|
|
||||||
|
// Get perspective projection matrix
|
||||||
|
RMAPI Matrix MatrixFrustum(double left, double right, double bottom, double top, double near, double far);
|
||||||
|
|
||||||
|
// Get perspective projection matrix
|
||||||
|
// NOTE: Fovy angle must be provided in radians
|
||||||
|
RMAPI Matrix MatrixPerspective(double fovy, double aspect, double near, double far);
|
||||||
|
|
||||||
|
// Get orthographic projection matrix
|
||||||
|
RMAPI Matrix MatrixOrtho(double left, double right, double bottom, double top, double near, double far);
|
||||||
|
|
||||||
|
// Get camera look-at matrix (view matrix);
|
||||||
|
RMAPI Matrix MatrixLookAt(Vector3 eye, Vector3 target, Vector3 up);
|
||||||
|
|
||||||
|
// Get float array of matrix data
|
||||||
|
RMAPI float16 MatrixToFloatV(Matrix mat);
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------------
|
||||||
|
// Module Functions Definition - Quaternion math
|
||||||
|
//----------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
// Add two quaternions
|
||||||
|
RMAPI Quaternion QuaternionAdd(Quaternion q1, Quaternion q2);
|
||||||
|
|
||||||
|
// Add quaternion and float value
|
||||||
|
RMAPI Quaternion QuaternionAddValue(Quaternion q, float add);
|
||||||
|
|
||||||
|
// Subtract two quaternions
|
||||||
|
RMAPI Quaternion QuaternionSubtract(Quaternion q1, Quaternion q2);
|
||||||
|
|
||||||
|
// Subtract quaternion and float value
|
||||||
|
RMAPI Quaternion QuaternionSubtractValue(Quaternion q, float sub);
|
||||||
|
|
||||||
|
// Get identity quaternion
|
||||||
|
RMAPI Quaternion QuaternionIdentity(void);
|
||||||
|
|
||||||
|
// Computes the length of a quaternion
|
||||||
|
RMAPI float QuaternionLength(Quaternion q);
|
||||||
|
|
||||||
|
// Normalize provided quaternion
|
||||||
|
RMAPI Quaternion QuaternionNormalize(Quaternion q);
|
||||||
|
|
||||||
|
// Invert provided quaternion
|
||||||
|
RMAPI Quaternion QuaternionInvert(Quaternion q);
|
||||||
|
|
||||||
|
// Calculate two quaternion multiplication
|
||||||
|
RMAPI Quaternion QuaternionMultiply(Quaternion q1, Quaternion q2);
|
||||||
|
// Scale quaternion by float value
|
||||||
|
RMAPI Quaternion QuaternionScale(Quaternion q, float mul);
|
||||||
|
|
||||||
|
// Divide two quaternions
|
||||||
|
RMAPI Quaternion QuaternionDivide(Quaternion q1, Quaternion q2);
|
||||||
|
|
||||||
|
// Calculate linear interpolation between two quaternions
|
||||||
|
RMAPI Quaternion QuaternionLerp(Quaternion q1, Quaternion q2, float amount);
|
||||||
|
|
||||||
|
// Calculate slerp-optimized interpolation between two quaternions
|
||||||
|
RMAPI Quaternion QuaternionNlerp(Quaternion q1, Quaternion q2, float amount);
|
||||||
|
|
||||||
|
// Calculates spherical linear interpolation between two quaternions
|
||||||
|
RMAPI Quaternion QuaternionSlerp(Quaternion q1, Quaternion q2, float amount);
|
||||||
|
|
||||||
|
// Calculate quaternion based on the rotation from one vector to another
|
||||||
|
RMAPI Quaternion QuaternionFromVector3ToVector3(Vector3 from, Vector3 to);
|
||||||
|
|
||||||
|
// Get a quaternion for a given rotation matrix
|
||||||
|
RMAPI Quaternion QuaternionFromMatrix(Matrix mat);
|
||||||
|
|
||||||
|
// Get a matrix for a given quaternion
|
||||||
|
RMAPI Matrix QuaternionToMatrix(Quaternion q);
|
||||||
|
|
||||||
|
// Get rotation quaternion for an angle and axis
|
||||||
|
// NOTE: Angle must be provided in radians
|
||||||
|
RMAPI Quaternion QuaternionFromAxisAngle(Vector3 axis, float angle);
|
||||||
|
|
||||||
|
// Get the rotation angle and axis for a given quaternion
|
||||||
|
RMAPI void QuaternionToAxisAngle(Quaternion q, Vector3 *outAxis, float *outAngle);
|
||||||
|
// Get the quaternion equivalent to Euler angles
|
||||||
|
// NOTE: Rotation order is ZYX
|
||||||
|
RMAPI Quaternion QuaternionFromEuler(float pitch, float yaw, float roll);
|
||||||
|
|
||||||
|
// Get the Euler angles equivalent to quaternion (roll, pitch, yaw);
|
||||||
|
// NOTE: Angles are returned in a Vector3 struct in radians
|
||||||
|
RMAPI Vector3 QuaternionToEuler(Quaternion q);
|
||||||
|
|
||||||
|
// Transform a quaternion given a transformation matrix
|
||||||
|
RMAPI Quaternion QuaternionTransform(Quaternion q, Matrix mat);
|
||||||
|
|
||||||
|
// Check whether two given quaternions are almost equal
|
||||||
|
RMAPI int QuaternionEquals(Quaternion p, Quaternion q);
|
||||||
|
|
||||||
|
//only define these when building yesmath
|
||||||
|
#ifdef YESMATH
|
||||||
|
// Ray, ray for raycasting
|
||||||
|
typedef struct Ray {
|
||||||
|
Vector3 position; // Ray position (origin)
|
||||||
|
Vector3 direction; // Ray direction (normalized)
|
||||||
|
} Ray;
|
||||||
|
|
||||||
|
// RayCollision, ray hit information
|
||||||
|
typedef struct RayCollision {
|
||||||
|
bool hit; // Did the ray hit something?
|
||||||
|
float distance; // Distance to the nearest hit
|
||||||
|
Vector3 point; // Point of the nearest hit
|
||||||
|
Vector3 normal; // Surface normal of hit
|
||||||
|
} RayCollision;
|
||||||
|
|
||||||
|
// BoundingBox
|
||||||
|
typedef struct BoundingBox {
|
||||||
|
Vector3 min; // Minimum vertex box-corner
|
||||||
|
Vector3 max; // Maximum vertex box-corner
|
||||||
|
} BoundingBox;
|
||||||
|
|
||||||
|
// Camera type, defines a camera position/orientation in 3d space
|
||||||
|
typedef struct Camera3D {
|
||||||
|
Vector3 position; // Camera position
|
||||||
|
Vector3 target; // Camera target it looks-at
|
||||||
|
Vector3 up; // Camera up vector (rotation over its axis)
|
||||||
|
float fovy; // Camera field-of-view apperture in Y (degrees) in perspective, used as near plane width in orthographic
|
||||||
|
int projection; // Camera projection type: CAMERA_PERSPECTIVE or CAMERA_ORTHOGRAPHIC
|
||||||
|
} Camera3D;
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
//"fixes" a weird bug with calling GetRayCollisionBox inside a method
|
||||||
|
RayCollision ObjectiveCBugFixRaycast(Camera camera, BoundingBox bbox) {
|
||||||
|
Vector3 direction = Vector3Subtract(camera.target, camera.position);
|
||||||
|
direction = Vector3Normalize(direction);
|
||||||
|
RayCollision rc = GetRayCollisionBox((Ray){camera.position, direction}, bbox);
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
|
||||||
|
Vector3 MidpointBoundingBox(BoundingBox bbox) {
|
||||||
|
Vector3 a = Vector3Add(bbox.min, bbox.max);
|
||||||
|
return Vector3Divide(a, (Vector3){2.0f, 2.0f, 2.0f});
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif // RAYMATH_H
|
||||||
@ -0,0 +1,550 @@
|
|||||||
|
/*******************************************************************************************
|
||||||
|
*
|
||||||
|
* rcamera - Basic camera system with support for multiple camera modes
|
||||||
|
*
|
||||||
|
* CONFIGURATION:
|
||||||
|
* #define RCAMERA_IMPLEMENTATION
|
||||||
|
* Generates the implementation of the library into the included file.
|
||||||
|
* If not defined, the library is in header only mode and can be included in other headers
|
||||||
|
* or source files without problems. But only ONE file should hold the implementation.
|
||||||
|
*
|
||||||
|
* #define RCAMERA_STANDALONE
|
||||||
|
* If defined, the library can be used as standalone as a camera system but some
|
||||||
|
* functions must be redefined to manage inputs accordingly.
|
||||||
|
*
|
||||||
|
* CONTRIBUTORS:
|
||||||
|
* Ramon Santamaria: Supervision, review, update and maintenance
|
||||||
|
* Christoph Wagner: Complete redesign, using raymath (2022)
|
||||||
|
* Marc Palau: Initial implementation (2014)
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* LICENSE: zlib/libpng
|
||||||
|
*
|
||||||
|
* Copyright (c) 2022-2024 Christoph Wagner (@Crydsch) & Ramon Santamaria (@raysan5)
|
||||||
|
*
|
||||||
|
* This software is provided "as-is", without any express or implied warranty. In no event
|
||||||
|
* will the authors be held liable for any damages arising from the use of this software.
|
||||||
|
*
|
||||||
|
* Permission is granted to anyone to use this software for any purpose, including commercial
|
||||||
|
* applications, and to alter it and redistribute it freely, subject to the following restrictions:
|
||||||
|
*
|
||||||
|
* 1. The origin of this software must not be misrepresented; you must not claim that you
|
||||||
|
* wrote the original software. If you use this software in a product, an acknowledgment
|
||||||
|
* in the product documentation would be appreciated but is not required.
|
||||||
|
*
|
||||||
|
* 2. Altered source versions must be plainly marked as such, and must not be misrepresented
|
||||||
|
* as being the original software.
|
||||||
|
*
|
||||||
|
* 3. This notice may not be removed or altered from any source distribution.
|
||||||
|
*
|
||||||
|
**********************************************************************************************/
|
||||||
|
|
||||||
|
#ifndef RCAMERA_H
|
||||||
|
#define RCAMERA_H
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------------
|
||||||
|
// Defines and Macros
|
||||||
|
//----------------------------------------------------------------------------------
|
||||||
|
// Function specifiers definition
|
||||||
|
|
||||||
|
// Function specifiers in case library is build/used as a shared library (Windows)
|
||||||
|
// NOTE: Microsoft specifiers to tell compiler that symbols are imported/exported from a .dll
|
||||||
|
#if defined(_WIN32)
|
||||||
|
#if defined(BUILD_LIBTYPE_SHARED)
|
||||||
|
#if defined(__TINYC__)
|
||||||
|
#define __declspec(x) __attribute__((x))
|
||||||
|
#endif
|
||||||
|
#define RLAPI __declspec(dllexport) // We are building the library as a Win32 shared library (.dll)
|
||||||
|
#elif defined(USE_LIBTYPE_SHARED)
|
||||||
|
#define RLAPI __declspec(dllimport) // We are using the library as a Win32 shared library (.dll)
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef RLAPI
|
||||||
|
#define RLAPI // Functions defined as 'extern' by default (implicit specifiers)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(RCAMERA_STANDALONE)
|
||||||
|
#define CAMERA_CULL_DISTANCE_NEAR 0.01
|
||||||
|
#define CAMERA_CULL_DISTANCE_FAR 1000.0
|
||||||
|
#else
|
||||||
|
#define CAMERA_CULL_DISTANCE_NEAR RL_CULL_DISTANCE_NEAR
|
||||||
|
#define CAMERA_CULL_DISTANCE_FAR RL_CULL_DISTANCE_FAR
|
||||||
|
#endif
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------------
|
||||||
|
// Types and Structures Definition
|
||||||
|
// NOTE: Below types are required for standalone usage
|
||||||
|
//----------------------------------------------------------------------------------
|
||||||
|
#if defined(RCAMERA_STANDALONE)
|
||||||
|
// Vector2, 2 components
|
||||||
|
typedef struct Vector2 {
|
||||||
|
float x; // Vector x component
|
||||||
|
float y; // Vector y component
|
||||||
|
} Vector2;
|
||||||
|
|
||||||
|
// Vector3, 3 components
|
||||||
|
typedef struct Vector3 {
|
||||||
|
float x; // Vector x component
|
||||||
|
float y; // Vector y component
|
||||||
|
float z; // Vector z component
|
||||||
|
} Vector3;
|
||||||
|
|
||||||
|
// Matrix, 4x4 components, column major, OpenGL style, right-handed
|
||||||
|
typedef struct Matrix {
|
||||||
|
float m0, m4, m8, m12; // Matrix first row (4 components)
|
||||||
|
float m1, m5, m9, m13; // Matrix second row (4 components)
|
||||||
|
float m2, m6, m10, m14; // Matrix third row (4 components)
|
||||||
|
float m3, m7, m11, m15; // Matrix fourth row (4 components)
|
||||||
|
} Matrix;
|
||||||
|
|
||||||
|
// Camera type, defines a camera position/orientation in 3d space
|
||||||
|
typedef struct Camera3D {
|
||||||
|
Vector3 position; // Camera position
|
||||||
|
Vector3 target; // Camera target it looks-at
|
||||||
|
Vector3 up; // Camera up vector (rotation over its axis)
|
||||||
|
float fovy; // Camera field-of-view apperture in Y (degrees) in perspective, used as near plane width in orthographic
|
||||||
|
int projection; // Camera projection type: CAMERA_PERSPECTIVE or CAMERA_ORTHOGRAPHIC
|
||||||
|
} Camera3D;
|
||||||
|
|
||||||
|
typedef Camera3D Camera; // Camera type fallback, defaults to Camera3D
|
||||||
|
|
||||||
|
// Camera projection
|
||||||
|
typedef enum {
|
||||||
|
CAMERA_PERSPECTIVE = 0, // Perspective projection
|
||||||
|
CAMERA_ORTHOGRAPHIC // Orthographic projection
|
||||||
|
} CameraProjection;
|
||||||
|
|
||||||
|
// Camera system modes
|
||||||
|
typedef enum {
|
||||||
|
CAMERA_CUSTOM = 0, // Camera custom, controlled by user (UpdateCamera() does nothing)
|
||||||
|
CAMERA_FREE, // Camera free mode
|
||||||
|
CAMERA_ORBITAL, // Camera orbital, around target, zoom supported
|
||||||
|
CAMERA_FIRST_PERSON, // Camera first person
|
||||||
|
CAMERA_THIRD_PERSON // Camera third person
|
||||||
|
} CameraMode;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------------
|
||||||
|
// Global Variables Definition
|
||||||
|
//----------------------------------------------------------------------------------
|
||||||
|
//...
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------------
|
||||||
|
// Module Functions Declaration
|
||||||
|
//----------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
#if defined(__cplusplus)
|
||||||
|
extern "C" { // Prevents name mangling of functions
|
||||||
|
#endif
|
||||||
|
|
||||||
|
RLAPI Vector3 GetCameraForward(Camera *camera);
|
||||||
|
RLAPI Vector3 GetCameraUp(Camera *camera);
|
||||||
|
RLAPI Vector3 GetCameraRight(Camera *camera);
|
||||||
|
|
||||||
|
// Camera movement
|
||||||
|
RLAPI void CameraMoveForward(Camera *camera, float distance, bool moveInWorldPlane);
|
||||||
|
RLAPI void CameraMoveUp(Camera *camera, float distance);
|
||||||
|
RLAPI void CameraMoveRight(Camera *camera, float distance, bool moveInWorldPlane);
|
||||||
|
RLAPI void CameraMoveToTarget(Camera *camera, float delta);
|
||||||
|
|
||||||
|
// Camera rotation
|
||||||
|
RLAPI void CameraYaw(Camera *camera, float angle, bool rotateAroundTarget);
|
||||||
|
RLAPI void CameraPitch(Camera *camera, float angle, bool lockView, bool rotateAroundTarget, bool rotateUp);
|
||||||
|
RLAPI void CameraRoll(Camera *camera, float angle);
|
||||||
|
|
||||||
|
RLAPI Matrix GetCameraViewMatrix(Camera *camera);
|
||||||
|
RLAPI Matrix GetCameraProjectionMatrix(Camera* camera, float aspect);
|
||||||
|
|
||||||
|
#if defined(__cplusplus)
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif // RCAMERA_H
|
||||||
|
|
||||||
|
|
||||||
|
/***********************************************************************************
|
||||||
|
*
|
||||||
|
* CAMERA IMPLEMENTATION
|
||||||
|
*
|
||||||
|
************************************************************************************/
|
||||||
|
|
||||||
|
#if defined(RCAMERA_IMPLEMENTATION)
|
||||||
|
|
||||||
|
#include "raymath.h" // Required for vector maths:
|
||||||
|
// Vector3Add()
|
||||||
|
// Vector3Subtract()
|
||||||
|
// Vector3Scale()
|
||||||
|
// Vector3Normalize()
|
||||||
|
// Vector3Distance()
|
||||||
|
// Vector3CrossProduct()
|
||||||
|
// Vector3RotateByAxisAngle()
|
||||||
|
// Vector3Angle()
|
||||||
|
// Vector3Negate()
|
||||||
|
// MatrixLookAt()
|
||||||
|
// MatrixPerspective()
|
||||||
|
// MatrixOrtho()
|
||||||
|
// MatrixIdentity()
|
||||||
|
|
||||||
|
// raylib required functionality:
|
||||||
|
// GetMouseDelta()
|
||||||
|
// GetMouseWheelMove()
|
||||||
|
// IsKeyDown()
|
||||||
|
// IsKeyPressed()
|
||||||
|
// GetFrameTime()
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------------
|
||||||
|
// Defines and Macros
|
||||||
|
//----------------------------------------------------------------------------------
|
||||||
|
#define CAMERA_MOVE_SPEED 0.09f
|
||||||
|
#define CAMERA_ROTATION_SPEED 0.03f
|
||||||
|
#define CAMERA_PAN_SPEED 0.2f
|
||||||
|
|
||||||
|
// Camera mouse movement sensitivity
|
||||||
|
#define CAMERA_MOUSE_MOVE_SENSITIVITY 0.003f // TODO: it should be independant of framerate
|
||||||
|
|
||||||
|
// Camera orbital speed in CAMERA_ORBITAL mode
|
||||||
|
#define CAMERA_ORBITAL_SPEED 0.5f // Radians per second
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------------
|
||||||
|
// Types and Structures Definition
|
||||||
|
//----------------------------------------------------------------------------------
|
||||||
|
//...
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------------
|
||||||
|
// Global Variables Definition
|
||||||
|
//----------------------------------------------------------------------------------
|
||||||
|
//...
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------------
|
||||||
|
// Module specific Functions Declaration
|
||||||
|
//----------------------------------------------------------------------------------
|
||||||
|
//...
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------------
|
||||||
|
// Module Functions Definition
|
||||||
|
//----------------------------------------------------------------------------------
|
||||||
|
// Returns the cameras forward vector (normalized)
|
||||||
|
Vector3 GetCameraForward(Camera *camera)
|
||||||
|
{
|
||||||
|
return Vector3Normalize(Vector3Subtract(camera->target, camera->position));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Returns the cameras up vector (normalized)
|
||||||
|
// Note: The up vector might not be perpendicular to the forward vector
|
||||||
|
Vector3 GetCameraUp(Camera *camera)
|
||||||
|
{
|
||||||
|
return Vector3Normalize(camera->up);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Returns the cameras right vector (normalized)
|
||||||
|
Vector3 GetCameraRight(Camera *camera)
|
||||||
|
{
|
||||||
|
Vector3 forward = GetCameraForward(camera);
|
||||||
|
Vector3 up = GetCameraUp(camera);
|
||||||
|
|
||||||
|
return Vector3Normalize(Vector3CrossProduct(forward, up));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Moves the camera in its forward direction
|
||||||
|
void CameraMoveForward(Camera *camera, float distance, bool moveInWorldPlane)
|
||||||
|
{
|
||||||
|
Vector3 forward = GetCameraForward(camera);
|
||||||
|
|
||||||
|
if (moveInWorldPlane)
|
||||||
|
{
|
||||||
|
// Project vector onto world plane
|
||||||
|
forward.y = 0;
|
||||||
|
forward = Vector3Normalize(forward);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Scale by distance
|
||||||
|
forward = Vector3Scale(forward, distance);
|
||||||
|
|
||||||
|
// Move position and target
|
||||||
|
camera->position = Vector3Add(camera->position, forward);
|
||||||
|
camera->target = Vector3Add(camera->target, forward);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Moves the camera in its up direction
|
||||||
|
void CameraMoveUp(Camera *camera, float distance)
|
||||||
|
{
|
||||||
|
Vector3 up = GetCameraUp(camera);
|
||||||
|
|
||||||
|
// Scale by distance
|
||||||
|
up = Vector3Scale(up, distance);
|
||||||
|
|
||||||
|
// Move position and target
|
||||||
|
camera->position = Vector3Add(camera->position, up);
|
||||||
|
camera->target = Vector3Add(camera->target, up);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Moves the camera target in its current right direction
|
||||||
|
void CameraMoveRight(Camera *camera, float distance, bool moveInWorldPlane)
|
||||||
|
{
|
||||||
|
Vector3 right = GetCameraRight(camera);
|
||||||
|
|
||||||
|
if (moveInWorldPlane)
|
||||||
|
{
|
||||||
|
// Project vector onto world plane
|
||||||
|
right.y = 0;
|
||||||
|
right = Vector3Normalize(right);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Scale by distance
|
||||||
|
right = Vector3Scale(right, distance);
|
||||||
|
|
||||||
|
// Move position and target
|
||||||
|
camera->position = Vector3Add(camera->position, right);
|
||||||
|
camera->target = Vector3Add(camera->target, right);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Moves the camera position closer/farther to/from the camera target
|
||||||
|
void CameraMoveToTarget(Camera *camera, float delta)
|
||||||
|
{
|
||||||
|
float distance = Vector3Distance(camera->position, camera->target);
|
||||||
|
|
||||||
|
// Apply delta
|
||||||
|
distance += delta;
|
||||||
|
|
||||||
|
// Distance must be greater than 0
|
||||||
|
if (distance <= 0) distance = 0.001f;
|
||||||
|
|
||||||
|
// Set new distance by moving the position along the forward vector
|
||||||
|
Vector3 forward = GetCameraForward(camera);
|
||||||
|
camera->position = Vector3Add(camera->target, Vector3Scale(forward, -distance));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Rotates the camera around its up vector
|
||||||
|
// Yaw is "looking left and right"
|
||||||
|
// If rotateAroundTarget is false, the camera rotates around its position
|
||||||
|
// Note: angle must be provided in radians
|
||||||
|
void CameraYaw(Camera *camera, float angle, bool rotateAroundTarget)
|
||||||
|
{
|
||||||
|
// Rotation axis
|
||||||
|
Vector3 up = GetCameraUp(camera);
|
||||||
|
|
||||||
|
// View vector
|
||||||
|
Vector3 targetPosition = Vector3Subtract(camera->target, camera->position);
|
||||||
|
|
||||||
|
// Rotate view vector around up axis
|
||||||
|
targetPosition = Vector3RotateByAxisAngle(targetPosition, up, angle);
|
||||||
|
|
||||||
|
if (rotateAroundTarget)
|
||||||
|
{
|
||||||
|
// Move position relative to target
|
||||||
|
camera->position = Vector3Subtract(camera->target, targetPosition);
|
||||||
|
}
|
||||||
|
else // rotate around camera.position
|
||||||
|
{
|
||||||
|
// Move target relative to position
|
||||||
|
camera->target = Vector3Add(camera->position, targetPosition);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Rotates the camera around its right vector, pitch is "looking up and down"
|
||||||
|
// - lockView prevents camera overrotation (aka "somersaults")
|
||||||
|
// - rotateAroundTarget defines if rotation is around target or around its position
|
||||||
|
// - rotateUp rotates the up direction as well (typically only usefull in CAMERA_FREE)
|
||||||
|
// NOTE: angle must be provided in radians
|
||||||
|
void CameraPitch(Camera *camera, float angle, bool lockView, bool rotateAroundTarget, bool rotateUp)
|
||||||
|
{
|
||||||
|
// Up direction
|
||||||
|
Vector3 up = GetCameraUp(camera);
|
||||||
|
|
||||||
|
// View vector
|
||||||
|
Vector3 targetPosition = Vector3Subtract(camera->target, camera->position);
|
||||||
|
|
||||||
|
if (lockView)
|
||||||
|
{
|
||||||
|
// In these camera modes we clamp the Pitch angle
|
||||||
|
// to allow only viewing straight up or down.
|
||||||
|
|
||||||
|
// Clamp view up
|
||||||
|
float maxAngleUp = Vector3Angle(up, targetPosition);
|
||||||
|
maxAngleUp -= 0.001f; // avoid numerical errors
|
||||||
|
if (angle > maxAngleUp) angle = maxAngleUp;
|
||||||
|
|
||||||
|
// Clamp view down
|
||||||
|
float maxAngleDown = Vector3Angle(Vector3Negate(up), targetPosition);
|
||||||
|
maxAngleDown *= -1.0f; // downwards angle is negative
|
||||||
|
maxAngleDown += 0.001f; // avoid numerical errors
|
||||||
|
if (angle < maxAngleDown) angle = maxAngleDown;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Rotation axis
|
||||||
|
Vector3 right = GetCameraRight(camera);
|
||||||
|
|
||||||
|
// Rotate view vector around right axis
|
||||||
|
targetPosition = Vector3RotateByAxisAngle(targetPosition, right, angle);
|
||||||
|
|
||||||
|
if (rotateAroundTarget)
|
||||||
|
{
|
||||||
|
// Move position relative to target
|
||||||
|
camera->position = Vector3Subtract(camera->target, targetPosition);
|
||||||
|
}
|
||||||
|
else // rotate around camera.position
|
||||||
|
{
|
||||||
|
// Move target relative to position
|
||||||
|
camera->target = Vector3Add(camera->position, targetPosition);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (rotateUp)
|
||||||
|
{
|
||||||
|
// Rotate up direction around right axis
|
||||||
|
camera->up = Vector3RotateByAxisAngle(camera->up, right, angle);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Rotates the camera around its forward vector
|
||||||
|
// Roll is "turning your head sideways to the left or right"
|
||||||
|
// Note: angle must be provided in radians
|
||||||
|
void CameraRoll(Camera *camera, float angle)
|
||||||
|
{
|
||||||
|
// Rotation axis
|
||||||
|
Vector3 forward = GetCameraForward(camera);
|
||||||
|
|
||||||
|
// Rotate up direction around forward axis
|
||||||
|
camera->up = Vector3RotateByAxisAngle(camera->up, forward, angle);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Returns the camera view matrix
|
||||||
|
Matrix GetCameraViewMatrix(Camera *camera)
|
||||||
|
{
|
||||||
|
return MatrixLookAt(camera->position, camera->target, camera->up);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Returns the camera projection matrix
|
||||||
|
Matrix GetCameraProjectionMatrix(Camera *camera, float aspect)
|
||||||
|
{
|
||||||
|
if (camera->projection == CAMERA_PERSPECTIVE)
|
||||||
|
{
|
||||||
|
return MatrixPerspective(camera->fovy*DEG2RAD, aspect, CAMERA_CULL_DISTANCE_NEAR, CAMERA_CULL_DISTANCE_FAR);
|
||||||
|
}
|
||||||
|
else if (camera->projection == CAMERA_ORTHOGRAPHIC)
|
||||||
|
{
|
||||||
|
double top = camera->fovy/2.0;
|
||||||
|
double right = top*aspect;
|
||||||
|
|
||||||
|
return MatrixOrtho(-right, right, -top, top, CAMERA_CULL_DISTANCE_NEAR, CAMERA_CULL_DISTANCE_FAR);
|
||||||
|
}
|
||||||
|
|
||||||
|
return MatrixIdentity();
|
||||||
|
}
|
||||||
|
|
||||||
|
#if !defined(RCAMERA_STANDALONE)
|
||||||
|
// Update camera position for selected mode
|
||||||
|
// Camera mode: CAMERA_FREE, CAMERA_FIRST_PERSON, CAMERA_THIRD_PERSON, CAMERA_ORBITAL or CUSTOM
|
||||||
|
void UpdateCamera(Camera *camera, int mode)
|
||||||
|
{
|
||||||
|
Vector2 mousePositionDelta = GetMouseDelta();
|
||||||
|
|
||||||
|
bool moveInWorldPlane = ((mode == CAMERA_FIRST_PERSON) || (mode == CAMERA_THIRD_PERSON));
|
||||||
|
bool rotateAroundTarget = ((mode == CAMERA_THIRD_PERSON) || (mode == CAMERA_ORBITAL));
|
||||||
|
bool lockView = ((mode == CAMERA_FREE) || (mode == CAMERA_FIRST_PERSON) || (mode == CAMERA_THIRD_PERSON) || (mode == CAMERA_ORBITAL));
|
||||||
|
bool rotateUp = false;
|
||||||
|
|
||||||
|
if (mode == CAMERA_CUSTOM) {}
|
||||||
|
else if (mode == CAMERA_ORBITAL)
|
||||||
|
{
|
||||||
|
// Orbital can just orbit
|
||||||
|
Matrix rotation = MatrixRotate(GetCameraUp(camera), CAMERA_ORBITAL_SPEED*GetFrameTime());
|
||||||
|
Vector3 view = Vector3Subtract(camera->position, camera->target);
|
||||||
|
view = Vector3Transform(view, rotation);
|
||||||
|
camera->position = Vector3Add(camera->target, view);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Camera rotation
|
||||||
|
if (IsKeyDown(KEY_DOWN)) CameraPitch(camera, -CAMERA_ROTATION_SPEED, lockView, rotateAroundTarget, rotateUp);
|
||||||
|
if (IsKeyDown(KEY_UP)) CameraPitch(camera, CAMERA_ROTATION_SPEED, lockView, rotateAroundTarget, rotateUp);
|
||||||
|
if (IsKeyDown(KEY_RIGHT)) CameraYaw(camera, -CAMERA_ROTATION_SPEED, rotateAroundTarget);
|
||||||
|
if (IsKeyDown(KEY_LEFT)) CameraYaw(camera, CAMERA_ROTATION_SPEED, rotateAroundTarget);
|
||||||
|
if (IsKeyDown(KEY_Q)) CameraRoll(camera, -CAMERA_ROTATION_SPEED);
|
||||||
|
if (IsKeyDown(KEY_E)) CameraRoll(camera, CAMERA_ROTATION_SPEED);
|
||||||
|
|
||||||
|
// Camera movement
|
||||||
|
// Camera pan (for CAMERA_FREE)
|
||||||
|
if ((mode == CAMERA_FREE) && (IsMouseButtonDown(MOUSE_BUTTON_MIDDLE)))
|
||||||
|
{
|
||||||
|
const Vector2 mouseDelta = GetMouseDelta();
|
||||||
|
if (mouseDelta.x > 0.0f) CameraMoveRight(camera, CAMERA_PAN_SPEED, moveInWorldPlane);
|
||||||
|
if (mouseDelta.x < 0.0f) CameraMoveRight(camera, -CAMERA_PAN_SPEED, moveInWorldPlane);
|
||||||
|
if (mouseDelta.y > 0.0f) CameraMoveUp(camera, -CAMERA_PAN_SPEED);
|
||||||
|
if (mouseDelta.y < 0.0f) CameraMoveUp(camera, CAMERA_PAN_SPEED);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Mouse support
|
||||||
|
CameraYaw(camera, -mousePositionDelta.x*CAMERA_MOUSE_MOVE_SENSITIVITY, rotateAroundTarget);
|
||||||
|
CameraPitch(camera, -mousePositionDelta.y*CAMERA_MOUSE_MOVE_SENSITIVITY, lockView, rotateAroundTarget, rotateUp);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Keyboard support
|
||||||
|
if (IsKeyDown(KEY_W)) CameraMoveForward(camera, CAMERA_MOVE_SPEED, moveInWorldPlane);
|
||||||
|
if (IsKeyDown(KEY_A)) CameraMoveRight(camera, -CAMERA_MOVE_SPEED, moveInWorldPlane);
|
||||||
|
if (IsKeyDown(KEY_S)) CameraMoveForward(camera, -CAMERA_MOVE_SPEED, moveInWorldPlane);
|
||||||
|
if (IsKeyDown(KEY_D)) CameraMoveRight(camera, CAMERA_MOVE_SPEED, moveInWorldPlane);
|
||||||
|
|
||||||
|
// Gamepad movement
|
||||||
|
if (IsGamepadAvailable(0))
|
||||||
|
{
|
||||||
|
// Gamepad controller support
|
||||||
|
CameraYaw(camera, -(GetGamepadAxisMovement(0, GAMEPAD_AXIS_RIGHT_X)*2)*CAMERA_MOUSE_MOVE_SENSITIVITY, rotateAroundTarget);
|
||||||
|
CameraPitch(camera, -(GetGamepadAxisMovement(0, GAMEPAD_AXIS_RIGHT_Y)*2)*CAMERA_MOUSE_MOVE_SENSITIVITY, lockView, rotateAroundTarget, rotateUp);
|
||||||
|
|
||||||
|
if (GetGamepadAxisMovement(0, GAMEPAD_AXIS_LEFT_Y) <= -0.25f) CameraMoveForward(camera, CAMERA_MOVE_SPEED, moveInWorldPlane);
|
||||||
|
if (GetGamepadAxisMovement(0, GAMEPAD_AXIS_LEFT_X) <= -0.25f) CameraMoveRight(camera, -CAMERA_MOVE_SPEED, moveInWorldPlane);
|
||||||
|
if (GetGamepadAxisMovement(0, GAMEPAD_AXIS_LEFT_Y) >= 0.25f) CameraMoveForward(camera, -CAMERA_MOVE_SPEED, moveInWorldPlane);
|
||||||
|
if (GetGamepadAxisMovement(0, GAMEPAD_AXIS_LEFT_X) >= 0.25f) CameraMoveRight(camera, CAMERA_MOVE_SPEED, moveInWorldPlane);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (mode == CAMERA_FREE)
|
||||||
|
{
|
||||||
|
if (IsKeyDown(KEY_SPACE)) CameraMoveUp(camera, CAMERA_MOVE_SPEED);
|
||||||
|
if (IsKeyDown(KEY_LEFT_CONTROL)) CameraMoveUp(camera, -CAMERA_MOVE_SPEED);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((mode == CAMERA_THIRD_PERSON) || (mode == CAMERA_ORBITAL) || (mode == CAMERA_FREE))
|
||||||
|
{
|
||||||
|
// Zoom target distance
|
||||||
|
CameraMoveToTarget(camera, -GetMouseWheelMove());
|
||||||
|
if (IsKeyPressed(KEY_KP_SUBTRACT)) CameraMoveToTarget(camera, 2.0f);
|
||||||
|
if (IsKeyPressed(KEY_KP_ADD)) CameraMoveToTarget(camera, -2.0f);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif // !RCAMERA_STANDALONE
|
||||||
|
|
||||||
|
// Update camera movement, movement/rotation values should be provided by user
|
||||||
|
void UpdateCameraPro(Camera *camera, Vector3 movement, Vector3 rotation, float zoom)
|
||||||
|
{
|
||||||
|
// Required values
|
||||||
|
// movement.x - Move forward/backward
|
||||||
|
// movement.y - Move right/left
|
||||||
|
// movement.z - Move up/down
|
||||||
|
// rotation.x - yaw
|
||||||
|
// rotation.y - pitch
|
||||||
|
// rotation.z - roll
|
||||||
|
// zoom - Move towards target
|
||||||
|
|
||||||
|
bool lockView = true;
|
||||||
|
bool rotateAroundTarget = false;
|
||||||
|
bool rotateUp = false;
|
||||||
|
bool moveInWorldPlane = true;
|
||||||
|
|
||||||
|
// Camera rotation
|
||||||
|
CameraPitch(camera, -rotation.y*DEG2RAD, lockView, rotateAroundTarget, rotateUp);
|
||||||
|
CameraYaw(camera, -rotation.x*DEG2RAD, rotateAroundTarget);
|
||||||
|
CameraRoll(camera, rotation.z*DEG2RAD);
|
||||||
|
|
||||||
|
// Camera movement
|
||||||
|
CameraMoveForward(camera, movement.x, moveInWorldPlane);
|
||||||
|
CameraMoveRight(camera, movement.y, moveInWorldPlane);
|
||||||
|
CameraMoveUp(camera, movement.z);
|
||||||
|
|
||||||
|
// Zoom target distance
|
||||||
|
CameraMoveToTarget(camera, zoom);
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif // RCAMERA_IMPLEMENTATION
|
||||||
Loading…
Reference in New Issue