Java 在三维块世界中,计算块/面摄影机/光标的重点是

Java 在三维块世界中,计算块/面摄影机/光标的重点是,java,3d,Java,3d,我一直在用minecraft克隆游戏自学3d编程。我有一个无限映射,以16x16x64块的块加载 当玩家(摄像机)四处走动时,摄像机(游戏光标)的中心指向一个区块。我试图找出如何确定用户指向哪个块 我有一个带有3d坐标、偏航、俯仰的相机,所以我知道用户在看什么 我曾尝试寻找坐标,该坐标将位于从该原点绘制的“直线”上,但这并不能解释相机何时指向块的边/角,系统将不知道 我试着在网上寻找一些例子,但我没有发现任何有用的东西,有一些例子,但它们有很多缺陷,而且文档记录也很差 如何正确地将相机的中心位置

我一直在用minecraft克隆游戏自学3d编程。我有一个无限映射,以16x16x64块的块加载

当玩家(摄像机)四处走动时,摄像机(游戏光标)的中心指向一个区块。我试图找出如何确定用户指向哪个块

我有一个带有3d坐标、偏航、俯仰的相机,所以我知道用户在看什么

我曾尝试寻找坐标,该坐标将位于从该原点绘制的“直线”上,但这并不能解释相机何时指向块的边/角,系统将不知道

我试着在网上寻找一些例子,但我没有发现任何有用的东西,有一些例子,但它们有很多缺陷,而且文档记录也很差

如何正确地将相机的中心位置转换为它所看到的块/面

“我试着寻找坐标,它位于从原点绘制的一条“线”上,但这不能解释相机何时指向块的边缘/角落,系统无法知道。”。。“如何正确地将相机的中心位置转换为它所看到的块/面?”

OpenGL程序进行鼠标拾取的两种常见方式是颜色拾取或光线投射。这听起来像是你在尝试迭代你的块网格来获得一个有点不寻常的位置,或者想做一些类似光线投射的事情

光线投射是从摄影机->通过鼠标->到屏幕上的一个平面->将屏幕空间映射到世界空间->与场景碰撞-/code>

“我曾尝试在网上查找示例,但没有发现任何有用的内容,有几个示例,但它们都有很多缺陷,文档记录也很差。”

以下是一些光线投射教程的链接


注意如果您发现任何较旧的OpenGL教程,它们可能会提到“选择模式”或“名称堆栈”,这非常旧,不要使用它-。

首先,关于相机高度问题的注意:确保相机位置和指向ModelView矩阵,而不是投影矩阵。投影矩阵只能用于补偿人眼相对于真实屏幕(平截体)的位置。“缩放”是一个棘手的问题

前面答案的链接显示了如何从相机获取视线向量,查看模型空间(屏幕中心或十字线)

把这条视线向量称为l。它应该是一个单位列向量,以与块相同的坐标系表示。 就偏航(h表示航向)和俯仰(p)而言,如果+y向上,且0偏航具有-z向前和x向右,则l的(x,y,z)分量为:l=(cp*sh,sp,-cp*ch),其中cp表示cos(俯仰),sh表示sin(偏航=航向),等等

我们想要相机前面最近的立方体,它的任何面都被相机的光线沿l方向刺穿

在每一步中,您都要排除立方体来考虑,以节省吞吐量。OpenGL有一种方法可以判断原语(如三角形)是否写入深度缓冲区(可见)。如果你想要,你可以渲染两次,并且注意在第二遍的**或相等规则下写入深度缓冲区的立方体,并且只考虑那些立方体。如果不是,你可以跳过它,只考虑所有立方体。< /P>

如果你已经选择了16x16x64块的有限数量,你可以考虑大立方体块块(例如16 ^ 3)作为一个整体来拒绝,首先使用粗略的方法为单个块,接受阈值按比例增加16。 假设一个立方体是2x2x2单位(在x,y,z的中心+/-1处的角)。 摄像机“眼睛”位于位置e。 对于中心位于c的每个立方体,计算从眼睛的位移:d=c-e。 计算l方向上的距离:u=d点l。(即u=dx*lx+dy*ly+dz*lz) 如果u<-1.5(立方体完全位于摄像机后面),则丢弃此立方体。 从光线计算立方体中心的垂直位移向量:p=d-u*l

粗略检查: 如果p分量的绝对值之和大于3,则丢弃立方体。 这是一种快速检查,将消除除非常接近视线光线的立方体以外的所有立方体。
按从最小到最大的u对所有剩余的多维数据集进行排序。
第一个通过以下详细检查的人获胜

详细检查: 在处理任何立方体之前,首先必须根据l向量进行一些准备: 指定所有立方体通用的8个角顶点编号和位置向量,如下所示:

no  x  y  z
1   1  1  1
2   1 -1  1
3   1 -1 -1
4   1  1 -1
5  -1  1  1
6  -1 -1  1
7  -1 -1 -1
8  -1  1 -1
接下来,根据l的x、y、z分量的符号,选择形成精确碰撞的二维凸包的4个或6个顶点,如肉眼所见:

xyz Vertices (cyclic)
+++ 234856
--- 658432 (reverse order of +++)
++- 123785 (6->1, 4->7) of +++
--+ 587321 reverse order of ++-
+-+ 156734
-+- 437651 reverse of +-+
-++ 148762
+-- 267841 reverse of -++
退化情况,当l的任意2个x、y或z分量为零时:

+00 1234
-00 4321
0+0 1485
0-0 5841
00+ 1562
00- 2651
根据您的视线l矢量,选择上述14个外壳中的一个。然后对剩余的每个范围排序的多维数据集执行以下详细测试。 现在,对于要在该外壳内的光线,意味着立方体的至少一个面被刺穿(或至少被擦伤),光线必须位于由外壳的后续顶点对(6或4次检查)指定的每个线段的左侧,因为我们逆时针绕外壳旋转。这与要求船体段的叉积与从该段任一端到射线的位移具有负投影或零投影到视线向量l的要求相同: 从左到右成对取外壳顶点,从最后一个到第一个环绕,最左边的顶点指定为“a”,右边的顶点指定为“b”,
((b-a)cross(p-a))dotl有一个名为CraftMania的Minecraft类型的克隆,在


可能有一些关于3D拾取的文档信息。

您使用的是什么技术?这是纯Java还是您也在使用OpenGL?Java和LWJGL,所以OpenGL。从那以后我找到了一份工作