我试图编辑我的鼠标缩放功能,以便在3d世界中缩放鼠标位置,如果我需要,我可以获得鼠标的3d线,但不知道该怎么做。
目前我的变焦只是缩放到屏幕中心。
void CCamera::OnMouseWheel(float zDelta)
{
Position -= Reference;
if(zDelta < 0 && length(Position) < 500.0f)
{
Position += Position * 0.1f;
}
if(zDelta > 0 && length(Position) > 0.05f)
{
Position -= Position * 0.1f;
}
Position += Reference;
CalculateViewMatrix();
}
void CCamera::CalculateViewMatrix()
{
ViewMatrix = mat4x4(X.x, Y.x, Z.x, 0.0f, X.y, Y.y, Z.y, 0.0f, X.z, Y.z, Z.z, 0.0f, -dot(X, Position), -dot(Y, Position), -dot(Z, Position), 1.0f);
ViewMatrixInverse = inverse(ViewMatrix);
ViewProjectionMatrix = ProjectionMatrix * ViewMatrix;
ViewProjectionMatrixInverse = ViewMatrixInverse * ProjectionMatrixInverse;
}
答案 0 :(得分:0)
您可能需要对代码进行一些编辑,以确保所有内容都兼容,例如编辑视图。但是这里有一个来自我的项目的代码片段,它正是您所说的。我认为代码非常明显,
void modelDefinition::onMouseWheel(wxMouseEvent &event)
{
if(event.GetWheelRotation() != 0)
{
/* This section of the code was adapted from Agro2D */
_cameraX += (((2.0 / this->GetSize().GetWidth()) * (event.GetX() - this->GetSize().GetWidth() / 2.0)) / _zoomFactor) * (this->GetSize().GetWidth() / this->GetSize().GetHeight());
_cameraY += (-(2.0 / this->GetSize().GetHeight()) * (event.GetY() - this->GetSize().GetHeight() / 2.0)) / _zoomFactor;
if(!_preferences.getMouseZoomReverseState())
{
if(event.GetWheelRotation() > 0)
_zoomFactor *= pow(1.2, -(event.GetWheelDelta()) / 150.0);
else
_zoomFactor *= pow(1.2, (event.GetWheelDelta()) / 150.0);
}
else
{
if(event.GetWheelRotation() < 0)
_zoomFactor *= pow(1.2, -(event.GetWheelDelta()) / 150.0);
else
_zoomFactor *= pow(1.2, (event.GetWheelDelta()) / 150.0);
}
/* This will recalculate the new position of the mouse. Assuming that the mouse does not move at all during the process
* This also enables the feature where the zoom will zoom in/out at the position of the mouse */
_cameraX -= (((2.0 / this->GetSize().GetWidth()) * (event.GetX() - this->GetSize().GetWidth() / 2.0)) / _zoomFactor) * (this->GetSize().GetWidth() / this->GetSize().GetHeight());
_cameraY -= (-(2.0 / this->GetSize().GetHeight()) * (event.GetY() - this->GetSize().GetHeight() / 2.0)) / _zoomFactor;
}
this->Refresh();// This will force the canvas to experience a redraw event
}
我应该提一下,函数this->Refresh
只会导致我的屏幕更新。你的可能会有所不同。
此外,_cameraX和_cameraY存储openGL画布的偏移量。
这是我的画布的构造函数:
modelDefinition::modelDefinition(wxWindow *par, const wxPoint &point, const wxSize &size, problemDefinition &definition) : wxGLCanvas(par, wxID_ANY, NULL, point, size, wxBORDER_DOUBLE | wxBORDER_RAISED)
{
_geometryContext = new wxGLContext(this);
wxGLCanvas::SetCurrent(*_geometryContext);
_localDefinition = &definition;
_editor.setZoomFactorAddress(_zoomFactor);
glViewport(0, 0, (double)this->GetSize().GetWidth(), (double)this->GetSize().GetHeight());
glClearColor(1.0f, 1.0f, 1.0f, 1.0f);
glMatrixMode(GL_MODELVIEW);// The matrix mode specifies which matrix stack is the target for matrix operations
glLoadIdentity();// Initial value
glTranslated((float)this->GetSize().GetWidth() / 2.0f, (float)this->GetSize().GetHeight() / 2.0f, 0.0f);// This will move the camera to the center of the screen
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrtho(-1.0, 1.0, -1.0, 1.0, -1.0, 1.0);
GLenum error = glGetError();
if(error != GL_NO_ERROR)
{
// wxMessageBox("Error - " + gluErrorString(error));
return;
}
glMatrixMode(GL_MODELVIEW);
}
以下是处理更新我的观点位置的代码:
void modelDefinition::updateProjection()
{
// First, load the projection matrix and reset the view to a default view
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
//Reset to modelview matrix
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
/* This section will handle the translation (panning) and scaled (zooming).
* Needs to be called each time a draw occurs in order to update the placement of all the components */
if(_zoomFactor < 1e-9)
_zoomFactor = 1e-9;
if(_zoomFactor > 1e6)
_zoomFactor = 1e6;
glScaled(_zoomFactor / (this->GetSize().GetWidth() / this->GetSize().GetHeight()), _zoomFactor, 1.0);
glTranslated(-_cameraX, -_cameraY, 0.0);
}
答案 1 :(得分:0)
假设你有鼠标光标的3D坐标。撤消视口变换可以在NDC空间中获得这些坐标,也可以通过矩阵反转获得视图空间或模型空间坐标。现在,您有一个从相机到这些鼠标坐标的矢量(在您喜欢的任何空间)。最后一步是将摄像机跟随该矢量移动一定量,具体取决于鼠标滚轮的旋转。
如果你没有这些3D鼠标坐标......你有一个很大的问题,因为它无法从2D数据中获取3D信息。你缺乏“屏幕深度”,NDC空间中的Z值。