From ce6c0f11f347c54bde58fd45104f41163e70669f Mon Sep 17 00:00:00 2001 From: asxzq Date: Wed, 21 Jul 2021 20:51:39 +0800 Subject: [PATCH] =?UTF-8?q?=E5=9C=A8=E8=AF=B4=E6=98=8E=E4=B8=AD=E5=8A=A0?= =?UTF-8?q?=E5=85=A5=E4=BA=86=E4=B8=80=E5=AE=9A=E7=9A=84=E4=BB=A3=E7=A0=81?= =?UTF-8?q?=E5=B1=95=E7=A4=BA?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- extradocs/tech-mousepick.dox | 37 ++++++++++++++++++++++++++++++++++++ 1 file changed, 37 insertions(+) diff --git a/extradocs/tech-mousepick.dox b/extradocs/tech-mousepick.dox index 4c32c21..ff5ab8b 100644 --- a/extradocs/tech-mousepick.dox +++ b/extradocs/tech-mousepick.dox @@ -30,6 +30,21 @@ \f] +[widget.cpp](https://github.com/xdedss/gldemo/blob/main/widget.cpp#L119): + +~~~{.cpp} + glm::vec3 Widget::get_ray(int mousex, int mousey, int screenWidth, int screenHeight, glm::mat4 matModel, glm::vec4& init_point) { + glm::vec4 ndc((float)mousex * 2 / (float)screenWidth - 1, (float)mousey * 2 / (float)screenHeight - 1, 1.0f, 1.0f); + glm::vec4 pointView = glm::inverse(projection) * ndc; + pointView.y *= -1; + pointView /= pointView.w; + glm::vec4 rayView = pointView - glm::vec4(0, 0, 0, 1); + init_point = matModel * glm::inverse(view) * glm::vec4(0, 0, 0, 1); + glm::vec4 ray = glm::normalize(matModel * glm::inverse(view) * rayView); + return glm::vec3(ray.x, ray.y, ray.z); +} +~~~ + ### 在每个模型中拾取点 将射线和相机坐标转化到模型系下: @@ -55,6 +70,28 @@ **值得注意的是:**如果一直没有搜索到需要的点,则当搜索点射出模型范围,即跳出搜索。 +[widget.cpp](https://github.com/xdedss/gldemo/blob/main/widget.cpp#L191): + +~~~{.cpp} +while (true) { + float d = glm::l2Norm(glm::cross(glm::vec3(qpoint[0] - search.x, qpoint[1] - search.y, qpoint[2] - search.z), ray)); + if ( d < thre) { + getpoints.push_back(obj->localToWorld() * glm::vec4(search.x,search.y,search.z,1)); + hitObjects.push_back(obj); + pointIs.push_back(pointI); + break; + } + + float deltaDistance = glm::l2Norm(glm::vec3(qpoint[0] - search.x, qpoint[1] - search.y, qpoint[2] - search.z)) - thre; + search += deltaDistance * ray; + assert(glm::l2Norm(search) < 1e10); + if (sqrt(pow(init_point.x - search.x, 2) + pow(init_point.y - search.y, 2) + pow(init_point.z - search.z, 2)) > maxthre) + break; + pointI = pointcloud->nearestSearch({ search.x,search.y, search.z }); + qpoint = pointcloud->getVertex(pointI).position(); + } +~~~ + ### 选出最优点 将记录的每个点都转换到世界坐标系下,计算世界坐标系中各个选中点到摄像机的距离,取距离最小的点为最终选择点,该点所在的模型为最终选择的模型