kongbaiyo
本帖最后由 dengyu 于 2021-10-16 00:02 编辑

Minecraft Ray Collision Detector

超精准射线碰撞检测器


这个数据包从根本上、低消耗地解决了原版非完整方块碰撞判定的问题。


特点

如何使用

给任意一个药水云的三个计分板(mrcd_x0、mrcd_y0和mrcd_z0)分别在三个方向上要前进的距离(单位是毫块,也就是坐标乘1000),再执行mrcd:generic/start这个函数即可。该药水云会传送至碰撞终点。若发生碰撞,则会产生mrcd_touch_edge和mrcd_touch_DIRECTION这些tag。其中后一个tag表示该药水云碰撞的面。(包括x_plus、x_minus、y_plus、y_minus、z_plus和z_minus)

如果希望药水云可以穿透一些玩家可穿透的方块,给该药水云加上mrcd_bullet这个tag即可。

如果希望药水可以和实体碰撞的话,给该药水云加上mrcd_entity这个tag即可。若碰撞到实体,则会产生mrcd_touch_entity这个tag,同时被碰撞的实体会被打上mrcd_tagget_entity这个tag。默认情况下不识别玩家,如果想要更改的话就在mrcd:target这个实体标签下添加player即可。可以与mrcd_bullet标签同时使用。

具体实现可以查看mrcd:raycast,mrcd:bullet和mrcd:entity这三个函数,分别表示了视线追踪的应用、发射子弹和识别实体的应用。


限制

由于游戏内花花和竹子的碰撞箱是根据方块坐标计算变化的,因此暂时没有将其实现,视为完整方块。

没有任何限制啦!在最新版v1.3中MRCD已能够计算竹子和花花的坐标偏移。没有任何方块能逃脱MRCD的眼睛!


图片欣赏




更新日志


版本对应


特别鸣谢



2021.12 数据,可能有更多内容
Minecraft Ray Collision Detector
超精准射线碰撞检测器


这个数据包从根本上、低消耗地解决了原版非完整方块碰撞判定的问题。



特点
  • 碰撞极为精准,和自带的黑框别无二致
  • 开销较低,穿过一个方块平均消耗命令200条左右
  • 可任意控制判定距离,灵活度高
  • 建模方便,可增加新的自定义碰撞箱

如何使用

给任意一个药水云的三个计分板(mrcd_x0、mrcd_y0和mrcd_z0)分别在三个方向上要前进的距离(单位是毫块,也就是坐标乘1000),再执行mrcd:generic/start这个函数即可。该药水云会传送至碰撞终点。若发生碰撞,则会产生mrcd_touch_edge和mrcd_touch_DIRECTION这些tag。其中后一个tag表示该药水云碰撞的面。(包括x_plus、x_minus、y_plus、y_minus、z_plus和z_minus)

如果希望药水云可以穿透一些玩家可穿透的方块,给该药水云加上mrcd_bullet这个tag即可。

如果希望药水可以和实体碰撞的话,给该药水云加上mrcd_entity这个tag即可。若碰撞到实体,则会产生mrcd_touch_entity这个tag,同时被碰撞的实体会被打上mrcd_tagget_entity这个tag。默认情况下不识别玩家,如果想要更改的话就在mrcd:target这个实体标签下添加player即可。可以与mrcd_bullet标签同时使用。

具体实现可以查看mrcd:raycast,mrcd:bullet和mrcd:entity这三个函数,分别表示了视线追踪的应用、发射子弹和识别实体的应用。


限制

由于游戏内花花和竹子的碰撞箱是根据方块坐标计算变化的,因此暂时没有将其实现,视为完整方块。

没有任何限制啦!在最新版v1.3中MRCD已能够计算竹子和花花的坐标偏移。没有任何方块能逃脱MRCD的眼睛!


图片欣赏




更新日志
  • v1.0
    • 初次发布
  • v1.1
    • 添加浆果丛支持
  • v1.2
    • 现在AEC可以碰撞实体了
    • 一些命令改进
  • v1.2.1
    • 现在AEC将会传送到被碰撞实体的边界上了
  • v1.2.2
    • bug修复:触碰完整方块x+,y+和z+面的AEC将会停留在碰撞前的一个方块内
    • 例子函数经过了一些修改
  • v2.0
    • 更名为超精准射线碰撞检测器(Minecraft Ray Collision Detector)
    • bug修复:蘑菇被当做完整方块
    • bug修复:子弹可穿过竹子
    • 添加花花、竹笋和竹子的支持
  • v2.1
    • 支持1.16
    • 添加火、灵魂火、灵魂灯笼、灵魂火把、灵魂营火、锁链、下界藤蔓、下界草、下界菌的支持
    • 为红石线、墙添加新的方块状态
    • bug修复:藤蔓被当作完整方块




版本对应
  • 数据包版本2.1 对应游戏版本1.16
  • 数据包版本2.0 对应游戏版本1.14.4, 1.15.2



特别鸣谢






原理


将药水云的三个计分板视为位移向量,将MC中的方块每个面视为平面,计算线面交点,若交点坐标在某一范围内,则发生碰撞。具体实现如下:


药水云的位移向量是:(#total_x, #total_y, #total_z)


首先获取当前位置的坐标,并把它转换成方块坐标,保存到(#block_x, #block_y, #block_z)里。(也就是以所在方块xyz值最小那个点为原点的坐标)

代码:

  1. scoreboard players set #const_1000 mrcd_system 1000
  2. execute store result score #block_x mrcd_system run data get entity @s Pos[0] 1000
  3. execute store result score #block_y mrcd_system run data get entity @s Pos[1] 1000
  4. execute store result score #block_z mrcd_system run data get entity @s Pos[2] 1000
  5. scoreboard players operation #block_x mrcd_system %= #const_1000 mrcd_system
  6. scoreboard players operation #block_y mrcd_system %= #const_1000 mrcd_system
  7. scoreboard players operation #block_z mrcd_system %= #const_1000 mrcd_system

位移向量转化为空间直线方程,用点向式:(x-#block_x)/#total_x=(y-#block_y)/#total_y=(z-#block_z)/#total_z。
这里以x=0平面为例,平面方程为x=0,带入可解得:
y=(-#block_x)#total_y/#total_x+#block_y
z=(-#block_x)#total_z/#total_x+#block_z
用命令表示就是这样:

代码:

  1. # y
  2. scoreboard players set #target_y mrcd_system 0
  3. scoreboard players operation #target_y mrcd_system -= #block_x mrcd_system
  4. scoreboard players operation #target_y mrcd_system *= @s mrcd_y0
  5. scoreboard players operation #target_y mrcd_system /= @s mrcd_x0
  6. scoreboard players operation #target_y mrcd_system += #block_y mrcd_system
  7. # z
  8. scoreboard players set #target_z mrcd_system 0
  9. scoreboard players operation #target_z mrcd_system -= #block_x mrcd_system
  10. scoreboard players operation #target_z mrcd_system *= @s mrcd_z0
  11. scoreboard players operation #target_z mrcd_system /= @s mrcd_x0
  12. scoreboard players operation #target_z mrcd_system += #block_z mrcd_system

之后进行判定,若yz坐标值均在0-1000范围内,则说明发生碰撞。

代码:

  1. execute if score #target_y mrcd_system matches 0..1000 if score #target_z mrcd_system matches 0..1000 run tag @s add mrcd_touch_edge

具体数据包内对以上过程进行了简化和整合,此处特别感谢SPGoding提出的简化想法!让我不至于建模到头凸。



翻阅Minecraft源码,得到坐标偏移计算代码如下(经过简化):

代码:

  1. public Vec3d getOffsetPos(BlockState state, BlockView view, BlockPos blockPos) {
  2.     long long6 = MathHelper.hashCode(blockPos.getX(), 0, blockPos.getZ());
  3.     return new Vec3d(((long6 & 0xFL) / 15.0f - 0.5) * 0.5, 0.0, ((long6 >> 8 & 0xFL) / 15.0f - 0.5) * 0.5);
  4. }

  5. public static long hashCode(int x, int y, int z) {
  6.     long long4 = (long)(x * 3129871) ^ z * 116129781L ^ (long)y;
  7.     long4 = long4 * long4 * 42317861L + long4 * 11L;
  8.     return long4 >> 16;
  9. }

其中hashcode计算涉及到long类型的乘、加和异或运算。但注意到,getOffsetPos函数调用hashcode时,仅使用到了hashcode的低16位。而在hashcode函数最后,又将hash运算结果右移了16位。因此,实际只需运算结果的低32位。又因为乘、加和异或运算数据高位对低位没有影响,因此不用另写大数计算的方法,直接调用计分板运算即可。
这里最关键问题是两个int类型的异或,这是消耗命令数最多的地方,我消耗了300+条命令,不知道有没有简便方法

丢人素学姐
这个原版模组缩写是啥来着?
WR...什么来着

捌柒
论取名的艺术

BlackCB.
**那么多?
嘛,有这种东东还是很好的至少显示记分板列表时会和谐不少

鱼宝放心飞
那么问题来了,非完整实体碰撞判定的问题呢

Ruainbow_
marker的移动速度好像有点慢。
可控吗?

kongbaiyo
Ruainbow_ 发表于 2019-11-14 01:31
marker的移动速度好像有点慢。
可控吗?

完全可控的!修改marker的速度计分板就可以了
你可以看例子函数bullet.mcfunction

EL月663
好强啊,这我得记好久

好吧就这样
厉害了完全想不到

hua1054137042
可以啊这玩意

🥶❄️☠️
真香,这是等离子射线吗?
不过现在置顶的帖子怎么又换了

🥶❄️☠️
kongbaiyo 发表于 2019-11-14 04:53
完全可控的!修改marker的速度计分板就可以了
你可以看例子函数bullet.mcfunction ...

bullet意思是子弹啊好像,而且最慢的蜂鸟手枪子弹也有一百多米每秒,这个。。。是不是慢了一些啊?不对,是慢了几倍速度啊?

CR_019
本帖最后由 CR_019 于 2020-3-24 15:26 编辑
建模方便,可增加新的自定义碰撞箱

敢问一下这个建模是怎么实现的吗?原理里面没看出来是怎么建模的(其实就是我菜)

kongbaiyo
CR_019 发表于 2020-3-24 15:20
敢问一下这个建模是怎么实现的吗?原理里面没看出来是怎么建模的

游戏里碰撞箱都是长方体,定义长方体两个角的坐标就可以了,然后长方体的对应的六个面都根据原理里那么判断
如果碰撞箱不是长方体,那就拿多个长方体去拼

zybyyb
这又够玩好久了吧

xia_long
所以这可以用在什么地方....简称艺术好看就完事了

Kris_X
看的我一脸懵,这玩意儿能用来干啥?能举个例子吗?(新手)

🥶❄️☠️
看来楼上那些来水的意味着不久以后这或许真的是水灾的兆头了
不过这个要是可以作为子弹攻击造成伤害的话就有意思了

腿短啊
没抢到沙发emmmm

⭐✔️
我就纳闷了,去年的帖子楼上还在抢沙发

cmdpchappy
什么。我的天,我的实际,

cmdpchappy
为什吗难免

cmdpchappy
好像没人额额

cmdpchappy
喂喂喂额我翁无

cmdpchappy
真的我我我我

小轩轩2264
好深奥的样子

禁/锢
长知识了,长知识了

1826156147
长知识了,长知识了

1826156147
学到了学到了

zwb_dwz
长知识了,长知识了,
学到了学到了

24k纯帅23356
有意思,学到了(做任务)

2268417684
emmmmmmmmmmm

Kkkknight
有意思,学到了(做任务

我叫云栖
有意思,学到了(做任务)+1


Crazy,
有意思,学到了(做任务)+2

无所谓好吧
6666666henhao

🥶❄️☠️
这个楼啊,估计还是难逃像上一个挂直播的傅里叶本轮法一样成为水楼的命运了看来
请各位务必看一下这个,不要灌水了mcbbs.net/thread-13354-1-1.html

不过楼主还是没回答我的问题,咳

百白术
我来学习啦

百白术
想下载各位大佬的地图可我却连评论的资格都没有。。。

百白术
我太难了。。。

papaxia
eemmmmmmmmm

Mr.stark
这个移速看起来有点慢啊,是作者为了做帖子特意调的么

tianziyue
666666666666

百白术
好厉害的样子。。

WINGY110
谢谢!!!!!

老崔爱mc
好厉害!!!!

loli816
谢谢分享

duoduoduoduoduo
试了一下,过来膜拜下大佬

ROdin
可以很厉害

愿灬许
我脑壳有点晕

下一页 最后一页