Panda3D学习 (3):旋转木马例程

时间:2024-03-29 13:39:34

这次从最简单的一个例程入手 从代码上也感觉比前两个简单了许多

1.Hpr值与姿态角

这个例程中涉及了Hpr值的设置,上个例程中就有,但是当时没搞清楚,这次配合了一下百度和自己的调试,大概得到了如下结论:H对应yaw(我怀疑是xyz中有了y所以只能用heading的首字母H),p对应pitch,r对应roll,与姿态角对应关系如下:

Panda3D学习 (3):旋转木马例程

https://jingyan.baidu.com/article/0bc808fc2c0e851bd485b9ce.html这里的动图解释的很生动,在我感觉上,h更像是围着z转,p是x,r是y。这样的话比较解释的通我改变例程参数后展现的效果。

2. 节点和模型

self.pandas = [self.carousel.attachNewNode("panda" + str(i))
               for i in range(4)]
self.models = [loader.loadModel("models/carousel_panda")

               for i in range(4)]

self.pandas[i].setPosHpr(0, 0, 1.3, i * 90, 0, 0)
# Load the actual panda model, and parent it to its dummy node

self.models[i].reparentTo(self.pandas[i])

这是例程中的代码,感觉上是这样的结论:

(来自手册):

dummyNode = render.attachNewNode("Dummy Node Name")

myModel.reparentTo(dummyNode)

myOtherModel.reparentTo(dummyNode)

就是先建立节点,然后把模型加到节点就可以了

不过应该也是可以直接对model setPos的,建立节点可能是想把该节点下所有东西都设置好pos,就不用重复了。

3.LerpFunc和Func

首先是LerpFunc,应该是LerpIntervals的一种,例程中是这样的:

 self.moves[i] = LerpFunc(
                self.oscillatePanda,  # function to call
                duration=3,  # 3 second duration
                fromData=1,  # starting value (in radians)
                toData=2 * pi,  # ending value (2pi radians = 360 degrees)
                # Additional information to pass to
                # self.oscialtePanda
                extraArgs=[self.models[i], pi * (i % 2)]
            )
            # again, we want these to play continuously so we start them with
            # loop()

            self.moves[i].loop()

对应手册上的说明

def myFunction(t):
  # Do something based on t.
 
i = LerpFunc(myFunction,
             fromData=0,
             toData=1,
             duration=0.0,
             blendType='noBlend',
             extraArgs=[],

             name=None)

This advanced interval has many things in common with all of the above LerpIntervals, but instead of directly animating a value, it instead calls the function you specify, passing a single floating-point parameter, t, that ranges from fromData to toData over the duration of the interval.

It is then up to your function to set whatever property of whatever object you like according to the current value of t.

经过我自己debug,fromData和toData代表的就是调用函数oscillatePanda的第一个参数,extraargs则是其余的。这样就可以通过这个data的变化来使得调用函数结果在duration的过程中的变化。

这里一直有一个疑问,我还是分不清为什么许多时候函数要引入第一个参数self的作用是什么,意义在哪里。


然后是Func

我觉得func很简单,就是执行的时候就会调用定义好的func,一般和Sequence这种一起使用

def myFunction(arg1, arg2):
   # Do something.
 

intervalName = Func(myFunction, arg1, arg2)

语法也比较简单

例程中对应为

self.lightBlink = Sequence(
            # For the first step in our sequence we will set the on texture on one
            # light and set the off texture on the other light at the same time
            Parallel(
                Func(self.lights1.setTexture, self.lightOnTex, 1),
                Func(self.lights2.setTexture, self.lightOffTex, 1)),
            Wait(1),  # Then we will wait 1 second
            # Then we will switch the textures at the same time
            Parallel(
                Func(self.lights1.setTexture, self.lightOffTex, 1),
                Func(self.lights2.setTexture, self.lightOnTex, 1)),
            Wait(1)  # Then we will wait another second
        )


        self.lightBlink.loop()  # Loop this sequence continuously

和parallel及Sequence共同使用。

Func(self.lights1.setTexture, self.lightOnTex, 1) 中 显然第一个参数为调用的函数名,后两个为输入参数。


这个Demo显然比之前的简单的多了。

我感觉也掌握了很多的panda3d的基本语法,但是一直不知道model和图片这些的具体实现,egg文件也不知道怎么自己创建,看来离自己做动画还有很遥远的距离要走。


今天就先到这里了,明天再看好了