ArcGIS Engine三维动画开发 来自:http://www.iarcgis.com/?p=826
ArcGIS Engine 三维开发
来自:http://www.iarcgis.com/?p=826
在三维中,经常使用的一个功能就是播放动画,也就是我们要对一条动画轨迹进行播放,而在ArcGIS Engine中做3D开发的时候,轨迹有两个对应的对象
IAnimationTrack和IAGAnimationTrack,
如果在帮助中仔细查看还会发现更多跟这两个类似的区别,一个接口比另一个接口多两个字母AG,
如IAnimationTracks和IAGAnimationTracks,IKeyframe和IAGKeyframe。
我们看下这些的描述
IAGKeyframe:访问运动对象的关键帧(Provides access to keyframes of animated objects. )
IKeyframe:访问运动对象的关键帧(Provides access to keyframes of animated objects.)
从描述上看,没有任何区别,那么为什么会有两个这样的接口,带AG的出来的比较晚,而且位于ESRI.ArcGIS.Animation中,而不带AG的是早期的接口位于ESRI.ArcGIS.Analyst3D中,而且这些接口的属性和方法都很类似:
Ikeyframe

IAGKeyframe

1.1 原因何在
既然两个接口提供的方法和接口很类似,为什么会有两套这样的接口呢?原来带AG的是后来出现的,而且是在9.2的时候增加的,在9.2的时候增加了Animation等类库,看下面的描述:

在帮助中,我们可以看到更多的信息,首先看到实现IAGAnimationTrack的接口有两个类即AGAnimationTrack和AnimationTrack,也就是说凡是带了AG的接口很多都被早期的对象继承,如下:

AGAnimationTrack类只实现了IAGAnimationTrack接口,如下图:

而AnimationTrack类不仅仅实现了1AnimationTrack接口,还实现了 1AGAnimationTrack接口,如下图:

1.1 后出现的不一定就节省力气
1.1.1 关键帧创建
在创建关键帧的时候两者差别不大,除了创建的时候的参数不一样,其他几乎没有变化,下面为使用IKeyframe创建的:
IKeyframe pKeyframe = new GlobeCameraKeyframeClass();
pKeyframe.Name = "Key" + Convert.ToString(_AnimationTrack.KeyframeCount + 1);
IScene pScene = globe.Globe as IScene;
pKeyframe.CaptureProperties(pScene, globe.GlobeDisplay.ActiveViewer.Camera);
_AnimationTrack.InsertKeyframe(pKeyframe, -1); for (int index = 0; index < _AnimationTrack.KeyframeCount; index++)
{
_AnimationTrack.get_Keyframe(index).TimeStamp = (double)index / (double)(_AnimationTrack.KeyframeCount - 1);
}
下面为使用IAGKeyframe创建的:
public static void InsertKeyfr(IGlobe pGlobe, string pTrackName)
{
IAGAnimationTracks pTracks = pGlobe as IAGAnimationTracks;
IAGAnimationTrack _AnimationTrack = GetAGAnimationTrack(pTracks, pTrackName);
if (_AnimationTrack == null)
{
_AnimationTrack = new AGAnimationTrackClass();
_AnimationTrack.Name = pTrackName; pTracks.AddTrack(_AnimationTrack); } IAGAnimationTrackKeyframes pAGKyeFrames = _AnimationTrack as IAGAnimationTrackKeyframes;
IAGKeyframe pKeyframe = new GlobeCameraKeyframeClass();
pKeyframe.Name = "Capture" + Convert.ToString(pAGKyeFrames.KeyframeCount + 1);
IScene pScene = pGlobe.GlobeDisplay.Scene; //还可以直接转换
pKeyframe.CaptureProperties(pGlobe as IAGAnimationContainer, pGlobe.GlobeDisplay.ActiveViewer.Camera);
(_AnimationTrack as IAGAnimationTrackKeyframes).InsertKeyframe(pKeyframe, -1); for (int index = 0; index < pAGKyeFrames.KeyframeCount; index++)
{
pAGKyeFrames.get_Keyframe(index).TimeStamp = (double)index / (double)(pAGKyeFrames.KeyframeCount - 1);
}
//更新窗体;
}
1.1.1 关键帧获取
但是有的时候不带AG的比带了AG的方便,比如要获取一条轨迹的关键帧,使用IAnimationTrack接口的时候只需要下面两个步骤:
- IAnimationTrack.KeyframeCount
- IAnimationTrack.Keyframe
而IAGAnimationTrack接口则需要3个步骤:
- IAGAnimationTrackKeyframes
- IAGAnimationTrackKeyframes.KeyframeCount
- IAGAnimationTrackKeyframes.Keyframe
1.1.2 播放动画
而在播放动画的饿时候使用IAnimationTracks,我们只需要用下面的步骤代码:
在播放的时候用下面的代码是可以实现动画播放的:
IAnimationTracks pTracks = globe.Globe as IAnimationTracks;
for (int i = 0; i < pTracks.TrackCount; i++)
{
IAnimationTrack pTrack = pTracks.Tracks.get_Element(i) as IAnimationTrack;
pTrack.IsEnabled = true;//设置为true 才可以播放这条轨迹
}
DateTime startTime = DateTime.Now;
TimeSpan timeSpan;
double elapsedTime;
double duration = 10;
bool play = true;
do
{
timeSpan = (DateTime.Now).Subtract(startTime);
elapsedTime = timeSpan.TotalSeconds;
if (elapsedTime > duration)
{
play = false;
elapsedTime = duration;
}
pTracks.ApplyTracks(globe.GlobeDisplay.ActiveViewer, elapsedTime, duration);
globe.GlobeDisplay.RefreshViewers();
} while (play);
我们在前面说到了,带AG的接口提供的方法和属性和不带的非常类似,但下面的代码播放之后是不能实现动画播放的
for (int i = 0; i < pTracks.TrackCount; i++)
{
IAGAnimationTrack pAnimationTrack = pTracks.AGTracks.get_Element(i) as IAGAnimationTrack;
pAnimationTrack.IsEnabled = true;
}
DateTime startTime = DateTime.Now;
TimeSpan timeSpan;
double elapsedTime;
double duration = 10;
bool play = true;
do
{
timeSpan = (DateTime.Now).Subtract(startTime);
elapsedTime = timeSpan.TotalSeconds;
if (elapsedTime > duration)
{
play = false;
elapsedTime = duration;
}
pTracks.ApplyTracks(false, duration);
this.globe.GlobeDisplay.RefreshViewers();
} while (play);
如何才能播放呢,既然已经知道带AG的来自Animation库,那就应该在这个库中找,使用下面的接口:
如果对ArcGlobe的动画非常熟悉的朋友,应该知道这4个方法对应了播放工具上的四个操作,录制,破防。暂停和停止
private IAGAnimationEnvironment CreatAnimationEnvironment(IGlobe pGlobe)
{
DateTime startTime = DateTime.Now; Double playTimeInterval = 10;
IBasicScene2 pBasicScene2 = pGlobe as IBasicScene2;
_pAGAnimationEnvironment = pBasicScene2.AnimationExtension.AnimationEnvironment;
_pAGAnimationEnvironment.IsIntervalPlay = true;
_pAGAnimationEnvironment.PlayInAllViewers = true;
_pAGAnimationEnvironment.PlayMode = esriAnimationPlayMode.esriAnimationPlayOnceForward;
_pAGAnimationEnvironment.AnimationDuration = playTimeInterval;
_pAGAnimationEnvironment.PlayType = esriAnimationPlayType.esriAnimationPlayTypeDuration;
_pAGAnimationEnvironment.PlayTime = playTimeInterval;
_pAGAnimationEnvironment.PutPlayInterval(0, playTimeInterval);//尤其关键,设置播放时间段。
_pAGAnimationEnvironment.RestoreState = true;
IArray pArr = new ArrayClass(); return _pAGAnimationEnvironment;
} //List存放了我路径轨迹的名称
private void PlayAnimaiton(IGlobe pGlobe)
{
IAGAnimationTracks pAGAnimationTracks = pGlobe as IAGAnimationTracks;
IAGAnimationUtils pAGAnimationUtils = new AGAnimationUtilsClass();
IAGAnimationPlayer pAGAnimaitonPlayer = pAGAnimationUtils as IAGAnimationPlayer;
_pAGAnimationEnvironment = CreatAnimationEnvironment(pGlobe);
List pList = new List();
if (checkedListBoxtracks.SelectedItems.Count > 0)
{
for (int j = 0; j < checkedListBoxtracks.CheckedItems.Count; j++)
{
pList.Add(checkedListBoxtracks.CheckedItems[j].ToString());
}
}
for (int i = 0; i < pAGAnimationTracks.TrackCount; i++)
{
IAGAnimationTrack pT=pAGAnimationTracks.AGTracks.get_Element(i) as IAGAnimationTrack; if (pList.Contains(pT.Name))
{
pT.IsEnabled = true;
}
else
{
pT.IsEnabled = false;
}
} pAGAnimaitonPlayer.PlayAnimation(pAGAnimationTracks, _pAGAnimationEnvironment, null);
//pAGAnimationUtils.SaveAnimationFile(pAGAnimationTracks.AnimationObjectContainer, "C:\\test.asa", ESRI.ArcGIS.esriSystem.esriArcGISVersion.esriArcGISVersion93);
}
1.3 但后出现的比较灵活
在使用不带AG的播放动画是,播放结束后,是不能回到原来的状态,但是后者却可以,还有就是在播放的时候,前者是不能停止和暂停(除非播放结束或系统出现问题),但是后者却可以,还有就是后者提供了录制的功能,而前者没有。同时,后者在播放的时候,只要将播放环境接口IAGAnimationEnvironment中的信息设置OK后,就不用自己去写while循环用来判断时间。在创建关键帧的时候,我们往往都是创建路径,然后将帧插入到路径中,但是后者有有个默认的路径,下面的代码就是向默认的路径中捕获当前的视图,也就是ArcGlobe中的那个照相机的功能:
ESRI.ArcGIS.Animation.IAGAnimationUtils pAnimationUtils = new ESRI.ArcGIS.Animation.AGAnimationUtilsClass();
ESRI.ArcGIS.Animation.IAGAnimationTracks pAnimationTracks = (ESRI.ArcGIS.Animation.IAGAnimationTracks)globe;
ESRI.ArcGIS.Analyst3D.IBasicScene2 pBasicScene2 = (ESRI.ArcGIS.Analyst3D.IBasicScene2)globe;
ESRI.ArcGIS.Animation.IAGAnimationEnvironment pAnimationEnvironment = pBasicScene2.AnimationExtension.AnimationEnvironment;
pAnimationUtils.CaptureCurrentView(pAnimationTracks, pAnimationEnvironment);
作者
ArcGIS Engine三维动画开发 来自:http://www.iarcgis.com/?p=826的更多相关文章
- 《ArcGIS Engine+C#实例开发教程》第七讲 图层符号选择器的实现2
原文:<ArcGIS Engine+C#实例开发教程>第七讲 图层符号选择器的实现2 摘要:在第七讲 图层符号选择器的实现的第一阶段中,我们完成了符号选择器窗体的创建与调用.在第二阶段中, ...
- 《ArcGIS Engine+C#实例开发教程》第八讲 属性数据表的查询显示
原文:<ArcGIS Engine+C#实例开发教程>第八讲 属性数据表的查询显示 第一讲 桌面GIS应用程序框架的建立 第二讲 菜单的添加及其实现 第三讲 MapControl与Page ...
- 《ArcGIS Engine+C#实例开发教程》第六讲 右键菜单添加与实现
原文:<ArcGIS Engine+C#实例开发教程>第六讲 右键菜单添加与实现 摘要:在这一讲中,大家将实现TOCControl控件和主地图控件的右键菜单.在AE开发中,右键菜单有两种实 ...
- 《ArcGIS Engine+C#实例开发教程》第四讲 状态栏信息的添加与实现
原文:<ArcGIS Engine+C#实例开发教程>第四讲 状态栏信息的添加与实现 摘要:在上一讲中,我们完成了 MapControl 和PageLayoutControl两种视图的同步 ...
- 《ArcGIS Engine+C#实例开发教程》第五讲 鹰眼的实现
原文:<ArcGIS Engine+C#实例开发教程>第五讲 鹰眼的实现 摘要:所谓的鹰眼,就是一个缩略地图,上面有一个矩形框,矩形框区域就是当前显示的地图区域,拖动矩形框可以改变当前地图 ...
- 《ArcGIS Engine+C#实例开发教程》第三讲 MapControl与PageLayoutControl同步
原文:<ArcGIS Engine+C#实例开发教程>第三讲 MapControl与PageLayoutControl同步 摘要:在ArcMap中,能够很方面地进行MapView和Layo ...
- 《ArcGIS Engine+C#实例开发教程》第二讲 菜单的添加及其实现
原文:<ArcGIS Engine+C#实例开发教程>第二讲 菜单的添加及其实现 摘要:在上一讲中,我们实现了应用程序基本框架,其中有个小错误,在此先跟大家说明下.在“属性”选项卡中,我们 ...
- 《ArcGIS Engine+C#实例开发教程》
原文:<ArcGIS Engine+C#实例开发教程> 摘要:<ArcGIS Engine+C#实例开发教程>,面向 ArcGIS Engine(以下简称AE)开发初学者,本教 ...
- 《ArcGIS Engine+C#实例开发教程》第一讲桌面GIS应用程序框架的建立
原文:<ArcGIS Engine+C#实例开发教程>第一讲桌面GIS应用程序框架的建立 摘要:本讲主要是使用MapControl.PageLayoutControl.ToolbarCon ...
随机推荐
- Android Studio -自定义LogCat的颜色
博文地址 http://www.cnblogs.com/Loonger/p/6285344.html 先看看效果 (设置中的显示,下图) 步骤如下 File->Settings 或Ctrl + ...
- DELETE - 删除一个表中的行
SYNOPSIS DELETE FROM [ ONLY ] table [ WHERE condition ] DESCRIPTION 描述 DELETE 从指明的表里删除满足 WHERE 子句的行. ...
- Win10本地搭建Apache+PHP运行环境
微软全新操作系统Windows10在190个国家和地区正式同步上市,正版Windows7.Windows8.1用户均可在一年内免费升级.介绍一下在升级后的Windwos10系统上安装及配置Apache ...
- Python基础2 列表 元祖 字符串 字典 集合 文件操作 -DAY2
本节内容 列表.元组操作 字符串操作 字典操作 集合操作 文件操作 字符编码与转码 1. 列表.元组操作 列表是我们最以后最常用的数据类型之一,通过列表可以对数据实现最方便的存储.修改等操作 定义列表 ...
- ES6(vue)对象词法扩展
ES6 允许声明在对象字面量时使用简写语法,来初始化属性变量和函数的定义方法,并且允许在对象属性中进行计算操作: function getCar(make, model, value) { retur ...
- js实现复制input的value到剪切板
<button class="button-code button-copy">复制链接</button><script> $(".b ...
- PHP11 日期和时间
学习要点 UNIX时间戳 将其他格式的日期转成UNIX时间戳格式 基于UNIX时间戳的日期计算 获取并格式化输出日期 修改PHP的默认时间 微秒的使用 Unix时间戳 相关概念 Unix tim ...
- docker-compose nginx
docker-compose nginx example source code docker-compose nginx balancing
- 任务五:零基础HTML及CSS编码(二)
面向人群: 零基础或初学者 难度: 简单 重要说明 百度前端技术学院的课程任务是由百度前端工程师专为对前端不同掌握程度的同学设计.我们尽力保证课程内容的质量以及学习难度的合理性,但即使如此,真正决定课 ...
- <Spring Cloud>入门五 hystrix
1.服务熔断 1.1引入坐标 <dependency> <groupId>org.springframework.cloud</groupId> <artif ...