在体素环境中有效放置盒子

时间:2012-12-13 04:40:44

标签: algorithm image-processing data-structures voxel

我有一组任意体素来定义游戏的空间。我的目标是根据道具的具体规则在这个房间内放置各种道具(绑定到体素的大小)。一些简单的规则示例(体素维度是xyz,并且有比这三个更多的道具):

  • 书架(2x3x1)需要靠墙和地面放置。
  • 桌子(4x1x2)需要放在地上。
  • 需要将壁挂式灯(1x1x1)靠墙放置。

道具不能与其他道具或现有体素相交。我试图找到一些有效的数据结构和/或算法,可以让我这么快地完成这项工作。我目前的方法是:

  • 创建一组 S 可能的道具位置,这是与填充体素相邻的一组空体素。
  • 标记 S 中的每个项目,如果它是地板,墙壁,角落等。
  • 选择要放置的道具 P
  • 选择 S 的子集 S ,以满足道具的放置规则(仅限墙壁,角落等)。
  • S'中选择一个任意元素 E
  • 这是非最佳部分:尝试以某种方式使 P 围绕 E 。查看 P 的界限是否允许将其置于 E 之上,而不与其他道具和体素相交。如果不合适,请尝试旋转和/或翻译 P 的边界,直到它位于包含 E 的合法地点。
  • 如果它适合,则更新 S 以包含新道具,并开始放置更多道具。
  • 如果仍然无法适应,请从 S'中选择另一个任意元素,然后重试。

它在技术上有效,但它不是非常理想,并且在最坏的情况下可以表现得非常糟糕,例如当道具无法放在房间的任何地方时,或者我正在挑选许多大型地板道具放在房间里大多数地板空间被支柱和支柱打破 孔。

如果我在选择 E 时能够以某种方式考虑 P 的维度,那将是理想的。我正在研究生成体素网格的3D convolution地图(基本上是模糊的网格图像),这样每个体素都有一些关于它周围有多少空间的粗略数据,但问题是我需要每次放下一个新道具时都要更新地图,听起来很贵。

另一个想法是将世界存储在一个八叉树中,并以某种方式进行更好的放置检查,但我似乎无法想象这将有多大帮助。八叉树是否允许我确定一个任意框是否比一个由位置键入的字典更有效地包含任何点?

TLDR:你如何使用比单个体素更大的装饰以编程方式装饰Minecraft中的房子?

1 个答案:

答案 0 :(得分:1)

如果您在S中没有太多体素,在创建墙壁和地板后,您可以简单地创建3组详尽的有效展示位置,每种道具类型一个。让我们为p型ValidPlacements(p)的道具调用一组有效的展示位置。

然后,当您成功地将一个新对象放入世界时,对于每个道具类型p,生成一个类型为p的放置集,该放置将与刚放置的对象在至少1个体素中相交,并从ValidPlacements中删除它们(p)。 (其中一些展示位置可能已经不存在,因为早先放置的对象已经知道它们是不可能的 - 这不是错误条件,只能被忽略。)使用哈希表或平衡树结构来保存每个一组展示位置,以便分别在O(1)时间或O(log n)时间内查找和删除每个展示位置

由于您的对象很小,放置一个对象只会消除少量其他可能的对象放置,因此删除任何对象的放置数量都会很小(它应该大致与两个卷的产品成比例)被交叉的物体)。如果您需要回溯并尝试对象x的其他展示位置,请记录在放置x时从允许展示位置集中实际删除的展示位置,并在删除x时重新插入它们。

示例:在(x,y,z)处放置左上角最左角的书架将消除2 * 3 * 1 = 6个灯的可能位置(即现在每个体素占用1个位置),以及更多的桌子和书架放置位置(即每个可能位置的1个位置,以任何方式与刚放置的书架重叠)。