自动循环播放全部VR场景

在多场景的漫游中,你可能希望不仅有自动旋转,还希望能够在一个场景停留一段时间后自动进入到下一个场景,当所有全景全部浏览结束后,又重新回到第一个场景,然后循环下去。这种功能作为一种自动展示相当实用。今天就为各位简单说一下如何实现这种bombtimer,这个陌生的英文单词就是定时炸弹的意思。先看一眼最基本的代码。
  1. <events onmousedown="set(bt,0); " onviewchange="set(bt,0); " />

  2. <action name="bombtimer">

  3. set(bt,%1);

  4. add(bt,1);

  5. delayedcall(1, bombtimer(get(bt)));

  6. if(bt == 15, set(bt,0); nextscene();, );

  7. action>

  8. <action name="nextscene">

  9. set(ns, get(scene[get(xml.scene)].index) );

  10. set(maxs, get(scene.count) );

  11. add(ns,1);

  12. if(ns == maxs, set(ns,0);, );

  13. loadscene( get(scene[get(ns)].name ), null, MERGE, BLEND(1.5) );

  14. action>


上面的代码中有一个events事件属性以及两个action动作,首先bt就是一个时间计算的变量,在这个案例中,15秒是定时炸弹爆炸的时间,为什么会有


  1. onmousedown="set(bt,0); " onviewchange="set(bt,0); "

因为在这个bombtimer中,我们假定只有在用户没有与pano全景进行交互时,也就是在非交互时间达到15秒时才进入下一个场景。因此只要鼠标按下,也就是onmousedown,或者视角变化onviewchange出现时,我们就要重置这个bt,也就是set(bt,0)。


第一个名为bombtimer的action是一个计时器功能的函数,首先它接受一个传递来的参数,也就是从第几秒开始计算,假设我们是从0开始,接着add这个action,使得bt变量增加1,这时候bt就从0增加了1,bt为1,delayedcall的中文意思就是延迟执行,它的第一个参数就是你要延迟执行的秒数,本例就是1秒,那延迟执行什么,就是延迟执行bombtimer(get(bt)),你可以看到,在一个bombtimer里面又要执行一个bombtimer,就好像是从镜子里面又看到你身后的另一面镜子,镜中有镜,不断循环。但这里我们用一个get(bt)将当前的bt变量送到下一次bombtimer中,那下一次的action里的bt就是1了,然后是add,它就成了2。这就是计时的主要代码。


当然,我们还需要它爆炸的,因此我们还要判断bt是否到了我们设定的15秒。

  1. if(bt == 15, set(bt,0); nextscene();, );

当bt是15秒的时候,我们重置bt值,并且执行一个nextscene的action。在nextscene的前两行,首先为ns变量载入当前场景的序号,为maxs载入场景总数,scene[get(xml.scene)].index与scene.count是两个很重要的系统变量,大家应该牢记。首先让ns增加1,检查它是否是最后一个场景,如果是的话,就将ns重置为0,因为第一个场景的序号index就是0,在krpano中,你要记住不是从1开始的,很多系统变量是从0开始计算的。


然后就是常见的loadscene,这里我们通过场景的index去载入该场景。

  1. get(scene[get(ns)].name )

这个东西看着很痛苦,其实很简单,假设现在ns是0,get(ns)就是0,那系统直接读取scene[0]的name属性,发现是pano001,因此最后就是

  1. loadscene( pano001 null, MERGE, BLEND(1.5) );


细心的朋友可能发现,这里的action似乎跟自动旋转无关。因此我们来看看一些变化。首先我们需要有一个按钮,来激活bombtimer。


  1. onclick="if(autorotate.enabled,set(layer[skin_btn_autorate].crop,'0|1216|64|64');set(autorotate.enabled,false);stopall(),set(layer[skin_btn_autorate].crop,'64|1216|64|64');set(autorotate.enabled,true);bombtimer(0));"


这里是按钮的onclick的事件,我在这里把自动旋转和定时炸弹功能合二为一。


然后我们来看自动旋转



  1. <autorotate enabled="false"

  2. waittime="1.0"

  3. speed="10.0"

  4. horizon="0.0"

  5. tofov="110"

  6. />


在startup里加上

  1. if(autorotate.enabled,bombtimer(0));


然后是



  1. <events onmousedown="set(bt,0);" />

  2. <action name="bombtimer">

  3. set(autorotate.enabled,true);

  4. set(bt,%1);

  5. add(bt,1);

  6. delayedcall(1, bombtimer(get(bt)));

  7. copy(bt_1,autorotate.speed);

  8. div(bt_2,360,bt_1);

  9. add(bt_2,autorotate.waittime);

  10. if(bt GE bt_2, set(bt,0); nextscene(););

  11. action>

  12. <action name="nextscene">

  13. set(ns, get(scene[get(xml.scene)].index));

  14. set(maxs, get(scene.count));

  15. add(ns,1);

  16. if(ns == maxs, set(ns,0));

  17. loadscene(get(scene[get(ns)].name), null, MERGE, BLEND(1.5));

  18. action>


因为有视角变化,所以这次不能用onviewchange,nextscene是一样的。来看关键的bombtimer,一开始我们要让场景旋转起来。


  1. set(autorotate.enabled,true);


接下来三行与原范例一致。后面出现一些新的变量,例如bt_1、bt_2,我们这次不是很死板的设定15秒,我们是转一圈之后就进入下一个场景。因此我们通过计算bt_2来得到所需要的时间,这里是简单的小学数学,我们用360度除一个角速度,即得到转一圈所需要的时间,因为还有一个等待时间,我们将这两个时间相加,就得到了新的爆炸时间。



2022-05-13
525阅读 · 0人点赞 · 0条评论

0人觉得很赞