154 lines
4.5 KiB
Markdown
154 lines
4.5 KiB
Markdown
|
|
|||
|
在3D Max中可以通过时间轴制作摄像机动画,你可以通过Egret3D所提供得插件将制作好的摄像机动画导出为`eca`格式文件,并通过在程序中对该文件的解析,生成摄像机动画。
|
|||
|
|
|||
|
为了方便查看效果,我们首先在3D MAX中制作一个简单的摄像机动画。3D MAX中,场景如下:
|
|||
|
|
|||
|
![](575cd31ccd58b.png)
|
|||
|
|
|||
|
摄像机运动轨迹如下:
|
|||
|
|
|||
|
![](575cd3235cbe6.gif)
|
|||
|
|
|||
|
我们以摄像机视角,查看整个场景运行效果如图:
|
|||
|
|
|||
|
![](575cd32284507.gif)
|
|||
|
|
|||
|
通过Egret3D插件导出其动画文件,名称为`Camera001.eca`,由于当前场景中摄像机名称为`Camera001`,所有导出文件保留其元素命名。
|
|||
|
|
|||
|
你需要借助`URLLoader`类来加载`Camera001.eca`文件,当文件加载完成后,得到的数据`evt.target.data`其数据类型为`egret3d.CameraAnimationController`。
|
|||
|
|
|||
|
在Egret3D中,控制摄像机的动画类由`CameraAnimationController`实现,每一帧中的数据由`CameraAnimationFrame`实现。
|
|||
|
|
|||
|
当你的数据加载并解析完成后,你就可以使用这个`CameraAnimationController`。当在使用之前,你需要通过其中的`bindCamera`方法绑定要控制的摄像机。
|
|||
|
|
|||
|
具体编码步骤如下:
|
|||
|
|
|||
|
1、加载`eca`文件
|
|||
|
|
|||
|
```
|
|||
|
var load:egret3d.URLLoader = new egret3d.URLLoader();
|
|||
|
load.addEventListener(egret3d.LoaderEvent3D.LOADER_COMPLETE,this.com,this);
|
|||
|
load.load("resource/Camera001.eca");
|
|||
|
```
|
|||
|
|
|||
|
```
|
|||
|
private ani:egret3d.CameraAnimationController;
|
|||
|
private com(evt:egret3d.LoaderEvent3D)
|
|||
|
{
|
|||
|
this.ani = evt.target.data;
|
|||
|
}
|
|||
|
```
|
|||
|
|
|||
|
2、绑定摄像机
|
|||
|
|
|||
|
```
|
|||
|
this.ani.bindCamera(this._view.camera3D);
|
|||
|
```
|
|||
|
|
|||
|
3、注册刷新
|
|||
|
|
|||
|
```
|
|||
|
this.canvas.addEventListener(egret3d.Event3D.ENTER_FRAME,this.update,this);
|
|||
|
```
|
|||
|
|
|||
|
```
|
|||
|
private update(evt:egret3d.Event3D)
|
|||
|
{
|
|||
|
this.ani.update(10,16);
|
|||
|
}
|
|||
|
```
|
|||
|
|
|||
|
每一次调用`CameraAnimationController`的`update`方法,才会更新一次摄像机动画。每一次更新,`update`方法需要两个参数。第一个参数为当前时间,第二个参数为每帧时间间隔。
|
|||
|
|
|||
|
4、播放动画
|
|||
|
|
|||
|
```
|
|||
|
this.ani.play(true);
|
|||
|
```
|
|||
|
|
|||
|
`play`方法中,参数如果为`true`,则摄像机动画循环播放。
|
|||
|
|
|||
|
5、暂停动画
|
|||
|
|
|||
|
```
|
|||
|
this.ani.stop();
|
|||
|
```
|
|||
|
|
|||
|
6、监听动画播放完毕事件
|
|||
|
|
|||
|
```
|
|||
|
this.ani.addEventListener(egret3d. CameraAnimationController.EVENT_CAMERA_COMPLETE,this.AniComplete,this);
|
|||
|
```
|
|||
|
|
|||
|
摄像机动画的事件直接封装到了`CameraAnimationController`中,并没有单独放置于独立的事件类中。
|
|||
|
|
|||
|
上述示例完整代码如下:
|
|||
|
|
|||
|
```
|
|||
|
class CameraAni extends LoadingUI
|
|||
|
{
|
|||
|
|
|||
|
private _view:egret3d.View3D;
|
|||
|
protected canvas:egret3d.Egret3DCanvas;
|
|||
|
public constructor()
|
|||
|
{
|
|||
|
super();
|
|||
|
this.CloseLoadingView();
|
|||
|
|
|||
|
this.canvas = new egret3d.Egret3DCanvas();
|
|||
|
this.canvas.x = 0;
|
|||
|
this.canvas.y = 0;
|
|||
|
this.canvas.width = window.innerWidth;
|
|||
|
this.canvas.height = window.innerHeight;
|
|||
|
this.canvas.start();
|
|||
|
|
|||
|
this._view = new egret3d.View3D(0,0,window.innerWidth,window.innerHeight);
|
|||
|
this.canvas.addView3D(this._view);
|
|||
|
this._view.backColor = 0x00ff00;
|
|||
|
|
|||
|
this.createCub();
|
|||
|
|
|||
|
this._view.camera3D.lookAt(new egret3d.Vector3D(300, 500, -1000), new egret3d.Vector3D(0, 0, 0));
|
|||
|
|
|||
|
var load:egret3d.URLLoader = new egret3d.URLLoader();
|
|||
|
load.addEventListener(egret3d.LoaderEvent3D.LOADER_COMPLETE,this.com,this);
|
|||
|
load.load("resource/Camera001.eca");
|
|||
|
}
|
|||
|
|
|||
|
private cube:egret3d.Mesh;
|
|||
|
private mat:egret3d.TextureMaterial;
|
|||
|
private createCub()
|
|||
|
{
|
|||
|
var mat:egret3d.TextureMaterial = new egret3d.TextureMaterial();
|
|||
|
var go:egret3d.CubeGeometry = new egret3d.CubeGeometry(10,10,10);
|
|||
|
var cube:egret3d.Mesh = new egret3d.Mesh(go, mat);
|
|||
|
this._view.addChild3D(cube);
|
|||
|
}
|
|||
|
|
|||
|
private ani:egret3d.CameraAnimationController;
|
|||
|
private com(evt:egret3d.LoaderEvent3D)
|
|||
|
{
|
|||
|
this.ani = evt.target.data;
|
|||
|
this.ani.bindCamera(this._view.camera3D);
|
|||
|
this.ani.play(true);
|
|||
|
|
|||
|
this.canvas.addEventListener(egret3d.Event3D.ENTER_FRAME,this.update,this);
|
|||
|
}
|
|||
|
|
|||
|
private update(evt:egret3d.Event3D)
|
|||
|
{
|
|||
|
this.ani.update(10,16);
|
|||
|
}
|
|||
|
}
|
|||
|
```
|
|||
|
|
|||
|
编译并运行,效果如图:
|
|||
|
|
|||
|
![](575cd31ce7598.gif)
|
|||
|
|
|||
|
## 摄像机帧数据
|
|||
|
|
|||
|
由于摄像机动画相对比较简单,不涉及变形等信息,只包含了时间和摄像机在三维空间中的运动轨迹于姿态。你可以通过`CameraAnimationController`类中的`cameraAnimationFrames`属性获取当前摄像机动画的全部帧数据。每个帧数据的内容可参考`CameraAnimationFrame`类的API内容。
|
|||
|
|
|||
|
|