继续前文,讲述python3D编程中的运动控制。正好借此来研究一下月相的变化。
月相变化的本质上是因为月亮绕地球的转动,导致地球(观察者)、月亮、太阳三者之间位置关系的变化。我们可以把这一运动进行简化为地球和月亮不动,太阳光的方向360度旋转变化。
平行光的方向
前文讲述了panda3D中的4种光源,其中平行光的特点是没有位置,只有方向。或者更准确地说,是光源的位置被忽略,真正起作用的是方向。
这样,我们可以假设太阳是绕着原点运动,而光的方向始终由太阳指向原点。这也是符合真正的天文状态的。
self.light.setPos(R * sin(angle), R * cos(angle), 0)
self.light.lookAt(0,0,0)
通过这样两行语句,可以设置光源的方向。R是半径,angle是角度。实际代码中,我们控制角度不断变化就可以了。
运动
熊猫3D系统中,运动是这样设置的:
self.taskMgr.add(self.update, 'main loop')
其中self.update是一个函数,而引号中的字符串则无须特别在意。
这样设置之后,这个self.update函数将作为自动执行任务被持续调用,每次调用会传递一个时间参数。
def update(self, task):
angleDegrees = task.time * 30
angleRadians = angleDegrees * (pi / 180.0)
self.light.setPos(50 * sin(angleRadians), 50 * cos(angleRadians), 0)
self.light.lookAt(0,0,0)
return task.cont
简单讲解一下代码:
- 第一行:每秒转动30度
- 第二行:角度转换为弧度——为了做正弦与余弦运算
- 第三行:用标准的圆参数方程设置光源的位置
- 第四行:光源位置不是重点,它指向原点的方向,是光源的方向。
- 第五行:含义是让系统继续处理其它的自动执行任务。
华光
如果你注意观察,会发现本节教程中的第一个动图与此有所不同。那里的月亮看起来更亮。在真正的太阳没出场之前,让我们不妨先多给月亮一些光辉。
self.filters = CommonFilters(base.win, base.cam)
filterok = self.filters.setBloom(blend=(1,1,1,0))
这样两行代码,就月亮的表面形成一层华光,看起来更像是在大气层内观察的效果。