OpenGL漫游模型示例
【OpenGL漫游模型示例】OpenGL漫游模型示例:
#include
#include
#include
#include
#include "TrackballController.h"#define CIGAMA 0.1TrackballController* TrackballController::m_inst(0);
TrackballController* TrackballController::Inst()
{
if(!m_inst)
{
m_inst = new TrackballController();
}return m_inst;
}TrackballController::TrackballController(void)
{
mOldMouseX=0;
mOldMouseY=0;
m_vPtTrans = glm::vec2(0.0f, 0.0f);
//鼠标平移距离mRotationAangle=0;
//旋转角度
mDistanceToModelCenter = -2.0;
mRotationAaxis_Local=glm::vec3(1.0f, 0.0f, 0.0f);
//初始化视图、平移、旋转、缩放矩阵
mViewMatrix = mTranslationMatrix = mRotationMatrix = mScaleMatrix = glm::mat4(1.0);
mScrollSpeed = 0.0f;
m_fScale = 1.0f;
//缩放比例mMouseButton = -1;
//标记鼠标按下的键
spin_y_old = 0.0f;
//模型旋转角度初始化
}TrackballController::~TrackballController(void)
{
}void TrackballController::OnMouseMove(int x, int y)
{
//
/*if ( abs(x - mOldMouseX) < CIGAMA && abs(y - mOldMouseY) < CIGAMA )
{
return;
}*/if ( GLFW_MOUSE_BUTTON_LEFT == mMouseButton )
{
GLint viewport[4];
glGetIntegerv(GL_VIEWPORT,viewport);
//获取视口大小
//转换屏幕坐标为opengl坐标
glm::vec2 newMouse = scaleMouse( glm::vec2(x, y), glm::vec2(viewport[2],viewport[3]));
glm::vec2 oldMouse = scaleMouse( glm::vec2(mOldMouseX, mOldMouseY), glm::vec2(viewport[2],viewport[3]));
//计算平移距离
glm::vec2 d = (newMouse - oldMouse);
//y轴方向上移动的距离大于x轴方向上的距离时,平移
if (abs(mOldMouseX - x) < abs(mOldMouseY - y))
{
m_vPtTrans = d;
}
else//反之,旋转
{
float RotationAangle = 360*(x-mOldMouseX)/m_fWinWidth;
mRotationMatrix=glm::rotate(mRotationMatrix, RotationAangle,glm::vec3(0.0f,1.0f,0.0f) );
//spin_y_old = mRotationAangle;
//SetRotateParameter(newMouse,oldMouse);
}mOldMouseX = x;
mOldMouseY = y;
//更新模型矩阵
UpdateMatrix();
}
}void TrackballController::OnMouseScroll( int value )
{
if ( value > 0 )
{
// 推远模型
//mDistanceToModelCenter += mScrollSpeed;
m_fScale *= (1.0f+mScrollSpeed);
}
else if ( value < 0 && m_fScale >= mScrollSpeed)
{
// 拉近模型
//mDistanceToModelCenter -= mScrollSpeed;
m_fScale *= (1.0f-mScrollSpeed);
}//printf("value=https://www.it610.com/article/%d, mDistanceToModelCenter=%f/n",value, mDistanceToModelCenter);
UpdateMatrix();
}void TrackballController::onMouseButton( int action,int button ,int x,int y)
{
if (action != GLFW_PRESS)
{
mMouseButton = -1;
return;
}mMouseButton = button;
mOldMouseX = x;
mOldMouseY = y;
}void TrackballController::UpdateMatrix()
{
//mTranslationMatrix = glm::translate(glm::mat4(1.0f),glm::vec3(0.0f, 0.0f, mDistanceToModelCenter));
mScaleMatrix = glm::scale(glm::mat4(1.0f),glm::vec3(m_fScale, m_fScale, m_fScale));
mTranslationMatrix = glm::translate(mTranslationMatrix,glm::vec3(0.0f, m_vPtTrans.y, mDistanceToModelCenter));
mViewMatrix = mTranslationMatrix * mRotationMatrix * mScaleMatrix;
m_vPtTrans = glm::vec2(0.0f,0.0f);
mDistanceToModelCenter = 0.0f;
}glm::vec2 TrackballController::scaleMouse(glm::vec2 coords, glm::vec2 viewport)
{
/*return glm::vec2( static_cast(coords.x*2.0f) / static_cast(viewport.x) - 1.0f,
1.0f - static_cast(coords.y*2.0f) / static_cast(viewport.y) );
*/return glm::vec2( static_cast(coords.x) / static_cast(viewport.x),
1.0f - static_cast(coords.y) / static_cast(viewport.y) );
}glm::vec3 TrackballController::projectToSphere(glm::vec2 xy)
{
static const float sqrt2 = sqrtf(2.f);
glm::vec3 result;
float d = glm::length(xy);
float size_=2;
if (d < size_ * sqrt2 / 2.f)
{
result.z = sqrtf(size_ * size_ - d*d);
}
else
{
float t = size_ / sqrt2;
result.z = t*t / d;
}result.x = xy.x;
result.y = xy.y;
return glm::normalize(result);
}void TrackballController::SetRotateParameter(glm::vec2 newMouse,glm::vec2 oldMouse)
{
if (newMouse == oldMouse)
{
return;
}glm::vec3 p1 = projectToSphere(oldMouse);
glm::vec3 p2 = projectToSphere(newMouse);
glm::vec3 r_axis_world = glm::cross(p1, p2);
glm::vec3 d = 0.5f*(p1 - p2);
mRotationAangle= 180*glm::length(d);
glm::vec3 r_axis_local_end=glm::vec3(glm::inverse(mViewMatrix)*glm::vec4(r_axis_world,1));
glm::vec3 r_axis_local_start=glm::vec3(glm::inverse(mViewMatrix)*glm::vec4(0.0,0.0,0.0,1));
mRotationAaxis_Local=r_axis_local_end-r_axis_local_start;
mRotationMatrix=glm::rotate(mRotationMatrix, mRotationAangle,mRotationAaxis_Local );
//glm::vec3(0,1,0)
}//初始化场景初始参数
void TrackballController::SetInitialState( glm::vec3 CameraPos, glm::vec3 modelCenter, glm::vec3 modelSize)
{
m_fScale = 1.0f;
mTranslationMatrix = mRotationMatrix = mScaleMatrix = glm::mat4(1.0);
spin_y_old = 0;
mDistanceToModelCenter = -1.0 * glm::length( CameraPos - modelCenter );
mViewMatrix = glm::lookAt(CameraPos, modelCenter, glm::vec3(0.0f,1.0f,0.0f));
// 根据模型的尺寸,计算出鼠标滚轮对模型的推远与拉近的速度
float length = glm::length( modelSize );
mScrollSpeed = length * 0.1f;
UpdateMatrix();
}//自动旋转参数设置
void TrackballController::AutoRotateAngle( GLfloat fAngle )
{
mRotationMatrix=glm::rotate(mRotationMatrix, fAngle-spin_y_old,glm::vec3(0.0f,1.0f,0.0f) );
spin_y_old = fAngle;
UpdateMatrix();
}//设置视口大小
void TrackballController::ReSize( GLfloat fWidth,GLfloat fHeight )
{
m_fWinWidth = fWidth;
m_fWinHeight = fHeight;
}
推荐阅读
- Flutter的ListView
- 一般模型化关系——从模型是什么到如何起作用的基本答案
- Pytorch学习|sklearn-SVM 模型保存、交叉验证与网格搜索
- 旅途碎碎念
- jvm|【JVM】JVM08(java内存模型解析[JMM])
- 时间管理的任务模型
- 2.关于OpenGL|2.关于OpenGL 坐标系以及渲染流程
- 脊柱漫游之脊柱综合篇(五)
- 《DOM知识点总结》
- 目标管理模型的应用案例