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:
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?
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 posição da esfera
jo_pos3Df pos;
jo_rot3Df rot;
jo_rot3Df sphere_rotation = {0.0f, 0.0f, 0.0f}; // Inicializando a rotação 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?