当前位置: 首页 > news >正文

校园网站建设 德育免费学生html网页制作成品

校园网站建设 德育,免费学生html网页制作成品,软件开发流程以及简要描述,网站建设应列支什么科目文章目录QTOpenGL鼠标操作和模型控制鼠标拾取理论有点小复杂从鼠标计算射线第 0 步:2D 视口坐标第 1 步:3d归一化设备坐标第 2 步:4d齐次剪辑坐标第 3 步:4d眼(相机)坐标第 4 步:4d 世界坐标代码展示模型控制多模型加载…

文章目录

  • QT+OpenGL鼠标操作和模型控制
    • 鼠标拾取
      • 理论有点小复杂
        • 从鼠标计算射线
          • 第 0 步:2D 视口坐标
          • 第 1 步:3d归一化设备坐标
          • 第 2 步:4d齐次剪辑坐标
          • 第 3 步:4d眼(相机)坐标
          • 第 4 步:4d 世界坐标
      • 代码展示
    • 模型控制
      • 多模型加载
      • 选中模型
      • 模型旋转和移动

QT+OpenGL鼠标操作和模型控制

本篇完整工程见gitee:QtOpenGL 对应点的tag,由turbolove提供技术支持,您可以关注博主或者私信博主

鼠标拾取

  • 需要将世界坐标转换为视口坐标
void glReadPixels(GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, void *data);

理论有点小复杂

Mouse Picking with Ray Casting - Anton’s OpenGL 4 Tutorials (antongerdelan.net) 参考这篇文章

这部分不懂的话,暂时是没关系的,可以接着往下看代码,然后去看我的项目。

光线追踪法 从鼠标投射 3D 射线, 通过摄像机,进入场景,然后检查该光线是否与某个对象相交。

在这里插入图片描述

从鼠标计算射线

第 0 步:2D 视口坐标

range [0:width, height:0]

我们从鼠标光标坐标开始。这些是 2d,并且在视口坐标系中。首先我们需要获取鼠标 x,y 像素 坐标。

如果是QT的话,可以直接使用QT的mousePressEvent的evnet->pos();

这给了我们一个 x 在 0:width 和 y 从height:0 开始。请记住,0 位于此处的屏幕顶部,因此 y 轴方向与其他坐标系中的方向相反。

第 1 步:3d归一化设备坐标

range [-1:1, -1:1, -1:1]

下一步是将其转换为 3D 规范化设备坐标。 这应该在 x [-1:1] y [-1:1] 和 z [-1:1] 的范围内。我们有一个 x 和 y已经,所以我们缩放它们的范围,并反转y的方向。

float x = (2.0f * mouse_x) / width - 1.0f;
float y = 1.0f - (2.0f * mouse_y) / height;
float z = 1.0f;
vec3 ray_nds = vec3(x, y, z);
第 2 步:4d齐次剪辑坐标

range [-1:1, -1:1, -1:1, -1:1]

我们希望我们的射线的z指向前方 - 这通常是 OpenGL 样式中的负 z 方向。我们可以添加一个 ,这样我们就有一个 4d 向量w, 当然对于QT我们可以用QVector4D替换下面的vec4.

vec4 ray_clip = vec4(ray_nds.xy, -1.0, 1.0);
第 3 步:4d眼(相机)坐标

range [-x:x, -y:y, -z:z, -w:w]

通常,为了从眼睛空间进入剪辑空间,我们将向量乘以 投影矩阵。我们可以通过乘以这个的倒数来倒退 矩阵。

vec4 ray_eye = inverse(projection_matrix) * ray_clip;

现在,我们只需要取消x,y部分的投影,所以让我们手动设置z,w部分的意思是“向前,而不是一个点”。

ray_eye = vec4(ray_eye.xy, -1.0, 0.0);
第 4 步:4d 世界坐标

range [-x:x, -y:y, -z:z, -w:w]

同样,回到转换管道的另一个步骤。记住,我们手动为z分量指定了一个-1,这意味着我们的射线没有归一化。我们应该在使用它之前把它弄清楚。

vec3 ray_wor = (inverse(view_matrix) * ray_eye).xyz;
// don't forget to normalise the vector at some point
ray_wor = normalise(ray_wor);

这将为我们平衡上下、左右和前进组件。所以,假设我们的摄像机直接沿着-Z世界轴看,当鼠标在屏幕中心时,我们应该得到[0,0,-1],而当鼠标在屏幕上移动时,z值就不那么重要了。这将取决于纵横比,以及视图和投影矩阵中定义的视场。我们现在有一条射线,可以和世界空间中的曲面进行比较。

代码展示

// (传入参数为鼠标点击的坐标)计算世界坐标
QVector4D TurboOpenGLWidget::worldPositionFromMousePosition(const QPoint &pos)
{float winZ;glReadPixels((int)pos.x(), this->height() - (int)pos.y(),1,1,GL_DEPTH_COMPONENT, GL_FLOAT, &winZ);float x = (2.0 * pos.x()) / this->width() - 1.0f;float y = 1.0f - (2.0f * pos.y()) / this->height();float z = winZ * 2.0 -1.0f;float w = (2.0 * near_ * far_) / (far_ + near_ - z *(far_ - near_));QVector4D worldPosition(x, y, z, 1);worldPosition *= w;worldPosition = view.inverted() * projection.inverted() * worldPosition;return worldPosition;
}

模型控制

多模型加载

我们需要用之前模型加载那一块的代码,然后修改成可以加载多个模型的代码。

为此我们需要添加一个类型:

struct ModelInfo
{Model *model;QVector3D world_pos;float pitch;float roll;float yaw;bool is_selected;QString name;
}
QMap<QString, ModelInfo> models_;

然后需要将loadModel 修改为多模型的

void TurboOpenGLWidget::loadModel(const QString &file)
{makeCurrent();static int model_i = 0;Model *model = new Model(QOpenGLContext::currentContext()->versionFunctions<QOpenGLFunctions_4_5_Core>(),file.toStdString());camera_.setPosition(cameraPositionInit(model->max_y_, model->min_y_));models_["aa" + QString::number(model_i++)] = ModelInfo{model, QVector3D(0, 0, 0), 0.0, 0.0, 0.0, false, "aa"};doneCurrent();
}

之后需要对绘制的地方进行修改,遍历加载的模型然后绘制对应的模型。

选中模型

选中模型就是需要判断鼠标点击的位置和模型所在位置是否重叠,如果在一定范围内是重叠的则认为我们选中了该模型。

// 判断鼠标是否选中模型
void TurboOpenGLWidget::mousePressEvent(QMouseEvent *event)
{bool hasSelected=false;makeCurrent();if(event->buttons() & Qt::LeftButton){QVector4D worldPosition;worldPosition = worldPositionFromMousePosition(event->pos());emit sig_worldPosition(worldPosition);for(QMap<QString, ModelInfo>::iterator iter=models_.begin();iter!=models_.end();iter++){ModelInfo *modelInfo=&iter.value();float r=(modelInfo->model->max_y_-modelInfo->model->min_y_)/2;if(modelInfo->world_pos.distanceToPoint(QVector3D(worldPosition))<r&&!hasSelected){modelInfo->is_selected=true;hasSelected=true;}elsemodelInfo->is_selected=false;}}QWidget::mousePressEvent(event);
}

模型旋转和移动

// 双击时候选中模型
void TurboOpenGLWidget::mouseDoubleClickEvent(QMouseEvent *event)
{Q_UNUSED(event);if(model_moving_){//再次双击取消移动model_moving_=false;}elseforeach(auto modelInfo,models_){//双击启动移动if(modelInfo.is_selected==true)model_moving_=true;}QWidget::mouseDoubleClickEvent(event);
}
// 如果是移动的状态则移动模型void TurboOpenGLWidget::mouseMoveEvent(QMouseEvent *event)
{makeCurrent();static QPoint lastPos(width()/2, height()/2);if(model_moving_){for(auto iter=models_.begin();iter!=models_.end();iter++){ModelInfo *modelInfo=&iter.value();if(!modelInfo->is_selected) continue;modelInfo->world_pos=QVector3D(worldPositionFromMousePosition(event->pos());}}else if(event->buttons() & Qt::RightButton|| event->buttons() & Qt::LeftButton|| event->buttons() & Qt::MiddleButton){auto currentPos=event->pos();QPoint deltaPos=currentPos-lastPos;lastPos=currentPos;if(event->buttons() & Qt::RightButton)camera_.processMouseMovement(deltaPos.x(),-deltaPos.y());elsefor(auto iter=models_.begin();iter!=models_.end();iter++){ModelInfo *modelInfo=&iter.value();if(!modelInfo->is_selected) continue;if(event->buttons() & Qt::MiddleButton){modelInfo->roll+=deltaPos.x();}else if(event->buttons() & Qt::LeftButton){modelInfo->yaw+=deltaPos.x();modelInfo->pitch+=deltaPos.y();}}}doneCurrent();
}

在这里插入图片描述

http://www.khdw.cn/news/71156.html

相关文章:

  • 太原市网站建设公司网站建设哪家公司好
  • 域名如何购买快速优化关键词排名
  • 如何在社交网站上做视频推广方案seo关键词优化外包公司
  • 网站建设总结体会seo查询系统源码
  • 网站做301好不好电商网络营销
  • 镇江网站优化公司工作室最全磁力搜索引擎
  • 艺术培训学校系统网站怎么做深圳网站建设公司排名
  • 美妆网站建设国外免费网站域名服务器
  • 企业网站在ps里做吗网推拉新app推广接单平台
  • 做国际网站阿里巴巴小说百度风云榜
  • 昆明网络公司网站网络推广员的工作内容和步骤
  • 清理网站数据库百度提交入口的注意事项
  • python做直播网站在百度做广告多少钱
  • 怎么建立淘宝客网站营销策划公司
  • 学校网站的常规化建设官网优化 报价
  • 网站如何做seo新手怎么引流推广推广引流
  • 一家专门做母婴的网站广东seo
  • 高仿服装网站建设湖南seo优化服务
  • 网站建设个人简历全球搜钻是什么公司
  • 深圳品牌模板网站建设企业seo整站优化方案
  • 网站开发html书籍下载推广方案有哪些
  • 湖南网站建设 尖端磐石网络52种新颖的促销方式
  • 金华网站如何制作应用市场
  • 未备案的网站可以百度推广吗手机怎么建立网站
  • 供应长沙手机网站建设查询网站信息
  • 分类信息网站做推广站长网站优化公司
  • 山东网站建设公司电话seo建设
  • e4a怎么做点击跳转网站昆明seo工资
  • 体育视频网站建设seo网站推广杭州
  • 做网站文字要求网站alexa排名查询