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 ...
随机推荐
- JVM的异常体系
任何程序都追求正确有效的运行,除了保证我们代码尽可能的少出错之外,我们还要考虑如何有效的处理异常,一个良好的异常框架对于系统来说是至关重要的.最近在采集框架的时候系统的了解一边,收获颇多,特此记录相关 ...
- Report Builder 打开报错
提示:REP-0756:警告:找不到PL/SQL程序库’inv.pll’. 解决办法 处理:1.运行 ---输入REgedit ,在注册表内,查找注册表项Reports_path. 2.将下载的.pl ...
- 第一个WebDriver脚本
1.cmd下安装selenium,输入pip install selenium 2.下载Firefox浏览器的驱动程序,https://github.com/mozilla/geckodriver/r ...
- vue.js中的表单radio,select,textarea的v-model属性的用法
只要是表单元素,其值已经不会再用value来定义了,但是placeholder还是可以用来设置默认值. section1--input:type="text" type=" ...
- Maven实战读书笔记(四):Maven生命周期与插件
Maven的生命周期是对所有构建过程的抽象和统一.包含了项目的清理.初始化.编译.测试.打包.集成测试.验证.部署和站点生成等几乎所有构建步骤. Maven的生命周期是抽象的,其实际行为是由插件来完成 ...
- thinkphp5实现文件上传
原理:通过form表单的enctype = "multipart / form-data"属性将文件临时放在htdocs文件夹的tmp目录下,再通过后台的程序将文件保存在自己设定的 ...
- 4. COLLATION_CHARACTER_SET_APPLICABILITY
4. COLLATION_CHARACTER_SET_APPLICABILITY 表COLLATION_CHARACTER_SET_APPLICABILITY表示哪种字符集适用于哪种排序规则. INF ...
- 2017acm南宁现场赛 J题 Rearrangement
题意: 给定一个2 * n的矩阵, 和 2 * n 个数, 问能不能通过重排列, 使得任意相邻两数不能被3整除 分析: 这题一直卡到最后, 赛后经对面大佬提醒后, 发现统计所有数模三的结果(0,1,2 ...
- 大数据学习——hdfs集群启动
第一种方式: 1 格式化namecode(是对namecode进行格式化) hdfs namenode -format(或者是hadoop namenode -format) 进入 cd /root/ ...
- 70.打印所有Spring boot载入的bean【从零开始学Spring Boot】
[从零开始学习Spirng Boot-常见异常汇总] 问题的提出: 我们在开发过程当中,我们可能会碰到这样的问题:No qualifying bean 就是我们定义的bean无法进行注入,那到底是什 ...