Minecraft 克隆的最佳盒子选择方法

2024-02-21

我正在制作 Minecraft 克隆作为我的第一个 OpenGL 项目,但卡在了框选择部分。做出可靠的盒子选择的最佳方法是什么?

我一直在研究一些 AABB 算法,但它们都没有足够好地解释它们到底做了什么(尤其是经过超级调整的算法),而且我不想使用我不理解的东西。

由于世界是由立方体组成的,我使用八叉树来消除光线投射计算上的一些压力,基本上我唯一需要的是这个函数:

float cube_intersect(Vector ray, Vector origin, Vector min, Vector max)
{
    //???
}

射线和原点很容易获得

Vector ray, origin, point_far;
double mx, my, mz;

gluUnProject(viewport[2]/2, viewport[3]/2, 1.0, (double*)modelview, (double*)projection, viewport, &mx, &my, &mz);
point_far = Vector(mx, my, mz);
gluUnProject(viewport[2]/2, viewport[3]/2, 0.0, (double*)modelview, (double*)projection, viewport, &mx, &my, &mz);
origin = Vector(mx, my, mz);
ray = point_far-origin;

最小值和最大值是立方体的对角。

考虑到我必须检查的立方体数量,即使使用八叉树,我什至不确定这是正确的方法。

我也尝试过gluProject,它有效,但非常不可靠,并且没有给我选定的立方体面。


EDIT

这就是我所做的:用射线计算空间中的位置:

float t = 0;
for(int i=0; i<10; i++)
{
    Vector p = ray*t+origin;
    while(visible octree)
    {
        if(p inside octree)
        {
            // then call recursive function until a cube is found
            break;
        }
        octree = octree->next;
    }
    if(found a cube)
    {
        break;
    }
    t += .5;
}

实际上它的速度快得惊人,并且在第一个找到的立方体之后停止。

正如您所看到的,光线必须穿过多个八叉树才能找到立方体(实际上是空间中的位置) - 屏幕中间有一个十字准线。增量步长越低,选择越精确,但速度也越慢。


使用盒子作为原语在内存需求和处理能力方面是过度的。 立方体非常适合渲染,即使在那里,您也可以找到更高级的算法,为您提供更好的最终图像(行进立方体)。从这个意义上说,《我的世界》的图形非常原始,因为体素渲染已经存在很长时间并且已经取得了重大进展。

基本上,您应该利用所有盒子的间距相等且大小相同的事实。这些称为体素。 与您所拥有的宽相位八叉树和窄相位 AABB 测试相比,网格中的光线投射是微不足道的。我建议您对体素和体素集碰撞检测/光线投射进行一些研究,因为您会发现这两种算法更容易实现并且运行速度更快。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Minecraft 克隆的最佳盒子选择方法 的相关文章

  • SharpZipLib - 将文件夹/目录添加到 zip 存档

    通过示例 我很好地掌握了如何提取 zip 文件 几乎在每个示例中 识别 ZipEntry 是否为目录的方法如下 string directoryName Path GetDirectoryName theEntry Name string
  • Accept() 是线程安全的吗?

    我目前正在用 C 语言为我正在做的课程编写一个简单的网络服务器 我们的一项要求是实现一个线程池来使用 pthread 处理连接 我知道我将如何粗略地执行此操作 在主线程中调用accept并将文件描述符传递给freee线程 但是我的朋友建议了
  • 获取 std::variant 当前持有的 typeid(如 boost::variant type())

    我已经从 boost variant 迁移到 std variant 但遇到了障碍 我在 boost type 中使用了一个很好的函数 它可以让你获取当前持有的 typeid 看https www boost org doc libs 1
  • 键盘加速器在 UWP 应用中停止工作

    我正在尝试将键盘加速器添加到 UWP 应用程序中的 CommandBar 菜单项 当应用程序启动时 这工作正常 但在我第一次打开溢出菜单后 加速器停止工作 这似乎不会发生在主要命令 菜单之外 上 只有溢出菜单内的辅助命令才会发生 此外 单击
  • 使用API​​隐藏程序标题栏

    它可以使用 c 和 windows api 删除窗口控制台标题栏 如果是的话如何 请 这个简单的应用程序隐藏并显示其所在控制台的标题栏 它会立即将控制台标题更改为 guid 以查找窗口句柄 然后 它使用 ToggleTitleBar 使用找
  • 静态类变量与外部变量相同,只是具有类作用域吗?

    在我看来 静态类变量与外部变量相同 因为你只需要declare它在static int x extern int x语句 并在其他地方实际定义它 通常在 cpp 文件中 静态类变量 h file class Foo static int x
  • Paradox 表 - Oledb 异常:外部表不是预期的格式

    我正在使用 Oledb 从 Paradox 表中读取一些数据 我遇到的问题是 当我将代码复制到控制台应用程序时 代码可以工作 但在 WinForms 中却不行 两者都以 x86 进行调试 我实际上只是复制代码 在 WinForms 应用程序
  • 矩阵向量变换

    我正在编写一个代码来制作软件蒙皮器 骨骼 皮肤动画 并且我正处于 优化 阶段 蒙皮器工作得很好 并且在 Core 上 1 09 毫秒内对 4900 个三角形网格与 22 个骨骼进行蒙皮Duo 2 Ghz 笔记本 我需要知道的是 1 有人可以
  • 有没有办法使用 i387 fsqrt 指令获得正确的舍入?

    有没有办法使用 i387 fsqrt 指令获得正确的舍入 除了改变精确模式在 x87 控制字中 我知道这是可能的 但这不是一个合理的解决方案 因为它存在令人讨厌的重入型问题 如果 sqrt 操作中断 精度模式将出错 我正在处理的问题如下 x
  • 方法“xxx”不能是事件的方法,因为该类派生的类已经定义了该方法

    我有一个代码 public class Layout UserControl protected void DisplayX DisplayClicked object sender DisplayEventArgs e CurrentDi
  • 序列化和反序列化 Visual Studio 解决方案文件 - 或以编程方式编辑?

    我想以编程方式添加和删除项目 解决方案文件夹和其他项目 例如解决方案的资源文件 但我不确定最好的方法是什么 对于那些不知道的人 高度简化 解决方案文件 sln 通常如下所示 Microsoft Visual Studio Solution
  • 在 MATLAB 中创建共享库

    一位研究人员在 MATLAB 中创建了一个小型仿真 我们希望其他人也能使用它 我的计划是进行模拟 清理一些东西并将其变成一组函数 然后我打算将其编译成C库并使用SWIG https en wikipedia org wiki SWIG创建一
  • 防止GDB中的PLT(过程链接表)断点

    在最新版本的 GDB 中 在库函数调用上设置断点会导致多个实际断点 调用过程链接表 PLT 实际的函数调用 这意味着当调用库函数时 我们每次都会经历两次中断 在以前的 GDB 版本中 只会创建 2 因此您只能得到一次中断 那么问题来了 是否
  • 如何用 C 语言练习 Unix 编程?

    经过五年的专业 Java 以及较小程度上的 Python 编程并慢慢感觉到我的计算机科学教育逐渐消失 我决定要拓宽我的视野 对世界的一般用处 并做一些 对我来说 感觉更重要的事情就像我真的对机器有影响一样 我选择学习 C 和 Unix 编程
  • 从事务范围调用 WCF 服务方法

    我有这样的代码 using TransactionScope scope TransactionScopeFactory CreateTransactionScope some methodes calls for which scope
  • 将非算术类型作为参数传递给 cmath 函数是否有效?

    给定以下用户定义类型S具有转换功能double struct S operator double return 1 0 以及以下调用cmath http en cppreference com w cpp header cmath使用类型的
  • .NET JIT 编译的代码缓存在哪里?

    NET 程序首先被编译为 MSIL 代码 当它被执行时 JIT编译器会将其编译为本机机器代码 我想知道 这些JIT编译的机器代码存储在哪里 它只存储在进程的地址空间中吗 但由于程序的第二次启动比第一次快得多 我认为即使在执行完成后 该本机代
  • 如何将对象转换为传递给函数的类型?

    这不会编译 但我想做的只是将对象转换为传递给函数的 t public void My Func Object input Type t t object ab TypeDescriptor GetConverter t ConvertFro
  • 从有符号字符转换为无符号字符然后再转换回来?

    我正在使用 JNI 并有一个 jbyte 类型的数组 其中 jbyte 表示为有符号字符 即范围从 128 到 127 jbyte 表示图像像素 对于图像处理 我们通常希望像素分量的范围为0到255 因此 我想将jbyte值转换为0到255
  • FindAsync 很慢,但是延迟加载很快

    在我的代码中 我曾经使用加载相关实体await FindAsync 希望我能更好地遵守 C 异步指南 var activeTemplate await exec DbContext FormTemplates FindAsync exec

随机推荐

  • 当公式更改单元格值时触发脚本

    我正在使用 Google 脚本 然后在 Google 工作表中的特定列发生更改时发送电子邮件 单元格中的信息可以手动输入 也可以根据其他单元格中的信息使用公式完成 当手动输入信息时 脚本可以正常工作 但在公式运行时则不行 我已经阅读了它并意
  • 为什么我无法从其他节点 IP 访问 kubernetes pod?

    我已经在 Kubespray 的帮助下安装了 kubernetes 集群 集群有 3 个节点 2 个主节点和 1 个工作节点 节点1 10 1 10 110 节点2 10 1 10 111 节点3 10 1 10 112 kubectl g
  • 如何在 NancyFX 中写入流输出?

    我正在使用 Nancy 编写一个简单的 Web 应用程序 至少一个请求会导致长度未知的流 因此我无法提供Content Length 我想用Transfer Encoding chunked 或 在这种情况下同样可以接受 Connectio
  • 在 Ruby 中迭代无限序列

    我正在尝试解决 Project Euler 问题 12 三角形数序列是通过将自然数相加生成的 数字 所以第 7 个三角形数 将为 1 2 3 4 5 6 7 28 前十项是 1 3 6 10 15 21 28 36 45 55 让我们列出前
  • PHP XML/HTML DOM 获取带有空格的 CSS 类属性

    我有以下问题 我正在使用 PHP XML DOM 解析器 当我解析现实世界的 HTML 时 许多元素的 class 属性中都有空格 因此这些元素实际上有多个 CSS 类 但是 当我使用 getAttribute 查询 DOMNode 时 我
  • 如何使用 REGEXP_SUBSTR 解析数据?

    我有一个像这样的数据集 见下文 我尝试提取形式为 variable number of digits hyphen only one digit 的数字 with mcte as select ILLD ELKJS 00000000 ELK
  • Composer 软件包已更新但未安装

    做完之后 sudo php composer phar update 我得到以下信息 Loading composer repositories with package information Updating dependencies
  • 通过Java获取Windows文件关联

    我以为这会是一件容易的事 但是 我希望我的 Java 程序能够获取用户的 Windows 文件关联 换句话说 我想知道用户使用什么来打开 txt文件 cvs文件等 assoc 和 ftype 命令提供该信息 但不提供给用户 换句话说 如果我
  • stderr 上的 Paramiko recv()/read()/readline(s)() 返回空字符串

    我正在使用 paramiko 收集远程主机上的一些信息并在阅读时遇到问题 read readline readlines 来自stderr渠道 有时stderr read 返回一个空字符串 在我看来 它看起来像是竞争条件的结果 然而 根据我
  • 计算每列或行非零元素平均值的有效方法

    我有一个 numpy 数组 用于存储用户对电影的评分 评分介于 1 到 5 之间 0 表示用户没有对电影进行评分 我想计算每部电影的平均评分 以及每个用户的平均评分 换句话说 我将计算每列或每行非零元素的平均值 是否有一个有效的 numpy
  • 如果已经登录,则正确跳过登录活动

    我的启动器图标当前启动登录活动 我已将登录状态存储在 SharedPreferences 中 有什么办法可以properly跳过登录活动并直接进入主要活动 无需any用户界面故障 所有现有的解决方案涉及finish in onCreate
  • 更改 XML 标签名称

    我想转换一个我已经解析过的 XML 文档XmlSlurper 相同的 XML 标记名称应替换为id属性 所有其他属性都应该被删除 从这段代码开始 def xml
  • 未绑定 play.api.db.slick.DatabaseConfigProvider 的实现

    我无法顺利使用 play 2 5 x 我收到以下运行时错误 ProvisionException Unable to provision see the following errors 1 No implementation for pl
  • 复制 Groovy 类属性

    我想要将对象属性复制到另一个对象以通用方式 如果目标对象上存在属性 我从源对象复制它 我的代码使用良好扩展元类 http groovy codehaus org gapi groovy lang ExpandoMetaClass html
  • javax.el.PropertyNotFoundException:目标无法访问,标识符“登录”解析为 null Spring + JSF [重复]

    这个问题在这里已经有答案了 我无法解决使用 Autowired 服务获取 null 的问题 这是我的代码 我的配置文件 应用程序上下文 xml
  • 如何将 Java 组合框中的项目居中

    Java 中的组合框是否有一种方法可以将组合框中的项目居中 我尝试了这个但没有成功 myCombobox setAlignmentY CENTER ALIGNMENT Thanks 试试这个链接 如何使用组合框 Java 教程 gt 使用
  • 使用 PHP Mail() 发送附件?

    我需要通过邮件发送 pdf 文件 可以吗 to xxx subject Subject message Example message with b html b headers MIME Version 1 0 r n headers C
  • T get()”是什么意思? (还有用吗?)

    这似乎是有效的 Java 语法
  • 如何使用存储过程在 mysql 中选择和插入值

    我是使用存储过程的新手 我有一个从表中获取值的查询 之后 我需要将结果插入到另一个表中 这是我的查询 SELECT a gender b purpose abroad as per recorded travel b country nam
  • Minecraft 克隆的最佳盒子选择方法

    我正在制作 Minecraft 克隆作为我的第一个 OpenGL 项目 但卡在了框选择部分 做出可靠的盒子选择的最佳方法是什么 我一直在研究一些 AABB 算法 但它们都没有足够好地解释它们到底做了什么 尤其是经过超级调整的算法 而且我不想