diff --git a/ClassicalSharp/Utils/Camera.cs b/ClassicalSharp/Utils/Camera.cs index 6bbaa054e..523ad9f2d 100644 --- a/ClassicalSharp/Utils/Camera.cs +++ b/ClassicalSharp/Utils/Camera.cs @@ -66,6 +66,10 @@ namespace ClassicalSharp { tiltM = Matrix4.Identity; } + protected Vector3 GetDirVector() { + return Utils.GetDirVector(player.HeadYRadians, AdjustHeadX(player.HeadX)); + } + public override Matrix4 GetProjection() { float fovy = game.Fov * Utils.Deg2Rad; float aspectRatio = (float)game.Width / game.Height; @@ -74,8 +78,7 @@ namespace ClassicalSharp { } public override void GetPickedBlock(PickedPos pos) { - Vector3 dir = Utils.GetDirVector(player.HeadYRadians, - AdjustHeadX(player.HeadX)); + Vector3 dir = GetDirVector(); Vector3 eyePos = player.EyePosition; float reach = game.LocalPlayer.ReachDistance; @@ -155,10 +158,6 @@ namespace ClassicalSharp { Matrix4.RotateX(out velX, -vel * 0.05f * p.tilt.velTiltStrength / velTiltScale); tiltM *= velX; } - - protected Vector3 GetDirVector() { - return Utils.GetDirVector(player.HeadYRadians, AdjustHeadX(player.HeadX)); - } } public class ThirdPersonCamera : PerspectiveCamera { diff --git a/src/Client/2DStructs.h b/src/Client/2DStructs.h index 07ca92573..d12b62d45 100644 --- a/src/Client/2DStructs.h +++ b/src/Client/2DStructs.h @@ -12,7 +12,6 @@ typedef struct Rectangle2D_ { /* Size of rectangle. */ Int32 Width, Height; } Rectangle2D; - /* Empty 2D rectangle. */ Rectangle2D Rectangle2D_Empty; @@ -20,12 +19,15 @@ Rectangle2D Rectangle2D_Empty; typedef struct Point2D_ { Int32 X, Y; } Point2D; +/* Point at X = 0 and Y = 0 */ +Point2D Point2D_Empty; /* Stores a point in 2D space. */ typedef struct Size2D_ { Int32 Width, Height; } Size2D; - +/* Size with Width = 0 and Height = 0 */ +Size2D Size2D_Empty; /* Creates a new rectangle. */ Rectangle2D Rectangle2D_Make(Int32 x, Int32 y, Int32 width, Int32 height); diff --git a/src/Client/Camera.c b/src/Client/Camera.c new file mode 100644 index 000000000..f5fa877c7 --- /dev/null +++ b/src/Client/Camera.c @@ -0,0 +1,193 @@ +#include "Camera.h" +#include "ExtMath.h" +#include "Game.h" +#include "Window.h" +#include "GraphicsAPI.h" +#include "Player.h" + +Real32 Camera_AdjustHeadX(Real32 value) { + if (value >= 90.00f && value <= 90.10f) return 90.10f * MATH_DEG2RAD; + if (value >= 89.90f && value <= 90.00f) return 89.90f * MATH_DEG2RAD; + if (value >= 270.0f && value <= 270.1f) return 270.1f * MATH_DEG2RAD; + if (value >= 269.9f && value <= 270.0f) return 269.9f * MATH_DEG2RAD; + return value * MATH_DEG2RAD; +} + +Vector3 PerspectiveCamera_GetDirVector() { + Entity* p = &LocalPlayer_Instance.Base.Base; + Real32 yaw = p->HeadY * MATH_DEG2RAD; + Real32 pitch = Camera_AdjustHeadX(p->HeadX); + return Vector3_GetDirVector(yaw, pitch); +} + +void PerspectiveCamera_GetProjection(Matrix* proj) { + Real32 fovy = Game_Fov * MATH_DEG2RAD; + Size2D size = Window_GetClientSize(); + Real32 aspectRatio = (Real32)size.Width / (Real32)size.Height; + Matrix_PerspectiveFieldOfView(proj, fovy, aspectRatio, Gfx_MinZNear, Game_ViewDistance); +} + +void PerspectiveCamera_GetPickedBlock(PickedPos* pos) { + Entity* p = &LocalPlayer_Instance.Base.Base; + Vector3 dir = PerspectiveCamera_GetDirVector(); + Vector3 eyePos = Entity_GetEyePosition(p); + Real32 reach = LocalPlayer_Instance.ReachDistance; + Picking_CalculatePickedBlock(eyePos, dir, reach, pos); +} + +Point2D previous, delta; +void PerspectiveCamera_CentreMousePosition(void) { + if (!Window_GetFocused()) return; + Point2D current = Window_GetDesktopCursorPos(); + delta = Point2D_Make(current.X - previous.X, current.Y - previous.Y); + + Point2D topLeft = Window_PointToScreen(Point2D_Empty); + Size2D size = Window_GetClientSize(); + Int32 cenX = topLeft.X + size.Width * 0.5f; + Int32 cenY = topLeft.Y + size.Height * 0.5f; + + Window_SetDesktopCursorPos(Point2D_Make(cenX, cenY)); + /* Fixes issues with large DPI displays on Windows >= 8.0. */ + previous = Window_GetDesktopCursorPos(); +} + +void PerspectiveCamera_RegrabMouse(void) { + if (!Window_GetExists()) return; + + Point2D topLeft = Window_PointToScreen(Point2D_Empty); + Size2D size = Window_GetClientSize(); + Int32 cenX = topLeft.X + size.Width * 0.5f; + Int32 cenY = topLeft.Y + size.Height * 0.5f; + + Point2D point = Point2D_Make(cenX, cenY); + Window_SetDesktopCursorPos(point); + previous = point; + delta = Point2D_Empty; +} + +#define sensiFactor (0.0002f / 3.0f * MATH_RAD2DEG) +#define slippery 0.97f +#define adjust 0.025f + +Real32 speedX = 0.0f, speedY = 0.0f; +void PersepctiveCamera_UpdateMouseRotation(void) { + Real32 sensitivity = sensiFactor * Game_MouseSensitivity; + + if (Game_SmoothCamera) { + speedX += delta.X * adjust; + speedX *= slippery; + speedY += delta.Y * adjust; + speedY *= slippery; + } else { + speedX = delta.X; + speedY = delta.Y; + } + + Real32 rotY = player.interp.next.HeadY + speedX * sensitivity; + Real32 yAdj = Game_InvertMouse ? -speedY * sensitivity : speedY * sensitivity; + Real32 headX = player.interp.next.HeadX + yAdj; + LocationUpdate* update; + LocationUpdate_MakeOri(update, rotY, headX); + + /* Need to make sure we don't cross the vertical axes, because that gets weird. */ + if (update->HeadX >= 90.0f && update->HeadX <= 270.0f) { + update->HeadX = player.interp.next.HeadX < 180.0f ? 89.9f : 270.1f; + } + game.LocalPlayer.SetLocation(update, false); +} + +void PerspectiveCamera_UpdateMouse(void) { + if (game.Gui.ActiveScreen.HandlesAllInput) return; + CentreMousePosition(); + UpdateMouseRotation(); +} + +void PerspectiveCamera_CalcViewBobbing(Real32 t, Real32 velTiltScale) { + if (!Game_ViewBobbing) { Camera_TiltMatrix = Matrix_Identity; return; } + LocalPlayer p = game.LocalPlayer; + Matrix tiltY, velX; + Matrix_RotateZ(out tiltM, -p.tilt.tiltX * p.anim.bobStrength); + Matrix_RotateX(out tiltY, Math.Abs(p.tilt.tiltY) * 3 * p.anim.bobStrength); + tiltM *= tiltY; + + bobbingHor = (p.anim.bobbingHor * 0.3f) * p.anim.bobStrength; + bobbingVer = (p.anim.bobbingVer * 0.6f) * p.anim.bobStrength; + + float vel = Utils.Lerp(p.OldVelocity.Y + 0.08f, p.Velocity.Y + 0.08f, t); + Matrix4.RotateX(out velX, -vel * 0.05f * p.tilt.velTiltStrength / velTiltScale); + tiltM *= velX; +} + +void PerspectiveCamera_Init(Camera* cam) { + +} + + public class ThirdPersonCamera : PerspectiveCamera { + public ThirdPersonCamera(Game window, bool forward) : base(window) { this.forward = forward; } + public override bool IsThirdPerson{ get{ return true; } } + + bool forward; + float dist = 3; + public override bool Zoom(float amount) { + dist = Math.Max(dist - amount, 2); + return true; + } + + public override Matrix4 GetView() { + Vector3 eyePos = player.EyePosition; + eyePos.Y += bobbingVer; + + Vector3 cameraPos = game.CurrentCameraPos; + return Matrix4.LookAt(cameraPos, eyePos, Vector3.UnitY) * tiltM; + } + + public override Vector2 GetCameraOrientation() { + if (!forward) + return new Vector2(player.HeadYRadians, player.HeadXRadians); + return new Vector2(player.HeadYRadians + (float)Math.PI, -player.HeadXRadians); + } + + public override Vector3 GetCameraPos(float t) { + CalcViewBobbing(t, dist); + Vector3 eyePos = player.EyePosition; + eyePos.Y += bobbingVer; + + Vector3 dir = GetDirVector(); + if (!forward) dir = -dir; + Picking.ClipCameraPos(game, eyePos, dir, dist, game.CameraClipPos); + return game.CameraClipPos.Intersect; + } + } + +void FirstPersonCamera_GetView(Matrix* mat) { + Vector3 camPos = Game_CurrentCameraPos; + Vector3 dir = GetDirVector(); + return Matrix4.LookAt(camPos, camPos + dir, Vector3.UnitY) * tiltM; +} + +Vector2 FirstPersonCamera_GetCameraOrientation(void) { + Entity* p = &LocalPlayer_Instance->Base->Base; + return Vector2_Create2(p->HeadY * MATH_DEG2RAD, p->HeadX * MATH_DEG2RAD); +} + +Vector3 FirstPersonCamera_GetCameraPos(void) { + CalcViewBobbing(t, 1); + Vector3 camPos = player.EyePosition; + camPos.Y += bobbingVer; + + double adjHeadY = player.HeadYRadians + Math.PI / 2; + camPos.X += bobbingHor * (float)Math.Sin(adjHeadY); + camPos.Z -= bobbingHor * (float)Math.Cos(adjHeadY); + return camPos; +} + +bool FirstPersonCamera_Zoom(Real32 amount) { return false; } + +void FirstPersonCamera_Init(Camera* cam) { + PerspectiveCamera_Init(cam); + cam->IsThirdPerson = false; + cam->GetView = FirstPersonCamera_GetView; + cam->GetCameraPos = FirstPersonCamera_GetCameraPos; + cam->GetCameraOrientation = FirstPersonCamera_GetCameraOrientation; + cam->Zoom = FirstPersonCamera_Zoom; +} \ No newline at end of file diff --git a/src/Client/Camera.h b/src/Client/Camera.h index ae1aa6be7..440a7edca 100644 --- a/src/Client/Camera.h +++ b/src/Client/Camera.h @@ -1,53 +1,44 @@ -#if 0 #ifndef CS_CAMERA_H #define CS_CAMERA_H #include "Typedefs.h" #include "Vectors.h" -#include "Matrix.h" -#include "PickedPos.h" +#include "Picking.h" /* Represents a camera, may be first or third person. -Copyright 2014-2017 ClassicalSharp | Licensed under BSD-3 + Copyright 2014-2017 ClassicalSharp | Licensed under BSD-3 */ +/* Tilt matrix applied to the active camera. */ +Matrix Camera_TiltMatrix; +/* Bobbing applied to the active camera. */ +Real32 Camera_BobbingVer, Camera_BobbingHor; + typedef struct Camera_ { - /* Tilt matrix of this camera. */ - Matrix tiltM; - - /* Bobbing applied to this camera. */ - Real32 bobbingVer, bobbingHor; - /* Whether this camera is a third person camera. NOTE: Causes the player's own entity model to be renderered if true.*/ bool IsThirdPerson; - /* Calculates the projection matrix for this camera. */ - void(*GetProjection)(Matrix* proj); - + void (*GetProjection)(Matrix* proj); /* Calculates the world/view matrix for this camera. */ - void(*GetView)(Matrix* view); - + void (*GetView)(Matrix* view); /* Calculates the location of the camera's position in the world. */ - Vector3(*GetCameraPos)(Real32 t); - + Vector3 (*GetCameraPos)(Real32 t); /* Calculates the yaw and pitch of the camera in radians. */ - Vector2(*GetCameraOrientation)(void); + Vector2 (*GetCameraOrientation)(void); /* Called every frame for the camera to update its state. e.g. Perspective cameras adjusts player's rotatation using delta between mouse position and window centre. */ - void(*UpdateMouse)(void); - + void (*UpdateMouse)(void); /* Called after the camera has regrabbed the mouse from 2D input handling. e.g. Perspective cameras set the mouse position to window centre. */ - void(*RegrabMouse)(void); + void (*RegrabMouse)(void); /* Calculates the picked block based on the camera's current state. */ - void(*GetPickedBlock)(PickedPos* pos); - + void (*GetPickedBlock)(PickedPos* pos); /* Attempts to zoom the camera's position closer to or further from its origin point. returns true if this camera handled zooming (Such as third person cameras) */ - bool(*Zoom)(Real32 amount); + bool (*Zoom)(Real32 amount); } Camera; /* Adjusts head X rotation of the player to avoid looking straight up or down. @@ -55,7 +46,6 @@ Returns the resulting angle in radians. NOTE: looking straight up or down (parallel to camera up vector) can otherwise cause rendering issues. */ Real32 Camera_AdjustHeadX(Real32 degrees); - /* Returns the active camera instance. */ Camera* Camera_ActiveCamera; @@ -67,24 +57,4 @@ void Camera_CycleActive(void); /* Adds a camera to the list of available cameras. */ void Camera_Add(Camera camera); - - -static Camera Camera_MakePerspective(void); - -static void PerspectiveCamera_CalcProj(Matrix* proj); - -static void PerspectiveCamera_GetPickedBlock(PickedPos* pos); - -static void PerspectiveCamera_CentreMousePosition(void); - -static void PerspectiveCamera_RegrabMouse(void); - -static void PerspectiveCamera_UpdateMouseRotation(void); - -static void PerspectiveCamera_UpdateMouse(void); - -static void PerspectiveCamera_CalcViewBobbing(Camera* cam, Real32 t, Real32 velTiltScale); - -static Vector3 PerspectiveCamera_GetDirVector(void); -#endif #endif \ No newline at end of file diff --git a/src/Client/Client.vcxproj b/src/Client/Client.vcxproj index 3ecadeaf9..f09e11067 100644 --- a/src/Client/Client.vcxproj +++ b/src/Client/Client.vcxproj @@ -213,7 +213,7 @@ - + @@ -247,6 +247,7 @@ + diff --git a/src/Client/Client.vcxproj.filters b/src/Client/Client.vcxproj.filters index 69fbc3978..162bb0687 100644 --- a/src/Client/Client.vcxproj.filters +++ b/src/Client/Client.vcxproj.filters @@ -240,9 +240,6 @@ Header Files\Utils - - Header Files\Math - Header Files\Network @@ -366,6 +363,9 @@ Header Files\Entities + + Header Files\Math + @@ -548,5 +548,8 @@ Source Files\Entities\Components + + Source Files\Utils + \ No newline at end of file diff --git a/src/Client/Entity.c b/src/Client/Entity.c index fa9dd539d..9d0213938 100644 --- a/src/Client/Entity.c +++ b/src/Client/Entity.c @@ -38,6 +38,12 @@ void LocationUpdate_MakePosAndOri(LocationUpdate* update, Vector3 pos, Real32 ro } +Vector3 Entity_GetEyePosition(Entity* entity) { + Vector3 pos = entity->Position; + pos.Y += entity->Model->GetEyeY(entity) * entity->ModelScale.Y; + return pos; +} + void Entity_GetPickingBounds(Entity* entity, AABB* bb) { AABB_Offset(bb, &entity->ModelAABB, &entity->Position); } diff --git a/src/Client/Entity.h b/src/Client/Entity.h index 778f5934f..638143178 100644 --- a/src/Client/Entity.h +++ b/src/Client/Entity.h @@ -81,6 +81,9 @@ typedef struct Entity_ { /* Initalises the given entity. */ void Entity_Init(Entity* entity); +/* Gets the position of the player's eye in the world. */ +Vector3 Entity_GetEyePosition(Entity* entity); + /* Returns the bounding box that contains the model, without any rotations applied. */ void Entity_GetPickingBounds(Entity* entity, AABB* bb); diff --git a/src/Client/ExtMath.h b/src/Client/ExtMath.h index bcf0a6d4c..e0d437e4d 100644 --- a/src/Client/ExtMath.h +++ b/src/Client/ExtMath.h @@ -2,40 +2,33 @@ #define CS_MATH_H #include #include "Typedefs.h" -/* Simple math functions. +/* Simple math functions and constants. Copyright 2017 ClassicalSharp | Licensed under BSD-3 */ #define MATH_PI 3.1415926535897931f - #define MATH_DEG2RAD (MATH_PI / 180.0f) - #define MATH_RAD2DEG (180.0f / MATH_PI) #define Math_AbsF(x) fabsf(x) - #define Math_AbsI(x) abs(x) #define Math_LogE(x) logf(x) - #define Math_PowE(x) expf(x) #define Math_Sin(x) sinf(x) - #define Math_Cos(x) cosf(x) - #define Math_Tan(x) tanf(x) +#define Math_Asin(x) asinf(x) +#define Math_Atan2(y, x) atan2f(y, x) #define Math_Sqrt(x) sqrtf(x) - #define Math_Mod(x, y) fmodf(x, y) /* Integer floor of a floating-point value. */ Int32 Math_Floor(Real32 value); - /* Log base 2 of given value. */ Int32 Math_Log2(Int32 value); - /* Performs rounding upwards integer division.*/ Int32 Math_CeilDiv(Int32 a, Int32 b); @@ -44,7 +37,6 @@ Real32 Math_Lerp(Real32 a, Real32 b, Real32 t); /* Returns the next highest power of 2 that is greater or equal to the given value. */ Int32 Math_NextPowOf2(Int32 value); - /* Returns whether the given value is a power of 2. */ bool Math_IsPowOf2(Int32 value); diff --git a/src/Client/Game.h b/src/Client/Game.h index 2afe30bbe..b3b55115c 100644 --- a/src/Client/Game.h +++ b/src/Client/Game.h @@ -3,7 +3,7 @@ #include "Typedefs.h" #include "Stream.h" #include "GraphicsEnums.h" -#include "PickedPos.h" +#include "Picking.h" #include "Options.h" /* Represents the game. Copyright 2014-2017 ClassicalSharp | Licensed under BSD-3 diff --git a/src/Client/PickedPos.h b/src/Client/Picking.h similarity index 78% rename from src/Client/PickedPos.h rename to src/Client/Picking.h index 25b74a3cd..176020b9e 100644 --- a/src/Client/PickedPos.h +++ b/src/Client/Picking.h @@ -1,10 +1,10 @@ -#ifndef CS_PICKEDPOS_H -#define CS_PICKEDPOS_H +#ifndef CS_PICKING_H +#define CS_PICKING_H #include "Typedefs.h" #include "Constants.h" #include "Vectors.h" #include "BlockID.h" -/* Data for picked/selected block by the user, and related methods. +/* Data for picking/selecting block by the user, and clipping the camera. Copyright 2014 - 2017 ClassicalSharp | Licensed under BSD-3 */ @@ -33,4 +33,8 @@ void PickedPos_SetAsValid(PickedPos* pos, Int32 x, Int32 y, Int32 z, Vector3 min /* Marks as not having a selected block. */ void PickedPos_SetAsInvalid(PickedPos* pos); + +void Picking_CalculatePickedBlock(Vector3 origin, Vector3 dir, Real32 reach, PickedPos* pos); + +void Picking_ClipCameraPos(Vector3 origin, Vector3 dir, Real32 reach, PickedPos* pos); #endif \ No newline at end of file diff --git a/src/Client/Player.h b/src/Client/Player.h index d7890a83a..0cc556987 100644 --- a/src/Client/Player.h +++ b/src/Client/Player.h @@ -21,6 +21,8 @@ typedef struct LocalPlayer_ { Real32 SpawnRotY, SpawnHeadX; /* Hacks state of this player. */ HacksComponent Hacks; + /* Distance (in blocks) that players are allowed to reach to and interact/modify blocks in. */ + Real32 ReachDistance; } LocalPlayer; diff --git a/src/Client/String.c b/src/Client/String.c index 9dfadc79d..b98aa1b4d 100644 --- a/src/Client/String.c +++ b/src/Client/String.c @@ -337,8 +337,7 @@ bool Convert_TryParseReal32(STRING_TRANSIENT String* str, Real32* value) { Int32 digit = c - '0'; if (!foundDecimalPoint) { whole *= 10; whole += digit; - } - else { + } else { fract += digit / divide; divide *= 10; } } diff --git a/src/Client/Vectors.c b/src/Client/Vectors.c index 7f0c1a8df..5720cdde3 100644 --- a/src/Client/Vectors.c +++ b/src/Client/Vectors.c @@ -181,4 +181,17 @@ void Vector3I_Max(Vector3I* result, Vector3I* a, Vector3I* b) { result->X = max(a->X, b->X); result->Y = max(a->Y, b->Y); result->Z = max(a->Z, b->Z); +} + + +Vector3 Vector3_GetDirVector(Real32 yawRad, Real32 pitchRad) { + Real32 x = -Math_Cos(pitchRad) * -Math_Sin(yawRad); + Real32 y = -Math_Sin(pitchRad); + Real32 z = -Math_Cos(pitchRad) * Math_Cos(yawRad); + return Vector3_Create3(x, y, z); +} + +void Vector3_GetHeading(Vector3 dir, Real32* yaw, Real32* pitch) { + *pitch = Math_Asin(-dir.Y); + *yaw = Math_Atan2(dir.X, -dir.Z); } \ No newline at end of file diff --git a/src/Client/Vectors.h b/src/Client/Vectors.h index 02c2685a5..8f6aef733 100644 --- a/src/Client/Vectors.h +++ b/src/Client/Vectors.h @@ -11,29 +11,22 @@ typedef struct Vector2_ { Real32 X, Y; } Vector2; typedef struct Vector3_ { Real32 X, Y, Z; } Vector3; typedef struct Vector3I_ { Int32 X, Y, Z; } Vector3I; - /* Constructs a 2D vector from the given coordinates. */ Vector2 Vector2_Create2(Real32 x, Real32 y); - /* Constructs a 3D vector with X, Y and Z set to given value. */ Vector3 Vector3_Create1(Real32 value); - /* Constructs a 3D vector from the given coordinates. */ Vector3 Vector3_Create3(Real32 x, Real32 y, Real32 z); - /* Constructs a 3D vector with X, Y and Z set to given value. */ Vector3I Vector3I_Create1(Int32 value); - /* Constructs a 3D vector from the given coordinates. */ Vector3I Vector3I_Create3(Int32 x, Int32 y, Int32 z); /* Returns the length of the given vector. */ Real32 Vector3_Length(Vector3* v); - /* Returns the squared length of the given vector. */ Real32 Vector3_LengthSquared(Vector3* v); - #define Vector2_UnitX Vector2_Create2(1.0f, 0.0f) #define Vector2_UnitY Vector2_Create2(0.0f, 1.0f) #define Vector2_Zero Vector2_Create2(0.0f, 0.0f) @@ -52,101 +45,78 @@ Real32 Vector3_LengthSquared(Vector3* v); #define Vector3I_One Vector3I_Create3(1, 1, 1) #define Vector3I_MinusOne Vector3I_Create3(-1, -1, -1) - /* Adds a and b. */ void Vector3_Add(Vector3* result, Vector3* a, Vector3* b); - /* Adds a and b. */ void Vector3I_Add(Vector3I* result, Vector3I* a, Vector3I* b); - /* Adds b to all components of a. */ void Vector3_Add1(Vector3* result, Vector3* a, Real32 b); - /* Subtracts b from a. */ void Vector3_Subtract(Vector3* result, Vector3* a, Vector3* b); - /* Subtracts b from a. */ void Vector3I_Subtract(Vector3I* result, Vector3I* a, Vector3I* b); - /* Multiplies all components of a by scale. */ void Vector3_Multiply1(Vector3* result, Vector3* a, Real32 scale); - /* Multiplies all components of a by scale. */ void Vector3I_Multiply1(Vector3I* result, Vector3I* a, Int32 scale); - /* Multiplies components of a by scale. */ void Vector3_Multiply3(Vector3* result, Vector3* a, Vector3* scale); - /* Divides all components of a by scale. */ void Vector3_Divide1(Vector3* result, Vector3* a, Real32 scale); - /* Divides components of a by scale. */ void Vector3_Divide3(Vector3* result, Vector3* a, Vector3* scale); - /* Negates components of a. */ void Vector3I_Negate(Vector3I* result, Vector3I* a); - /* Linearly interpolates between two vectors. */ void Vector3_Lerp(Vector3* result, Vector3* a, Vector3* b, Real32 blend); - /* Calculates the dot product of two vectors. */ Real32 Vector3_Dot(Vector3* left, Vector3* right); - /* Calculates the cross product of two vectors. */ void Vector3_Cross(Vector3* result, Vector3* a, Vector3* b); - /* Calculates the normal of a vector. */ void Vector3_Normalize(Vector3* result, Vector3* a); - /* Transforms a vector by the given matrix. */ void Vector3_Transform(Vector3* result, Vector3* a, Matrix* mat); - /* Transforms a vector consisting of only a X component by the given matrix. */ void Vector3_TransformX(Vector3* result, Real32 x, Matrix* mat); - /* Transforms a vector consisting of only a Y component by the given matrix. */ void Vector3_TransformY(Vector3* result, Real32 y, Matrix* mat); - /* Transforms a vector consisting of only a Z component by the given matrix. */ void Vector3_TransformZ(Vector3* result, Real32 z, Matrix* mat); /* Rotates the given 3D coordinates around the x axis. */ Vector3 Vector3_RotateX(Vector3 v, Real32 angle); - /* Rotates the given 3D coordinates around the y axis. */ Vector3 Vector3_RotateY(Vector3 v, Real32 angle); - /* Rotates the given 3D coordinates around the y axis. */ Vector3 Vector3_RotateY3(Real32 x, Real32 y, Real32 z, Real32 angle); - /* Rotates the given 3D coordinates around the z axis. */ Vector3 Vector3_RotateZ(Vector3 v, Real32 angle); - /* Returns whether the two vectors are exact same on all axes. */ bool Vector3_Equals(Vector3* a, Vector3* b); - /* Returns whether the two vectors are different on any axis. */ bool Vector3_NotEquals(Vector3* a, Vector3* b); - /* Returns whether the two vectors are exact same on all axes. */ bool Vector3I_Equals(Vector3I* a, Vector3I* b); - /* Returns whether the two vectors are different on any axes. */ bool Vector3I_NotEquals(Vector3I* a, Vector3I* b); - /* Returns a vector such that each component is floor of input floating-point component.*/ void Vector3I_Floor(Vector3I* result, Vector3* a); - /* Returns a vector with the integer components converted to floating-point components.*/ void Vector3I_ToVector3(Vector3* result, Vector3I* a); /* Returns a vector such that each component is minimum of corresponding a and b component.*/ void Vector3I_Min(Vector3I* result, Vector3I* a, Vector3I* b); - /* Returns a vector such that each component is maximum of corresponding a and b component.*/ void Vector3I_Max(Vector3I* result, Vector3I* a, Vector3I* b); + +/* Returns a normalised vector that faces in the direction described by the given yaw and pitch. */ +Vector3 Vector3_GetDirVector(Real32 yawRad, Real32 pitchRad); +/* Returns the yaw and pitch of the given direction vector. +NOTE: This is not an identity function. Returned pitch is always within [-90, 90] degrees.*/ +void Vector3_GetHeading(Vector3 dir, Real32* yawRad, Real32* pitchRad); #endif \ No newline at end of file