- c - 在位数组中找到第一个零
- linux - Unix 显示有关匹配两种模式之一的文件的信息
- 正则表达式替换多个文件
- linux - 隐藏来自 xtrace 的命令
Edit3:我的问题与我预期的功能完全不同。我让代码保留下来,也许这对某人有帮助 :)(并且不要忘记调试!)。
我试图找到直线与三角形相交的 vector 。
当前状态:随机交叉,即使鼠标不在地板上和相机 View 依赖(lookat 矩阵)
步骤
取消投影鼠标坐标
我检查了 glm::unproject 和 gluUnproject 的源代码并创建了这个函数。
pixel::CVector3 pixel::CVector::unproject(
CVector2 inPosition,
pixel::CShape window,
pixel::matrix4 projectionMatrix,
pixel::matrix4 modelViewMatrix,
float depth
)
{
// transformation of normalized coordinates
CVector4 inVector;
inVector.x = (2.0f * inPosition.x) / window.width - 1.0f;
inVector.y = (2.0f * inPosition.y) / window.height - 1.0f;
inVector.z = 2.0f * depth - 1.0f;
inVector.w = 1.0f;
// multiply inverted matrix with vector
CVector4 rayWorld = pixel::CVector::multMat4Vec4(pixel::CMatrix::invertMatrix(projectionMatrix * modelViewMatrix), inVector);
CVector3 result;
result.x = rayWorld.x / rayWorld.w;
result.y = rayWorld.y / rayWorld.w;
result.z = rayWorld.z / rayWorld.w;
return result;
}
检查路口
pixel::CVector3 pixel::Ray::intersection(
Ray ray,
pixel::CVector3 v0,
pixel::CVector3 v1,
pixel::CVector3 v2
)
{
// compute normal
CVector3 a, b, n;
a = v1 - v0;
b = v2 - v0;
n = ray.direction.cross(b);
// find determinant
float det = a.dot(n);
if (det < 0.000001f)
{
std::cout << "Ray intersecting with backface triangles \n";
return pixel::CVector::vector3(0.0f, 0.0f, 0.0f);
}
det = 1.0f / det;
// calculate distance from vertex0 to ray origin
CVector3 s = ray.origin - v0;
float u = det * s.dot(n);
if (u < -0.000001f || u > 1.f + 0.000001f)
{
std::cout << "U: Intersection outside of the triangle!\n";
return pixel::CVector::vector3(0.0f, 0.0f, 0.0f);
}
CVector3 r = s.cross(a);
float v = det * ray.direction.dot(r);
if (v < -0.000001f || u + v > 1.f + 0.000001f)
{
std::cout << "V/U: Intersection outside of triangle!\n";
return pixel::CVector::vector3(0.0f, 0.0f, 0.0f);
}
// distance from ray to triangle
det = det * b.dot(r);
std::cout << "T: " << det << "\n";
CVector3 endPosition;
endPosition.x = ray.origin.x + (ray.direction.x * det);
endPosition.y = ray.origin.y + (ray.direction.y * det);
endPosition.z = ray.origin.z + (ray.direction.z * det);
return endPosition;
}
用法
if (event.button.button == SDL_BUTTON_RIGHT)
{
camera->setCameraActive();
float mx = event.motion.x;
float my = window->info.height - event.motion.y;
// ray casting
pixel::Ray ray;
std::cout << "\n\n";
// near
pixel::CVector3 rayNear = pixel::CVector::unproject(
pixel::CVector::vector2(mx, my),
pixel::CVector::shape2(window->info.internalWidth, window->info.internalHeight),
camera->camInfo.currentProjection,
camera->camInfo.currentView,
1.0f
);
// far
pixel::CVector3 rayFar = pixel::CVector::unproject(
pixel::CVector::vector2(mx, my),
pixel::CVector::shape2(window->info.internalWidth, window->info.internalHeight),
camera->camInfo.currentProjection,
camera->camInfo.currentView,
0.0f
);
// normalized direction results in the same behavior
ray.origin = cameraPosition;
ray.direction = pixel::CVector::normalize(rayFar- rayNear);
std::cout << "Raycast \n";
std::cout << "Mouse Position: " << mx << " - " << my << "\n";
std::cout << "Camera Position: " << ray.origin.x << " - " << ray.origin.y << " - " << ray.origin.z << "\n";
std::cout << "Ray direction: " << ray.direction.x << " - " << ray.direction.y << " - " << ray.direction.z << "\n";
pixel::CVector3 vertOne = pixel::CVector::vector3(0.0f, 0.0f, -300.0f);
pixel::CVector3 vertTwo = pixel::CVector::vector3(0.0f, 0.0f, 0.0f);
pixel::CVector3 vertThree = pixel::CVector::vector3(300.0f, 0.0f, 0.0f);
pixel::CVector3 vertFour = pixel::CVector::vector3(300.0f, 0.0f, -300.0f);
pixel::CVector3 rayHit = pixel::Ray::intersection(ray, vertOne, vertTwo, vertThree);
pixel::CVector3 rayHit2 = pixel::Ray::intersection(ray, vertThree, vertFour, vertOne);
std::cout << "Ray hit: " << rayHit.x << " - " << rayHit.y << " - " << rayHit.z << "\n";
std::cout << "Ray hit: " << rayHit2.x << " - " << rayHit2.y << " - " << rayHit2.z << "\n";
std::cout << "--------------------\n";
towerHouse->modelMatrix = pixel::CMatrix::translateMatrix(rayHit);
输出
因为我从未使用过 glm::unproject 或 gluUnproject,所以我不知道正常输出应该是什么样子,但我得到的结果如下:
光线方向:0.109035 -0.0380502 0.0114562
我觉得不对,但是根据其他来源(上面提到的)检查我的代码,我没有看到错误。
光线相交在某些特殊情况下有效(相机旋转),即使我不点击地板,我也会得到相交。从背面命中到三角形外部的交叉点输出也是如此。
所有这些错误看起来问题的主要根源是未投影。
有正确方向的提示吗?
最佳答案
这离这个问题的答案还差得很远,但这太复杂了,无法在评论或聊天中解释。
首先:
// near
pixel::CVector3 rayNear = pixel::CVector::raycast(
pixel::CVector::vector2(mx, my),
pixel::CVector::shape2(window->info.internalWidth, window->info.internalHeight),
camera->camInfo.currentProjection,
camera->camInfo.currentView,
1.0f // WRONG
);
// far
pixel::CVector3 rayFar = pixel::CVector::raycast(
pixel::CVector::vector2(mx, my),
pixel::CVector::shape2(window->info.internalWidth, window->info.internalHeight),
camera->camInfo.currentProjection,
camera->camInfo.currentView,
0.0f // WRONG
);
Near 在窗口空间中是 0.0,far 是 1.0(取决于深度范围,但是如果你改变了深度范围你应该已经知道了)。
在你的光线转换函数中,你有:
CVector3 result;
result.x = rayWorld.x / rayWorld.w;
result.y = rayWorld.y / rayWorld.w;
result.z = rayWorld.z / rayWorld.w;
有可能w == 0.0
,此时结果还不是一条射线...它是object-space(不是世界)中的一个位置。通常,您总是会使用行为良好的矩阵,但如果您看过 UnProject (...)
的正式实现,你会注意到他们处理 w == 0.0
的情况具有特殊的返回值或通过设置状态标志。
pixel::CVector3 vertOne = pixel::CVector::vector3(0.0f, 0.0f, -300.0f);
pixel::CVector3 vertTwo = pixel::CVector::vector3(0.0f, 0.0f, 0.0f);
pixel::CVector3 vertThree = pixel::CVector::vector3(300.0f, 0.0f, 0.0f);
pixel::CVector3 vertFour = pixel::CVector::vector3(300.0f, 0.0f, -300.0f);
这些顶点在什么坐标空间?大概是对象空间,这意味着如果您从相机的视点(在世界空间中定义)转换一条光线,该光线穿过远平面上的一个点,并尝试更频繁地测试与对象空间中的三角形的交点你会错过的。这是因为每个空间的原点、比例和旋转可能不同。在尝试此测试之前,您需要将这些点转换为世界空间(您的原始代码有一个 floor->modelMatrix
可以很好地用于此目的)。
关于c++ - 设置射线(原点,方向)和三角形交点(无glm),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20842623/
我试图弄清楚如何获取所有可见窗口的框架。我尝试了以下代码,但它仅适用于应用程序本身,其他窗口报告 {0,0,0,0} NSArray *windowArray = [NSWindow wind
左矩形=新矩形(0,0,WIDTH/9,HEIGHT);在此代码中,如果我增加宽度,为什么它看起来会进一步延伸到 JFrame 的左侧?如果我减少它为什么它会向右延伸?这不是像坐标平原一样工作吗?高度
假设我有一个 AffineTransform (transform) 并调用它的一堆方法。假设我旋转并平移它。然后我用它转换图形对象 (g2d): g2d.transform(transform);
我认为当你对物体施加力时,它会施加到 body 的原点(可能是质心)。现在我正在尝试创建类似俄罗斯方 block 的 block ,并通过应用 LinearPulse 使它们跳跃,如下所示: body
我正在阅读 Big Nerd Ranch 指南第 4 版,但在处理 View 和 View 层次结构的章节中,我遇到了一些与 View 来源有关的问题。 我已经在我的 View Controller
我想把原点放在中心,所以我做了: SetViewportOrgEx(hdc,width/2,height/2,NULL); (如下面的代码所示) 现在,在实现双缓冲后它似乎无法正常工作。任何想法为什么
当我的 Sprite 旋转原点固定在窗口的左上角时,我遇到了这个问题(与 sprite.Draw 和 sprite.Draw2D 相同)无论哪种方式,如果我改变旋转中心它仍然在左上角。我需要 Spri
有人告诉我,您可以通过以下方式向与当前 Git 分支名称相匹配的远程分支推送和 pull : git push origin HEAD 或 git pull origin HEAD 它以前一直对我有用
我正在使用自定义 View 和 Canvas 在屏幕上绘制对象。 View 位于距屏幕原点的 Y 偏移处。我想平移 Canvas ,然后绘制一个对象。但是,当我使用 setmatrix 平移 Canv
尝试拖动组。为什么 origin 在这里不起作用?注意到当你第一次点击它时它是如何跳跃的吗? JSFIDDLE基于此:http://bl.ocks.org/mbostock/1557377 var d
我正在尝试使用以下立方体的透视视角: http://jsfiddle.net/TrySpace/JvFSQ/5/ 但是我没有按照我的预期去做,我想要改变实际的视角。所以当transformOrigin
我的 OpenShift Origin 安装似乎有问题。 当我获得路由器的端点时,我得到以下信息: oc get endpoints --namespace=default --selector=ro
这是怎么做到的?我正在寻找 iOS7/8 解决方案。 KeyboardWillShow 并不令人满意,因为我需要在键盘实际显示之前根据键盘高度调整 View 大小。 最佳答案 keyboardWill
我正在 iframe 上监听其内容何时发生变化。当它发生时,我想知道内容的当前来源是什么。 我无法访问该内容,因为它违反了相同的域策略,但我只要根据网址或主机知道它显示的内容就可以了。 我可以通过 j
我一直致力于使用 CSS3 创建动画条形图。它在钢筋的两侧运行良好,但钢筋的顶部和底部一直存在问题。 我一直在通过 jQuery 改变它们的 css“高度”属性来缩放边,但我意识到这不是最好的方法。我
Edit3:我的问题与我预期的功能完全不同。我让代码保留下来,也许这对某人有帮助 :)(并且不要忘记调试!)。 我试图找到直线与三角形相交的 vector 。 当前状态:随机交叉,即使鼠标不在地板上和
我需要在原始 View 的坐标中计算 UIView subview 的可见 CGRect。如果比例为 1,我可以正常工作,但如果其中一个 super View 或 View 本身被缩放(收缩),可见的
这个问题类似于以前回答的问题 Fast interpolation over 3D array ,但无法解决我的问题。 我有一个维度为(时间、高度、纬度、经度)的 4D 数组,标记为 y.shape=
我正在制作自定义贴纸包。这是一个 iMessage 扩展应用程序。我继承了 UICollectionView 而不是使用基本的 MSMessagesViewController。因此,只有当我在展开
我使用 CGWindowListCopyWindowInfo 获取所有窗口的列表。它根据屏幕的 左上角 原点为我提供每个窗口的坐标。 如果我使用 NSWindow 的 setFrame 方法,坐标基于
我是一名优秀的程序员,十分优秀!