这两天考试+修改论文。。勉强抽出一点时间学习一下。。还是不能落下
这个例程的名字叫太阳系,难度是入门级,也就是说事实上我的学习进程应该从这个例程开始。。结果本末倒置了,上来就学了迄今最难的一个例程。。不过没事,还好没有碰到太大的挫折。今天在碎片化的时间里学习一下这个入门例程,一方面简单一些,不会太耽误复习的进度,另一方面也可以夯实一下之前不能说有多少的基础。。
Step1. blank_window
from direct.showbase.ShowBase import ShowBase
base = ShowBase()
base.run()
这个例程就是演示了一下如何打开一个panda3d窗口,显然,创建一个ShowBase类然后用run方法,之前每个例程都是如此。
Step2. basic_setup
这个例程演示了一些基本的设置,总共包括
标题设置——OnscreenText
背景设置——base.setBackgroudColor(0,0,0)
相机位置设置——camera.setPos,camer.setHpr
前几篇里都有涉及了。。
Step3. load_model
这一步介绍了模型的加载,
self.sky = loader.loadModel("models/solar_sky_sphere")
#Load model returns a NodePath, which you can think of as an object containing your model
这个对NodePath的解释我觉得可以,就当作一个包含模型的对象就可以了
# After the object is loaded, it must be placed in the scene. We do this by
# changing the parent of self.sky to render, which is a special NodePath.
# Each frame, Panda starts with render and renders everything attached to
# it.
self.sky.reparentTo(render)
这一段也解释的挺好的,意思就是加载模型后要归到render下才能渲染。这个之前的例程里我已经熟悉了,
不过这里才知道render就是每一帧起始点,理解更深入一些了。
# You can set the position, orientation, and scale on a NodePath the same
# way that you set those properties on the camera. In fact, the camera is
# just another special NodePath
这一段说的也挺好的,改变一个NodePath的Scale,Pos属性其实就是在camera上设置了这些属性。但是后面一句不太理解,一直搞不太清楚camera到底是什么,我现在理解就是一个观察点,最后呈现的是从这个观察点看到的东西。
然后是加载Texture,我至今仍把texture理解为图片,然后它的加载和加载model只有一个区别,不同的函数调用,其他的几乎一样 self.sky_tex = loader.loadTexture("models/stars_1k_tex.jpg")
然后是self.sky.setTexture(self.sky_tex, 1) 替换模型的texture,我的理解就是插入图片。
注释里介绍了第二个参数1的含义就是如果不是1的话这条命令就会被无视。这,那为啥要这么设计呢?不考虑这个的话以后setTexture无脑用1就完事儿了。
这个图片长这样:
将self.sky.setTexture(self.sky_tex, 1) 这句话注释与否的两个结果贴出:
这是未注释的结果
这是注释后的结果,函数的功能显而易见了。
Step4 加载行星图
这一步涉及了Node和model之间的关系,我觉得这个例程讲的也很好
# Here is where we load all of the planets, and place them.
# The first thing we do is create a dummy node for each planet. A dummy
# node is simply a node path that does not have any geometry attached to it.
# This is done by
# We do this because positioning the planets around a circular orbit could
# be done with a lot of messy sine and cosine operations. Instead, we define
# our planets to be a given distance from a dummy node, and when we turn the
# dummy, the planets will move along with it, kind of like turning the
# center of a disc and having an object at its edge move. Most attributes,
# like position, orientation, scale, texture, color, etc., are inherited
# this way. Panda deals with the fact that the objects are not attached
# directly to render (they are attached through other NodePaths to render),
# and makes sure the attributes inherit.
# This system of attaching NodePaths to each other is called the Scene
# Graph
self.orbit_root_mercury = render.attachNewNode('orbit_root_mercury')
self.orbit_root_venus = render.attachNewNode('orbit_root_venus')
self.orbit_root_mars = render.attachNewNode('orbit_root_mars')
self.orbit_root_earth = render.attachNewNode('orbit_root_earth')
大意就是我们建立一些虚拟的结点,通过attachNewNode这个函数。然后将模型reparenTo到这个节点上,这样节点一动,模型就会跟着动,而且节点可以理解为圆心,这样操作起来直接就是cos,sin。只需要改变模型到圆点的距离就可以很好的模拟圆周运动了。
self.venus = loader.loadModel("models/planet_sphere")
self.venus_tex = loader.loadTexture("models/venus_1k_tex.jpg")self.venus.setScale(0.923 * self.sizescale)
通过reparentTo,将模型加载到节点上,然后设置到该节点的距离
经过代码调试,节点应该也是可以通过setPos设置位置的,我觉得默认是继承了parent的位置,然后可以设置。但例程中没有改变节点的位置,而是通过改变model相对于节点的位置。
Step5 让行星们转起来
这里用了Interval的函数
self.day_period_sun = self.sun.hprInterval(20, (360, 0, 0))
和之前一样,第一个参数是时间,第二个参数是终止位置。
这句话就是在这段时间内匀速从初始位置到终止位置。
以及self.orbit_period_mercury = self.orbit_root_mercury.hprInterval(
(0.241 * self.yearscale), (360, 0, 0))
这里说明Node也是可以用于动画的。
self.day_period_sun.loop()
最后用loop语句启动就可以了
step6 交互控制
这里用的是accept语句来接收鼠标和键盘输入,没有什么问题,和前几个例子一样。
总体来说这个例程还是很适合入门的,后悔呀,我应该先看这个的,不过这么看下来我也应该掌握了许多基本语法了,可能更需要的是更多的实践来巩固和提高。