gpt4 book ai didi

c++ - OpenGl:Arcball相机旋转问题

转载 作者:行者123 更新时间:2023-12-02 10:27:28 25 4
gpt4 key购买 nike

我需要安装Arcball摄像机。我也有类似的东西,但是它的弯曲度非常高(角度急剧变化,当向右/向左旋转时,相机会强烈地上下移动)。
这是我的源代码,您能告诉我我哪里出错了:

bool get_arcball_vec(double x, double y, glm::vec3& a) 
{

glm::vec3 vec = glm::vec3((2.0 * x) / window.getWidth() - 1.0, 1.0 - (2.0 * y) / window.getHeight(), 0.0);


if (glm::length(vec) >= 1.0)
{
vec = glm::normalize(vec);
}
else
{
vec.z = sqrt(1.0 - pow(vec.x, 2.0) - pow(vec.y, 2.0));
}
a = vec;

return true;
}

...
void onMouseMove(double x, double y) {
if (rightMouseButtonPressed) {
glm::vec3 a,b;
cur_mx = x;
cur_my = y;
if (cur_mx != last_mx || cur_my != last_my)
if (get_arcball_vec(last_mx, last_my, a) && get_arcball_vec(cur_mx, cur_my, b))
viewport.getCamera().orbit(a,b);

last_mx = cur_mx;
last_my = cur_my;

...

void Camera::orbit(glm::vec3 a, glm::vec3 b)
{
forward = calcForward();
right = calcRight();


double alpha = acos(glm::min(1.0f, glm::dot(b, a)));


glm::vec3 axis = glm::cross(a, b);


glm::mat4 rotationComponent = glm::mat4(1.0f);

rotationComponent[0] = glm::vec4(right, 0.0f);
rotationComponent[1] = glm::vec4(up, 0.0f);
rotationComponent[2] = glm::vec4(forward, 0.0f);


glm::mat4 toWorldCameraSpace = glm::transpose(rotationComponent);


axis = toWorldCameraSpace * glm::vec4(axis, 1.0);

glm::mat4 orbitMatrix = glm::rotate(glm::mat4(1.0f), (float)alpha, axis);


eye = glm::vec4(target, 1.0) + orbitMatrix * glm::vec4(eye - target, 1.0f);

up = orbitMatrix * glm::vec4(up, 1.0f);
}

最佳答案

我使用以下代码将2D鼠标位置映射到球体:

Vector3 GetArcBallVector(const Vector2f & mousePos) {

float radiusSquared = 1.0; //squared radius of the sphere

//compute mouse position from the centre of screen to interval [-half, +half]
Vector3 pt = Vector3(
mousePos.x - halfScreenW,
halfScreenH - mousePos.y,
0.0f
);

//if length squared is smaller than sphere diameter
//point is inside
float lengthSqr = pt.x * pt.x + pt.y * pt.y;

if (lengthSqr < radiusSquared){
//inside
pt.z = std::sqrtf(radiusSquared - lengthSqr);
}
else {
pt.z = 0.0f;
}

pt.z *= -1;
return pt;
}
为了计算旋转,我使用了最后一个( startPt)和当前( endPt)映射位置,然后执行以下操作:
Quaternion actRot = Quaternion::Identity();
Vector3 axis = Vector3::Cross(endPt, startPt);

if (axis.LengthSquared() > MathUtils::EPSILON) {
float angleCos = Vector3::Dot(endPt, startPt);
actRot = Quaternion(axis.x, axis.y, axis.z, angleCos);
}
我更喜欢在矩阵上使用 Quaternions,因为它们很容易相乘(用于累积旋转)和插值(用于某些欺骗)。

关于c++ - OpenGl:Arcball相机旋转问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/63695456/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com