Start porting camera to C.

This commit is contained in:
UnknownShadow200 2017-08-25 18:02:11 +10:00
parent b181be4af0
commit b9eb5f976c
15 changed files with 267 additions and 110 deletions

View File

@ -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 {

View File

@ -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);

193
src/Client/Camera.c Normal file
View File

@ -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;
}

View File

@ -1,50 +1,41 @@
#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
*/
/* 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);
/* Calculates the world/view matrix for this camera. */
void (*GetView)(Matrix* view);
/* Calculates the location of the camera's position in the world. */
Vector3 (*GetCameraPos)(Real32 t);
/* Calculates the yaw and pitch of the camera in radians. */
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);
/* 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);
/* Calculates the picked block based on the camera's current state. */
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);
@ -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

View File

@ -213,7 +213,7 @@
<ClInclude Include="NormalBuilder.h" />
<ClInclude Include="Options.h" />
<ClInclude Include="Physics.h" />
<ClInclude Include="PickedPos.h" />
<ClInclude Include="Picking.h" />
<ClInclude Include="PickedPosRenderer.h" />
<ClInclude Include="Player.h" />
<ClInclude Include="Respawn.h" />
@ -247,6 +247,7 @@
<ItemGroup>
<ClCompile Include="2DStructs.c" />
<ClCompile Include="AABB.c" />
<ClCompile Include="Camera.c" />
<ClCompile Include="EntityComponents.c" />
<ClCompile Include="AxisLinesRenderer.c" />
<ClCompile Include="Block.c" />

View File

@ -240,9 +240,6 @@
<ClInclude Include="Camera.h">
<Filter>Header Files\Utils</Filter>
</ClInclude>
<ClInclude Include="PickedPos.h">
<Filter>Header Files\Math</Filter>
</ClInclude>
<ClInclude Include="NetworkEnums.h">
<Filter>Header Files\Network</Filter>
</ClInclude>
@ -366,6 +363,9 @@
<ClInclude Include="EntityComponents.h">
<Filter>Header Files\Entities</Filter>
</ClInclude>
<ClInclude Include="Picking.h">
<Filter>Header Files\Math</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<ClCompile Include="Noise.c">
@ -548,5 +548,8 @@
<ClCompile Include="EntityComponents.c">
<Filter>Source Files\Entities\Components</Filter>
</ClCompile>
<ClCompile Include="Camera.c">
<Filter>Source Files\Utils</Filter>
</ClCompile>
</ItemGroup>
</Project>

View File

@ -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);
}

View File

@ -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);

View File

@ -2,40 +2,33 @@
#define CS_MATH_H
#include <math.h>
#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);

View File

@ -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

View File

@ -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

View File

@ -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;

View File

@ -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;
}
}

View File

@ -182,3 +182,16 @@ void Vector3I_Max(Vector3I* result, Vector3I* a, Vector3I* b) {
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);
}

View File

@ -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