1 #include "interface.hpp"
3 #include "geometry.hpp"
7 #include <glm/gtc/matrix_transform.hpp>
12 Interface::Interface(World &world)
14 , ctrl(world.Player())
15 , hud(world.BlockTypes())
20 , outline_transform(1.0f)
21 , move_velocity(0.005f)
22 , pitch_sensitivity(-0.0025f)
23 , yaw_sensitivity(-0.001f)
32 hud.Viewport(960, 600);
33 hud.Display(selection);
37 void Interface::Handle(const SDL_KeyboardEvent &event) {
38 switch (event.keysym.sym) {
40 front = event.state == SDL_PRESSED;
43 back = event.state == SDL_PRESSED;
46 left = event.state == SDL_PRESSED;
49 right = event.state == SDL_PRESSED;
52 up = event.state == SDL_PRESSED;
55 down = event.state == SDL_PRESSED;
59 if (event.state == SDL_PRESSED) {
64 if (event.state == SDL_PRESSED) {
71 void Interface::FaceBlock() {
72 selection.SetFace(Block::Face((selection.GetFace() + 1) % Block::FACE_COUNT));
73 hud.Display(selection);
76 void Interface::TurnBlock() {
77 selection.SetTurn(Block::Turn((selection.GetTurn() + 1) % Block::TURN_COUNT));
78 hud.Display(selection);
82 void Interface::Handle(const SDL_MouseMotionEvent &event) {
83 ctrl.RotateYaw(event.xrel * yaw_sensitivity);
84 ctrl.RotatePitch(event.yrel * pitch_sensitivity);
87 void Interface::Handle(const SDL_MouseButtonEvent &event) {
88 if (event.state != SDL_PRESSED) return;
90 if (event.button == 1) {
92 } else if (event.button == 2) {
94 } else if (event.button == 3) {
99 void Interface::PickBlock() {
100 if (!aim_chunk) return;
101 selection = aim_chunk->BlockAt(aim_block);
102 hud.Display(selection);
105 void Interface::PlaceBlock() {
106 if (!aim_chunk) return;
107 Chunk *mod_chunk = aim_chunk;
108 glm::vec3 next_pos = Chunk::ToCoords(aim_block) + aim_normal;
109 if (!Chunk::InBounds(next_pos)) {
110 mod_chunk = &world.Next(*aim_chunk, aim_normal);
111 next_pos -= aim_normal * glm::vec3(Chunk::Extent());
113 mod_chunk->BlockAt(next_pos) = selection;
114 mod_chunk->Invalidate();
117 void Interface::RemoveBlock() {
118 if (!aim_chunk) return;
119 aim_chunk->BlockAt(aim_block) = remove;
120 aim_chunk->Invalidate();
124 void Interface::Handle(const SDL_MouseWheelEvent &event) {
127 } else if (event.y > 0) {
132 void Interface::SelectNext() {
134 if (size_t(selection.type) >= world.BlockTypes().Size()) {
137 hud.Display(selection);
140 void Interface::SelectPrevious() {
142 if (selection.type <= 0) {
143 selection.type = world.BlockTypes().Size() - 1;
145 hud.Display(selection);
148 void Interface::Handle(const SDL_WindowEvent &event) {
149 if (event.event == SDL_WINDOWEVENT_RESIZED) {
150 hud.Viewport(event.data1, event.data2);
155 void Interface::Update(int dt) {
157 if (right && !left) {
158 vel.x = move_velocity;
159 } else if (left && !right) {
160 vel.x = -move_velocity;
163 vel.y = move_velocity;
164 } else if (down && !up) {
165 vel.y = -move_velocity;
167 if (back && !front) {
168 vel.z = move_velocity;
169 } else if (front && !back) {
170 vel.z = -move_velocity;
175 Ray aim = ctrl.Aim();
177 if (world.Intersection(aim, glm::mat4(1.0f), &aim_chunk, &aim_block, &dist, &aim_normal)) {
179 aim_chunk->Type(aim_chunk->BlockAt(aim_block)).FillOutlineModel(outline);
180 outline_transform = glm::scale(glm::mat4(1.0f), glm::vec3(1.0002f));
181 outline_transform = aim_chunk->Transform(world.Player().ChunkCoords());
182 outline_transform *= aim_chunk->ToTransform(aim_block);
190 void Interface::Render(DirectionalLighting &program) {
192 program.SetM(outline_transform);