PHP

ogre 3d 1.7 beginner’s guide 第四章 第二小节 中文翻译 添加运动到场景之中

2011/3/4

Adding movement to the scene

【 添加运动到场景之中 】

We have created our scene; now let's add movement to the scene.

【 我们已经创建了场景;现在让我们把运动添加进场景中。】

Time for action – adding movement to the scene

【 实践时刻 —— 添加运动到场景中 】

Up until now, we only had one class, namely, ExampleApplication. This time we need

another one:

【 目前为止,我们只有一个类,即是,ExampleApplication。这次我们需要另一个类:】

1.  Create a new class, name it Example25FrameListener, and let it inherit publicly

from Ogre::FrameListener:

【 1. 创建一个新类,命名为Example25FrameListener,并使它从Ogre::FrameListener 中公有继承。】

class Example25FrameListener : public Ogre::FrameListener

{

};

2.  Add a private member variable, which is an Ogre::SceneNode pointer, and name

it _node:

【 2. 添加一个私有的成员变量,一个Ogre::SceneNode的指针,并把它命名为_ node】

private:

Ogre::SceneNode* _node;

3.  Add a public constructor that takes an Ogre::SceneNode pointer as a parameter

and assigns it to the member node pointer:

【 3. 添加接收一个Ogre::SceneNode指针为参数的公有构造函数,并把这个指针赋值操作给成员变量node 指针。】

public:

Example25FrameListener(Ogre::SceneNode* node)

{

_node = node;

}

4.  Add a new function called frameStarted(FrameEvent& evt), which translates

the member node with (0,0,0.1) and then returns true:

【 4. 添加一个新的frameStarted(FrameEvent& evt) 函数,在函数中用(0,0,0.1)变换成员node,然后返回 true:】

bool frameStarted(const Ogre::FrameEvent  &evt)

{

_node->translate(Ogre::Vector3(0.1,0,0));

return true;

}

5.  Add a new member variable to hold the pointer to the FrameListener, which we

will create later:

【 5. 添加一个FrameListener指针为成员变量。】

Ogre::FrameListener* FrameListener;

6.  Add a constructor which inits the pointer with NULL and a destructor which destroys

the FrameListener when the application is closed:

【 6. 添加一个初始化FrameListener为NULL的构造函数和一个当程序结束时删除FrameListener的析构函数。】

Example25()

{

FrameListener = NULL;

}

~Example25()

{

if(FrameListener)

{

delete FrameListener;

}

}

    • Now create a new function in ExampleApplication called createFrameListener. In this function, create an instance of the FrameListener we defined and add it using mRoot:

【 现在,在ExampleApplication类中创建一个名为createFrameListener的新函数。在这个函数中,创建一个FrameListener的实例并添加它到mRoot:】

void createFrameListener()

{

FrameListener = new Example25FrameListener(_SinbadNode);

mRoot->addFrameListener(FrameListener);

}

8.  Compile and run the application. You should see the same scene as seen earlier,

but this time, the instance of Sinbad moves right and you can't move the camera or

close the application with the Escape key. To close the application, click the X button

on the console windows, or if you started the application from a console, you can

use CTRL+C.

【 8. 编译运行程序。你应看到和之前相同的场景。但是这次,Sinbad的实例向右边移动了并且你不能移动摄像机或用Escape键关闭程序。你可以使用控制台窗口的X按钮关闭窗口。如果你从控制台启动程序,你可以使用CTRL+C 来结束程序。】

What just happened?

【 刚刚发生了什么?】

We added a new class to our code which moves our scene node.

【 我们添加了一个可以移动我们场景结点的类到我们的代码中。】

FrameListener

【 帧监听 】

The new concept we have encountered here is the concept of FrameListeners. As the name suggests, a FrameListener is based on the observer pattern. We can add a class instance which inherits from the Ogre::FrameListener interface to our Ogre 3D root instance using the addFrameListener() method of Ogre::Root. When this class instance is added, our class gets notified when certain events happen. In this example, we overrode the frameStarted() method.

【 我们在此遇到的一个新概念就是帧监听。顾名思义,帧监听是基于一个观察者的模式。我们可以添加一个类的实例。你可以使用Ogre::Root的addFrameListener()方法,通过继承自Ogre::FrameListener的接口,添加一个对象到我们的Ogre3D根对象中。当对象被添加时,在确定的事件发生时我们的类就会得到通知。在这个例子中,我们重写了frameStarted()方法。】

Before a frame (by frame, we mean a single picture of the scene) is rendered, Ogre::Root iterates over all added FrameListeners and calls the frameStarted() method of each one. In our implementation (see step 4) of this function, we translated the node 0.1 units on the x-axis. This node was passed to the Framelistener in its constructor. Therefore, each time the scene is rendered, the node is translated a bit, and as a result, the model moves. As we have seen during the running of the application, we can't move our camera or exit our application using the Escape key. This is because these things were done by the FrameListener, which comes with the ExampleApplication framework. The ExampleApplication framework comes with the SDK. Now that we have replaced it with our own implementation, we can't use the functions the FrameListener offers any longer.

But we will reimplement most of them in this chapter, so no worries. If needed, we could still

call the functions of the base class to get our default behavior back.In step 4, our function returns true. If it returned false, Ogre 3D would interpret this as a signal to drop out of the render loop, and with this, the application would be closed. We will use this fact to reimplement the "press Escape to exit the application" function.

【 在帧(帧,意思是指场景中的单个图像)被渲染之前,Ogre::Root 遍历所有添加的Framelistener并调用每个的frameStarted()方法。我们第四步中的函数定义中,我们沿X轴每帧0.1单位的速率变换结点。这个结点通过Example25FrameListener构造函数的返回地址传递给Framelistener。因此,场景每次被渲染的时候,结点就变换一点位置。结果,模型就移动了。正如我们在程序运行时看到的,我们不能移动摄像机或使用Escape 键退出。这是因为这些是由Framelistener来操作的,而这个FrameListener是ExampleApplication 框架自带的。ExampleApplication是SDK自带的。现在我们代替其原有的FrameListener,使用我们自己定义的实现过程。这样我们就不能使用自带的Framelistener,但是这章我们将会重新实现他们中的大部分,所以不用担心。如果需要,我们可能仍然调用基类的成员函数来获得默认的行为。在第四步中,我们函数返回true。如果返回false,Ogre 3D 将会解释false为退出渲染循环的标志,而与此同时,程序就会结束。我们将会使用重新实现“按Escape键退出”的函数。】

Pop quiz – design pattern of FrameListener

【 简单测试 —— FrameListener的设计模式 】

1.  On which design pattern is the FrameListener concept based?

【 1. Framelistener概念的模式是基于?】

a.  Decorator 【装饰者】

b.  Bridge     【桥】

c.  Observer 【观察者】