-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathcamera.c
More file actions
106 lines (87 loc) · 2.75 KB
/
camera.c
File metadata and controls
106 lines (87 loc) · 2.75 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
#include "camera.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>
void Camera_updateScales(Camera *camera);
Rect Rect_set(float x, float y, float w, float h)
{
Rect rect = { .x = x, .y = y, .w = w, .h = h };
return rect;
}
Camera *Camera_new(int width, int height)
{
Camera *camera = NULL;
camera = (Camera *)calloc(1, sizeof(Camera));
if (!camera) goto ERROR_LABEL;
camera->m_width = width;
camera->m_height = height;
camera->m_xScale = 1.0f;
camera->m_yScale = 1.0f;
camera->m_worldView = Rect_set(0.f, 0.f, 16.f, 9.f);
Camera_updateScales(camera);
return camera;
ERROR_LABEL:
printf("ERROR - Camera_new()\n");
return NULL;
}
void Camera_free(Camera *camera)
{
if (!camera) return;
memset(camera, 0, sizeof(Camera));
free(camera);
}
void Camera_updateScales(Camera *camera)
{
Rect *worldView = &camera->m_worldView;
float viewWidth, viewHeight;
viewWidth = worldView->w;
viewHeight = worldView->h;
camera->m_xScale = camera->m_width / viewWidth;
camera->m_yScale = camera->m_height / viewHeight;
}
void Camera_zoom(Camera *camera, Vec2 center, float factor)
{
Rect *worldView = &camera->m_worldView;
worldView->x = center.x + (worldView->x - center.x) * factor;
worldView->y = center.y + (worldView->y - center.y) * factor;
worldView->w *= factor;
worldView->h *= factor;
Camera_updateScales(camera);
}
void Camera_worldToView(Camera *camera, Vec2 position, int *x, int *y)
{
*x = (int)((position.x - camera->m_worldView.x) * camera->m_xScale);
*y = (int)((position.y - camera->m_worldView.y) * camera->m_yScale);
*y = camera->m_height - *y;
}
void Camera_viewToWorld(Camera *camera, int x, int y, Vec2 *position)
{
y = camera->m_height - y;
float ratioX = (float)x / (float)camera->m_width;
float ratioY = (float)y / (float)camera->m_height;
position->x = camera->m_worldView.x + ratioX * (camera->m_worldView.w);
position->y = camera->m_worldView.y + ratioY * (camera->m_worldView.h);
}
void Camera_move(Camera *camera, Vec2 displacement)
{
camera->m_worldView.x += displacement.x;
camera->m_worldView.y += displacement.y;
}
void Camera_setView(Camera *camera, Rect *worldView)
{
#ifdef _WIN32
memcpy_s(&camera->m_worldView, sizeof(Rect), worldView, sizeof(Rect));
#else
memcpy(&camera->m_worldView, worldView, sizeof(Rect));
#endif
Camera_updateScales(camera);
}
void Camera_getView(Camera *camera, Rect *worldView)
{
#ifdef _WIN32
memcpy_s(worldView, sizeof(Rect), &camera->m_worldView, sizeof(Rect));
#else
memcpy(worldView, &camera->m_worldView, sizeof(Rect));
#endif
}