I'm trying to build a simple low-poly sphere... that is "playable" using a Sega Saturn gamepad (similar to the game Marble Madness) with Jo Engine... The code I'm using is as follows:
| | | #include <jo/jo.h> #include "sphere.h" jo_camera cam; jo_img_8bits floor_image; jo_palette image_pal; jo_pos3Df sphere_position = {0, 50, 0}; // Inicializando a posio da esfera jo_pos3Df pos; jo_rot3Df rot; jo_rot3Df sphere_rotation = {0.0f, 0.0f, 0.0f}; // Inicializando a rotao da esfera void my_draw(void) { jo_printf(12, 1, "*Simple 3D demo*"); jo_3d_camera_look_at(&cam); jo_3d_push_matrix(); { jo_3d_translate_matrixf(sphere_position.x, sphere_position.y, sphere_position.z); jo_3d_rotate_matrix_rad(sphere_rotation.rx, sphere_rotation.ry, sphere_rotation.rz); display_sphere_mesh(); jo_3d_set_mesh_texture(&Meshsphere, 0); } jo_3d_pop_matrix(); } void my_gamepad(void) { const float movement_speed = 1.0f; const float rotation_speed = JO_DEG_TO_RAD(5.0f); const float DIAGONAL_FACTOR = 0.707f; //(1/sqrt(2)) float delta_x = 0.0f; float delta_z = 0.0f; float delta_rx = 0.0f; float delta_ry = 0.0f; switch (jo_get_input_direction_pressed(0)) { case LEFT: delta_x = -movement_speed; delta_ry = -rotation_speed; break; case RIGHT: delta_x = movement_speed; delta_ry = rotation_speed; break; case UP: delta_z = movement_speed; delta_rx = -rotation_speed; break; case DOWN: delta_z = -movement_speed; delta_rx = rotation_speed; break; case UP_LEFT: delta_x = -movement_speed * DIAGONAL_FACTOR; delta_z = movement_speed * DIAGONAL_FACTOR; delta_ry = -rotation_speed * DIAGONAL_FACTOR; delta_rx = -rotation_speed * DIAGONAL_FACTOR; break; case UP_RIGHT: delta_x = movement_speed * DIAGONAL_FACTOR; delta_z = movement_speed * DIAGONAL_FACTOR; delta_ry = rotation_speed * DIAGONAL_FACTOR; delta_rx = -rotation_speed * DIAGONAL_FACTOR; break; case DOWN_LEFT: delta_x = -movement_speed * DIAGONAL_FACTOR; delta_z = -movement_speed * DIAGONAL_FACTOR; delta_ry = -rotation_speed * DIAGONAL_FACTOR; delta_rx = rotation_speed * DIAGONAL_FACTOR; break; case DOWN_RIGHT: delta_x = movement_speed * DIAGONAL_FACTOR; delta_z = -movement_speed * DIAGONAL_FACTOR; delta_ry = rotation_speed * DIAGONAL_FACTOR; delta_rx = rotation_speed * DIAGONAL_FACTOR; break; case NONE: return; } sphere_position.x += delta_x; sphere_position.z += delta_z; sphere_rotation.rx += delta_rx; sphere_rotation.ry += delta_ry; } void load_floor_texture(void) { pos.x = 800.0; pos.y = 800.0; pos.z = -35.0; rot.rx = JO_DEG_TO_RAD(90.0); rot.ry = JO_DEG_TO_RAD(0.0); rot.rz = JO_DEG_TO_RAD(0.0); jo_core_tv_off(); jo_enable_background_3d_plane(JO_COLOR_Black); jo_tga_8bits_loader(&floor_image, JO_ROOT_DIR, "FLOOR.TGA", 0); jo_background_3d_plane_a_img(&floor_image, image_pal.id, true, true); jo_core_tv_on(); } jo_palette *my_tga_palette_handling(void) { jo_create_palette(&image_pal); return (&image_pal); } void draw_3d_planes(void) { jo_3d_push_matrix(); { jo_3d_rotate_matrix_rad(rot.rx, rot.ry, rot.rz); jo_3d_translate_matrixf(pos.x, pos.y, pos.z); jo_background_3d_plane_a_draw(true); } jo_3d_pop_matrix(); } void jo_main(void) { jo_core_init(JO_COLOR_Black); jo_set_tga_palette_handling(my_tga_palette_handling); jo_sprite_add_tga(JO_ROOT_DIR, "ROCK.TGA", JO_COLOR_Transparent); load_floor_texture(); jo_3d_camera_init(&cam); jo_core_add_callback(my_draw); jo_core_add_callback(my_gamepad); jo_core_add_callback(draw_3d_planes); jo_core_run(); } |
the result is: https://imgur.com/rytTvAq... As you can see, the low-poly sphere is not rotating like a ball when I move the gamepad to the left or right. Instead, it seems to pivot awkwardly or rotate around the wrong axis. How can I properly implement rotation for a sphere using Jo Engine so that it rotates smoothly like a rolling ball in the correct direction based on the gamepad input? |