redstone_machine...吧 关注:3,604贴子:60,844

【为精准而鸣起的丧歌】高度衰减源码解析和基于碰撞箱的压爆现象

取消只看楼主收藏回复

对于矢量炮来说这才是真正意义上的丧歌!


IP属地:广东1楼2018-08-01 18:36回复
    大家都明白,对于矢量炮来说最重要的一点就是精准,可是两年前恩氟在制作三维矢量炮的时候,发现了高度衰减现象。
    什么是高度衰减现象?
    高度衰减:简称高衰,是指三维矢量炮在Y轴推进数一样时,XZ轴推进数增加时,Y轴推进距离会不断减小,这和矢量理论相违背,被称作高度衰减
    如下图


    IP属地:广东2楼2018-08-01 18:37
    收起回复
      那么为什么会有高度衰减呢?
      首先我们要向讲一下MC中常见也比较常用的系统——碰撞箱
      关于碰撞箱在源码中的定义就是空间中两个点坐标所组成的长方体边框
      是用来处理有关于部分运动与碰撞的系统


      IP属地:广东3楼2018-08-01 18:38
      收起回复
        而且对于一个实体来说,他的碰撞箱系统伴随着一些附加值
        第一个就是Pos中心,对应的是实体的初始Posx,Posz,Posy

        这个坐标是直接与实体的运动挂钩,也可以称作 运动中心
        第二个就是CoverPos中心,这个中心跟碰撞箱相关联,常用来当作被推进的实体的中心
        大部分情况下这个中心的坐标跟Pos中心的坐标基本一样,不一样的情况之后会说,可以被称作 被动中心
        第三个是Explosion中心,这个中心顾名思义就是可爆炸实体爆炸的中心,如果这个中心被水覆盖,那么就可以保证没有方块破坏,反之亦然,可以称作 爆炸中心


        IP属地:广东4楼2018-08-01 18:39
        收起回复
          最后我们就需要谈一下实体的Eyeheight
          每个实体在生成时都会设置一个width和height值,width就是实体的长和宽(这就意味着所有实体的碰撞箱长宽都一致?不太清楚,有待考察),height就是这个实体的高,然后系统会通过这两个值来确立一个实体的碰撞箱,但大家都知道,MC的主角steve有一个视线高度,略低于steve的碰撞箱顶部,这个视线高度就是实体的Eyeheight,这个Eyeheight固定是一个实体height的0.85倍,如下图


          IP属地:广东5楼2018-08-01 18:40
          收起回复
            为什么要谈这个Eyeheight,因为对于Pos中心和CoverPos中心来说,唯一的差距就是这个Eyeheight,在大部分情况下,Pos中心的XZ坐标值和CoverPos中心一致,但是对于不同实体来说,他们的Y值差了一个Eyeheight
            PS:我们用F3+B就可以看到Eyeheight,如下图,对于生物来说两层的那个线就是Eyeheight,蓝线是模拟视线,对于普通实体来说,蓝线所处的高度就是Eyeheight



            IP属地:广东6楼2018-08-01 18:41
            回复
              同样的,并不是所有实体都有Eyeheight,比如说。。。TNT


              可以看到图中的蓝线和地面重合,所以说TNT没有Eyeheight,真惨QAQ


              IP属地:广东7楼2018-08-01 18:42
              回复
                好了,现在我们进入正题,为什么会有高度衰减现象?
                在这个帖子之前,大家普遍认为实体只有一个中心,爆炸处理以这个中心为起始进行,运动处理也以这个中心为起始进行,可惜我上面说到,实体有不同的中心,分担不同的任务。
                所以说我们前面提到Coverpos中心是被动中心,而Explosion中心是爆炸中心,简单讲的话,对于实体来说,就永远是A的爆炸中心发出“冲击波”,到达B的被动中心使B产生运动,同样的如果这两个中心不在同一个高度的话,就会出现平地起飞的现象,比如说TNT炮平着发射steve当作人肉大炮,会发现steve并没有平着飞出去,而是斜飞,大概就是这个意思,那现在你不禁想问,那么TNT推TNT呢,这回总是平着推出去了吧。
                可惜很抱歉,mojang就是可以为所欲为,实际上TNT的被动中心和爆炸中心不仅不是同一个点,而且连高度都不一样!
                首先在(0,0,0)坐标处的TNT实体的爆炸中心是(0.49,0.49,0.06125)
                而被动中心则是(0.49,0.49,0.833)
                PS:
                爆炸中心计算公式是(width/2,width/2,height/16)
                被动中心计算公式是(width/2,width/2,0+Eyeheight)
                算出来就是上面的点


                IP属地:广东8楼2018-08-01 18:43
                回复
                  现在你肯定非常不屑的说我错了,没错,如果真的是这样的话平地推进的两个实体TNT都会斜射出去(因为有高度差)
                  但实际上只需要解决一个一个细节即可,实体TNT没有Eyeheight!
                  也就是说被动中心是(0.49,0.49,0)
                  那其实也让你感到迷惑,0和0.06125这样不也是有高度差么,可是区别是现在是下推
                  这样我们就可以看出一个一直都在影响红石炮,但这么长时间基本没有人发现的一个现象——压爆现象
                  指推进TNT和被推进TNT平地推进时会有很微小的下压现象


                  IP属地:广东9楼2018-08-01 18:43
                  回复
                    可能你不是很相信,其实最开始我也不是很相信这种东西,但我们做一下试验
                    下面是实验图1

                    5个命令方块是推进端,fuse为0,放出后立刻爆炸
                    1个命令方块是弹头端,fuse为30
                    可以看到,当我让它自由下落的时候,可以下落到38坐标往上一点
                    当我激活推进端时,它会下落到39坐标,接近40坐标
                    产生了大概2格的误差,正是因为两个中心有0.06125的竖直距离差


                    或者我们换一个思路,如果爆炸中心在0.06125高度处,我们可以挡住它从而大幅减少推力

                    可以看到运动了很短一段距离


                    IP属地:广东11楼2018-08-01 18:46
                    回复
                      而我挡住上面

                      则基本没有影响

                      同理实验3,当TNT底下有灵魂沙的时候,即使顶上有水也会炸掉整个装置,正是因为爆炸中心是0.06125,落在灵魂沙上的时候,爆炸中心在灵魂沙和水的空隙中导致爆炸
                      PS:灵魂沙是不完整方块



                      IP属地:广东12楼2018-08-01 18:47
                      回复(1)
                        好了,那么高度衰减又是怎么一回事呢
                        其实到现在很多人已经明白了,之所以会高度衰减,是因为中心不在同一高度这个已经违背的矢量理论的标准,也正是因为这个压爆现象,使得你的水平推进越大,向下的推挤误差越明显,自然会有高度衰减,而且这个误差高度只有0.06125,可以说基本无法规避,算是真正意义上的矢量炮精准度的丧钟
                        对了,还有一件事请,为什么平地的矢量炮基本显现不出来这种误差呢?
                        个人认为是因为炮头TNT在运动过程中有一段是接触地面的,这段接触地面的距离摩擦阻力很大,使得这种小误差被肉眼忽略,而三维则很精确,有一点误差都可以肉眼可见,放大了这个误差,所以说平地矢量炮如果推进距离足够远,也会有点阵变形的时候
                        真的是讽刺呀,明明运动原理非常巧妙地凑出了满足三轴的矢量理论,结果却因为这个而丧失了精度


                        IP属地:广东13楼2018-08-01 18:50
                        收起回复
                          好了,到这里高度衰减和压爆现象就完结了
                          下面是关于对应源码的部分内容
                          。。。似乎图片太大了传不上来,要不我一会发网盘吧


                          IP属地:广东14楼2018-08-01 18:54
                          回复
                            解决方案:在源码中将TNT实体的Eyeheight启用并特殊设定成0.06125即可


                            IP属地:广东15楼2018-08-01 18:56
                            回复(1)
                              最后就是矢量炮现今的发展方向,如果不想改源码,那么矢量炮的精准度肯定是略逊一筹,但是矢量炮的控制思路还是值得一试,以后可以开发出有火控和扫射的散射矢量炮。。。


                              IP属地:广东16楼2018-08-01 19:01
                              回复