3 #include "client/camera.h"
4 #include "client/client.h"
5 #include "client/client_player.h"
6 #include "client/client_terrain.h"
7 #include "client/cube.h"
8 #include "client/debug_menu.h"
9 #include "client/texture.h"
10 #include "environment.h"
13 struct ClientPlayer client_player;
15 static ClientEntity *player_entity;
16 static pthread_rwlock_t lock_player_entity;
18 // updat epos/rot box/eye functions
20 static void update_eye_pos_camera()
22 v3f64 pos = player_entity->data.pos;
23 v3f32 eye = player_entity->data.eye;
25 camera_set_position((v3f32) {pos.x + eye.x, pos.y + eye.y, pos.z + eye.z});
28 static void update_pos()
30 pthread_rwlock_rdlock(&player_entity->lock_box_eye);
31 update_eye_pos_camera();
32 pthread_rwlock_unlock(&player_entity->lock_box_eye);
34 debug_menu_changed(ENTRY_POS);
35 debug_menu_changed(ENTRY_HUMIDITY);
36 debug_menu_changed(ENTRY_TEMPERATURE);
39 static void update_rot()
41 camera_set_angle(player_entity->data.rot.x, player_entity->data.rot.y);
42 debug_menu_changed(ENTRY_YAW);
43 debug_menu_changed(ENTRY_PITCH);
46 static void update_transform()
48 client_entity_transform(player_entity);
51 static void send_pos_rot()
53 dragonnet_peer_send_ToServerPosRot(client, &(ToServerPosRot) {
54 .pos = player_entity->data.pos,
55 .rot = player_entity->data.rot,
61 static void recv_pos_rot()
71 static void on_add(ClientEntity *entity)
73 pthread_rwlock_wrlock(&lock_player_entity);
76 fprintf(stderr, "[error] attempt to re-add localplayer entity\n");
79 player_entity = refcount_grb(&entity->rc);
82 entity->type->update_nametag(entity);
85 pthread_rwlock_unlock(&lock_player_entity);
88 static void on_remove(ClientEntity *entity)
90 pthread_rwlock_wrlock(&lock_player_entity);
91 refcount_drp(&entity->rc);
93 pthread_rwlock_unlock(&lock_player_entity);
96 static void on_update_pos_rot(__attribute__((unused)) ClientEntity *entity)
101 static void on_update_box_eye(__attribute__((unused)) ClientEntity *entity)
103 pthread_rwlock_rdlock(&lock_player_entity);
104 update_eye_pos_camera();
105 pthread_rwlock_unlock(&lock_player_entity);
108 static void on_update_nametag(ClientEntity *entity)
110 if (entity->data.nametag) {
111 free(entity->data.nametag);
112 entity->data.nametag = NULL;
116 static void on_transform(ClientEntity *entity)
118 entity->model->root->rot.y = entity->model->root->rot.z = 0.0f;
122 void client_player_init()
124 client_player.movement = (ToClientMovement) {
132 client_entity_types[ENTITY_LOCALPLAYER] = (ClientEntityType) {
134 .remove = &on_remove,
136 .update_pos_rot = &on_update_pos_rot,
137 .update_box_eye = &on_update_box_eye,
138 .update_nametag = &on_update_nametag,
139 .transform = &on_transform,
142 client_entity_types[ENTITY_PLAYER] = (ClientEntityType) {
146 .update_pos_rot = NULL,
147 .update_box_eye = NULL,
148 .update_nametag = NULL,
149 .transform = &on_transform,
152 pthread_rwlock_init(&client_player.lock_movement, NULL);
154 player_entity = NULL;
155 pthread_rwlock_init(&lock_player_entity, NULL);
158 // called on shutdown
159 void client_player_deinit()
161 pthread_rwlock_destroy(&client_player.lock_movement);
162 pthread_rwlock_destroy(&lock_player_entity);
165 ClientEntity *client_player_entity()
167 ClientEntity *entity = NULL;
169 pthread_rwlock_rdlock(&lock_player_entity);
171 entity = refcount_grb(&player_entity->rc);
172 pthread_rwlock_unlock(&lock_player_entity);
177 void client_player_update_pos(ClientEntity *entity)
179 pthread_rwlock_rdlock(&lock_player_entity);
181 if (entity == player_entity) {
186 pthread_rwlock_unlock(&lock_player_entity);
189 void client_player_update_rot(ClientEntity *entity)
191 pthread_rwlock_rdlock(&lock_player_entity);
193 if (entity == player_entity) {
198 pthread_rwlock_unlock(&lock_player_entity);
202 // create mesh object and info hud
203 void client_player_add_to_scene()
205 client_player.obj = object_create();
206 client_player.obj->scale = (v3f32) {0.6, 1.75, 0.6};
207 client_player.obj->visible = false;
209 object_set_texture(client_player.obj, texture_load(RESSOURCE_PATH "textures/player.png", true));
211 for (int f = 0; f < 6; f++) {
212 for (int v = 0; v < 6; v++) {
213 Vertex3D vertex = cube_vertices[f][v];
214 vertex.position.y += 0.5;
215 object_add_vertex(client_player.obj, &vertex);
219 pthread_rwlock_rdlock(&client_player.rwlock);
221 pthread_rwlock_unlock(&client_player.rwlock);
223 debug_menu_update_yaw();
224 debug_menu_update_pitch();
229 void client_player_jump()
231 ClientEntity *entity = client_player_entity();
235 pthread_rwlock_rdlock(&entity->lock_pos_rot);
236 pthread_rwlock_rdlock(&entity->lock_box_eye);
240 client_player.movement.collision,
243 &client_player.velocity
245 client_player.velocity.y += client_player.movement.jump;
247 pthread_rwlock_unlock(&entity->lock_box_eye);
248 pthread_rwlock_unlock(&entity->lock_pos_rot);
250 refcount_drp(&entity->rc);
253 // to be called every frame
254 void client_player_tick(f64 dtime)
256 ClientEntity *entity = client_player_entity();
260 pthread_rwlock_rdlock(&client_player.lock_movement);
261 pthread_rwlock_wrlock(&entity->lock_pos_rot);
262 pthread_rwlock_rdlock(&entity->lock_box_eye);
266 client_player.movement.collision,
269 &client_player.velocity,
272 client_player.movement.flight ? 0.0 : -client_player.movement.gravity,
277 client_player_update_pos(entity);
279 pthread_rwlock_unlock(&entity->lock_box_eye);
280 pthread_rwlock_unlock(&entity->lock_pos_rot);
281 pthread_rwlock_unlock(&client_player.lock_movement);
283 refcount_drp(&entity->rc);