protocol uint/magnolia / source / client / camera.c
 1#include "client/camera.h"
 2#include "mgmath.h"
 3
 4#define MAX_PITCH (MG_AngleDeg(89.0f)) /* < 90 so no div by 0s */
 5
 6void camera_init(MGCamera* cam, MGVec3 pos)
 7{
 8	/* TODO: maybe some immediate mode ui could be nice? */
 9	/* IMGUI imgui Immediate */
10	cam->pos = pos;
11	cam->yaw = 0.0f;
12	cam->pitch = 0.0f;
13	cam->fov = MG_AngleDeg(70.0f);
14	cam->near = 0.1f;
15	cam->far = 100.0f;
16}
17
18void camera_move(MGCamera* cam, MGVec3 offset)
19{
20	MGVec3 forward = camera_get_forward(cam);
21	MGVec3 right = camera_get_right(cam);
22	MGVec3 movement = MG_V3(0.0f, 0.0f, 0.0f);
23
24	/* ignore pitch so we don't go to where we look */
25	forward.y = 0.0f;
26	forward = MG_NormV3(forward);
27
28	movement = MG_AddV3(movement, MG_MulV3F(forward, offset.z));
29	movement = MG_AddV3(movement, MG_MulV3F(right, offset.x));
30
31	movement.y += offset.y;
32	cam->pos = MG_AddV3(cam->pos, movement);
33}
34
35void camera_rotate(MGCamera* cam, float dyaw, float dpitch)
36{
37	cam->yaw += dyaw;
38	cam->pitch += dpitch;
39
40	if (cam->pitch > MAX_PITCH)
41		cam->pitch = MAX_PITCH;
42
43	if (cam->pitch < -MAX_PITCH)
44		cam->pitch = -MAX_PITCH;
45}
46
47MGVec3 camera_get_forward(const MGCamera* cam)
48{
49	MGVec3 forward;
50	float  pcos = MG_CosF(cam->pitch);
51
52	forward.x = pcos * MG_SinF(cam->yaw);
53	forward.y = MG_SinF(cam->pitch);
54	forward.z = -pcos * MG_CosF(cam->yaw);
55	return MG_NormV3(forward);
56}
57
58MGVec3 camera_get_right(const MGCamera* cam)
59{
60	return MG_NormV3(MG_Cross(camera_get_forward(cam), MG_V3(0.0f, 1.0f, 0.0f)));
61}
62
63MGMat4 camera_get_view(const MGCamera* cam)
64{
65	MGVec3 target = MG_AddV3(cam->pos, camera_get_forward(cam));
66	return MG_LookAt_RH(cam->pos, target, MG_V3(0.0f, 1.0f, 0.0f));
67}
68
69MGMat4 camera_get_proj(const MGCamera* cam, float aspect)
70{
71	return MG_Perspective_RH_NO(cam->fov, aspect, cam->near, cam->far);
72}