Home Game Development How do I repair my planet-facing digital camera?

How do I repair my planet-facing digital camera?

0
How do I repair my planet-facing digital camera?

[ad_1]

Summary

I’m having bother implementing a digital camera controller appropriate for first individual use round a planet.

The digital camera must be oriented accurately based on gravity (vector from digital camera place to planet middle). I need the look route to remain the identical relative to the planet’s floor. This signifies that the look route ought to transfer because the orientation modifications, even when the mouse is just not touched. Not doing this might be complicated for the participant.

Attempts

I’ve tried many alternative options. The largest downside is that the transformation I take advantage of to go between the world up vector (0,1,0) and the digital camera’s orientation leads to spinning on the south pole. The digital camera yaws of it is personal accord because the orientation modifications close to the south pole. If you keep nonetheless and go searching, it is wonderful, however for every body the orientation change, the digital camera rotates itself. I’ve remoted it to the pitch a part of the digital camera route (in the event you take away the pitch fully, the digital camera yaw behaves wonderful).

As far as I can perceive it up to now, it has one thing to do with this: think about you are on the equator, going through the north pole. You stroll to the north pole with out altering route. How you progress proper, all the best way all the way down to the equator. At this level, you might be going through alongside the equator, regardless of having by no means purposefully modified route.

I do not want theoretical assistance on how cameras work, or how matrices or quaternions work. I need assistance from math wizards or skilled individuals.

Code

Each part represents a distinct try at an answer. There’s a remark above every describing what the problems are. (I’m completely happy to scrap all this code; I simply need one thing that works.)

void Camera::set_angles_advanced(float horizontal, float vertical) {
glm::mat4 trans;
float issue = 1.0f;
float real_vertical = vertical;
m_horizontal += horizontal;
m_vertical += vertical;

whereas (m_horizontal > TWO_PI) {
    m_horizontal -= TWO_PI;
}

whereas (m_horizontal < -TWO_PI) {
    m_horizontal += TWO_PI;
}

if (m_vertical > MAX_VERTICAL) {
    vertical -= m_vertical - MAX_VERTICAL;

    if (vertical < 0) {
        vertical = 0;
    }

    m_vertical = MAX_VERTICAL;
}
else if (m_vertical < -MAX_VERTICAL) {
    vertical -= m_vertical - MAX_VERTICAL;

    if (vertical > 0) {
        vertical = 0;
    }

    m_vertical = -MAX_VERTICAL;
}

// -------------------- south pole rotation
/*glm::quat rotation;

if (m_orientation != glm::vec3(0.0f, 1.0f, 0.0f)) {
    glm::vec3 axis = glm::normalize(glm::cross(glm::vec3(0.0f, 1.0f, 0.0f), m_orientation));
    rotation = glm::rotate(rotation, acosf(m_orientation.y) * ONEEIGHTY_PI, axis);
}

rotation = glm::rotate(rotation, m_horizontal * ONEEIGHTY_PI, glm::vec3(0.0f, 1.0f, 0.0f));
rotation = glm::rotate(rotation, m_vertical * ONEEIGHTY_PI, glm::vec3(1.0f, 0.0f, 0.0f));

m_direction = glm::vec3(rotation * glm::vec4(0.0f, 0.0f, -1.0f, 0.0f));*/



// --------------------- south pole rotation
/*glm::vec3 tmp = m_orientation;
float look_factor = 1.0f;
float addition = 0.0f;

if (tmp.y < 0.0f) {
    tmp.y *= -1.0f;
    look_factor = -1.0f;
    addition = 180.0f;
}

glm::mat4 yaw = glm::rotate(glm::mat4(), m_horizontal * ONEEIGHTY_PI, m_orientation);
glm::mat4 pitch = glm::rotate(glm::mat4(), m_vertical * -ONEEIGHTY_PI, glm::vec3(1.0f, 0.0f, 0.0f));

if (tmp != glm::vec3(0.0f, 1.0f, 0.0f)) {
    glm::vec3 axis = glm::normalize(glm::cross(glm::vec3(0.0f, 1.0f, 0.0f), tmp));
    pitch = glm::rotate(glm::mat4(), acosf(tmp.y) * ONEEIGHTY_PI * look_factor + addition, axis) * pitch;
}

glm::mat4 cam = yaw * pitch;

m_direction = glm::vec3(cam[2]);*/

// -------------------- oscillation when wanting near vertical, vertical vary capped
/*glm::mat4 yaw_matrix = glm::rotate(glm::mat4(), m_horizontal * ONEEIGHTY_PI, m_orientation);

m_right = glm::cross(m_direction, m_orientation);

glm::mat4 pitch_matrix = glm::rotate(glm::mat4(), m_vertical * -ONEEIGHTY_PI, glm::normalize(m_right));

glm::mat4 camera_matrix = pitch_matrix * yaw_matrix;
m_direction = glm::vec3(camera_matrix[2]);*/


// --------------------- oscillation when wanting near vertical, vertical vary all the time capped to -90,90
/*glm::mat4 yaw = glm::rotate(glm::mat4(), m_horizontal * ONEEIGHTY_PI, m_orientation);
glm::mat4 pitch = glm::rotate(glm::mat4(), m_vertical * -ONEEIGHTY_PI, m_right);

glm::mat4 cam = pitch * yaw;

m_right = glm::vec3(cam[0]);
m_up = glm::vec3(cam[1]);
m_direction = glm::vec3(cam[2]);*/



// ----------------------- south pole rotation
/*glm::dvec3 dir = glm::dvec3(cos(m_vertical) * sin(m_horizontal),
    sin(m_vertical),
    cos(m_vertical) * cos(m_horizontal));

glm::vec3 tmp = m_orientation;
tmp.y = fabs(tmp.y);

glm::dmat4 dtrans;
float angle;

if (glm_sq_distance(tmp, glm::vec3(0.0f, 1.0f, 0.0f)) > 0.001f) {
    glm::vec3 axis = glm::normalize(glm::cross(glm::vec3(0.0f, 1.0, 0.0f), m_orientation));
    angle = acos(m_orientation.y) * ONEEIGHTY_PI;
    dtrans = glm::rotate(glm::mat4(), angle, axis);
}
else if (m_orientation.y < 0.0f) {
    issue = -1.0f;
}

dir = glm::dvec3(dtrans * glm::dvec4(dir.x, dir.y, dir.z, 0.0f));
m_direction = glm::vec3(dir);*/


m_dir_horizontal_norm = glm::normalize(m_direction - glm_project(m_direction, m_orientation));

m_view = glm::lookAt(m_position, m_position + m_direction, m_orientation);
m_vp = m_perspective * m_view;
}

Edit: Solved. Complete code for future reference. I would not want my trials with this downside upon anybody.

glm::mat4 trans;
float issue = 1.0f;
float real_vertical = vertical;
m_horizontal += horizontal;
m_vertical += vertical;

whereas (m_horizontal > TWO_PI) {
    m_horizontal -= TWO_PI;
}

whereas (m_horizontal < -TWO_PI) {
    m_horizontal += TWO_PI;
}

if (m_vertical > MAX_VERTICAL) {
    m_vertical = MAX_VERTICAL;
}
else if (m_vertical < -MAX_VERTICAL) {
    m_vertical = -MAX_VERTICAL;
}

glm::quat world_axes_rotation = glm::angleAxis(m_horizontal * ONEEIGHTY_PI, glm::vec3(0.0f, 1.0f, 0.0f));
world_axes_rotation = glm::normalize(world_axes_rotation);
world_axes_rotation = glm::rotate(world_axes_rotation, m_vertical * ONEEIGHTY_PI, glm::vec3(1.0f, 0.0f, 0.0f));

m_pole = glm::normalize(m_pole - glm::dot(m_orientation, m_pole) * m_orientation);

glm::mat4 local_transform;

local_transform[0] = glm::vec4(m_pole.x, m_pole.y, m_pole.z, 0.0f);
local_transform[1] = glm::vec4(m_orientation.x, m_orientation.y, m_orientation.z, 0.0f);
glm::vec3 tmp = glm::cross(m_pole, m_orientation);
local_transform[2] = glm::vec4(tmp.x, tmp.y, tmp.z, 0.0f);
local_transform[3] = glm::vec4(m_position.x, m_position.y, m_position.z, 1.0f);

world_axes_rotation = glm::normalize(world_axes_rotation);
m_view = local_transform * glm::mat4_cast(world_axes_rotation);
m_direction = -1.0f * glm::vec3(m_view[2]);
m_up = glm::vec3(m_view[1]);
m_right = glm::vec3(m_view[0]);

m_view = glm::inverse(m_view);

[ad_2]

LEAVE A REPLY

Please enter your comment!
Please enter your name here