3D卷的数据结构和算法?

时间:2014-06-18 19:42:55

标签: java algorithm data-structures 3d minecraft

我一直在修补一些Minecraft Bukkit插件开发,目前我正在开发一些我需要能够定义空间“体积”并确定实体(播放器)从外部移动到内部的时间(反之亦然)。

如果我将“音量”限制为方框, 应该简单。数据结构可以只维持X / Y / Z边界整数(因此总共6个整数)并计算两个点的移入/退出(从移动到移动)应该只是确定A)是否所有三个To值都是在所有三个范围内,B)至少有一个From值超出其相应范围。

(虽然如果有一种更好,更高效的存储和计算方式,我会全力以赴。)

然而,如果“音量”不是一个简单的盒子怎么办?假设我有一个形状奇特的房间,想要封闭那个房间的音量。我可以单独排列多个“卷”以填充整个空间,但是当实体从一个实体移动到另一个实体时,这会导致误报。

之前没有在游戏或3D引擎中工作,我在如何构建这样的结构上画了一个空白。但是我发现这可能是一个已经解决的问题并且已经确定了已建立的模式。基本上,我正在尝试:

  1. 定义一个数据结构,可以表示奇形状的空间体积(尽管至少基于块坐标)。
  2. 定义一个算法,给定移动的源和目的地,可以确定移动是否越过定义空间的边界。
  3. 是否有既定的模式和做法?

2 个答案:

答案 0 :(得分:2)

我不知道之前是否曾在任何类型的视频游戏中使用过,但首先想到的是经典的Sieve of Eratosthenes implementation,唯一的变化就是制作{{{3}} 1}}数组3D,并使用键作为坐标。显然,虽然在Minecraft中booleanx值可能很大,但您可能希望通过在世界y位置和您的选择之间保存偏移来节省空间,类似于这样:

0,0

class OddArea { static final int MAX_SELECTION_SIZE = 64; //Or whatever public final int xOffset, yOffset; // 256 = Chunk height public final boolean[][][] squares = new boolean[MAX_SELECTION_SIZE][MAX_SELECTION_SIZE][256]; OddArea() { this(0, 0); } OddArea(final int xOffset, final int yOffset) { this.xOffset = xOffset; this.yOffset = yOffset; } void addBlock(final int x, final int y, final int z) { this.squares[x - this.xOffset][y - this.yOffset][z] = true; } boolean isInsideArea(final int x, final int y, final int z) { return this.squares[x - this.xOffset][y - this.yOffset][z]; } } 并不需要偏移,因为Minecraft世界只有256块高。

我可以通过此设置考虑的唯一问题是,在开始填充对象之前,您必须知道最低的zx坐标

答案 1 :(得分:0)

通常,您应该使用类似于kd trees的数据结构。您可以将体积表示为立方体或球体的并集,并且应该很容易评估对象是否进入体积。

顺便说一句,要计算两个球是否相交,检查中心之间的距离是否小于半径之和。