使用 Jo 引擎在 Sega Saturn 上出现球体旋转问题

问题描述 投票:0回答:1

我正在尝试构建一个简单的低多边形球体,它可以使用Sega Saturn游戏手柄(类似于游戏Marble Madness)和Jo Engine(Sega Saturn的C引擎)来“玩”。我使用的代码如下:

#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();
}

结果是:

https://imgur.com/rytTvAq

如您所见,当我向左或向右移动游戏手柄时,低多边形球体并没有像球一样旋转。相反,它似乎笨拙地旋转或绕错误的轴旋转。

如何使用 Jo Engine 正确实现球体的旋转,使其根据游戏手柄输入像滚球一样以正确的方向平滑旋转?

c animation math rotation
1个回答
0
投票

不是一个大问题,您只需将 Y 旋转与 Z 旋转切换即可。为了在地面上旋转球(X/Z 轴),您不想使用垂直轴(在本例中为 Y 轴)。这是一个更改后的版本,以反映我之前提到的更改。没有太多改变,我只是将

delta_ry
重命名为
delta_rz
并将其添加到末尾的右侧向量元素中。

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_rz = 0.0f;

    switch (jo_get_input_direction_pressed(0))
    {
        case LEFT:
            delta_x = -movement_speed;
            delta_rz = rotation_speed;
            break;
        case RIGHT:
            delta_x = movement_speed;
            delta_rz = -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_rz = 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_rz = -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_rz = 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_rz = -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.rz += delta_rz;
}
最新问题
© www.soinside.com 2019 - 2025. All rights reserved.