视域调度(视域体裁剪)

  在WW中用户改变自己的的视角,纹理影像和高程会动态加载,在视野范围内的影像和DEM显示,超出视域范围的瓦片则不显示。不仅是瓦片,太阳、大气网格、三维模型ModelFeature等都会相应的进行剔除。

  看了ROAM相关的的视域体裁剪论文,有好多采用的是将视域体投影的简化算法。WW是否也是这样?我原来以为是,后来在群里和别人聊,说到了Frustum,才知道这个东西的作用。

  这里涉及的类主要是World_Wind_1.4.0_Source\PluginSDK\ViewFrustum.cs文件中的Frustum类。

  查看Frustum类,包含公有字段public Plane[] planes = new Plane[6];可以知道WW的视域裁剪采用的是六面体来实现的。

  1 using System;
  2 using Microsoft.DirectX;
  3 using Microsoft.DirectX.Direct3D;
  4
  5 namespace WorldWind
  6 {
  7     /// <summary>
  8     /// The region of space in the modeled world that may appear on the screen; it is the field of view of the notional camera.
  9     /// Used to perform culling of invisible object (prior to rendering) to increase speed.
 10     /// See: http://en.wikipedia.org/wiki/Viewing_frustum
 11     /// </summary>
 12     public class Frustum
 13     {
 14         public Plane[] planes = new Plane[6];
 15
 16         public void Update(Matrix m)
 17         {
 18             //bottom (down) plane
 19             this.planes[0] = new Plane(
 20                 m.M14 + m.M12, //a
 21                 m.M24 + m.M22, //b
 22                 m.M34 + m.M32, //c
 23                 m.M44 + m.M42 //d
 24                 );
 25
 26             //far plane
 27             this.planes[1] = new Plane(
 28                 m.M14 - m.M13,
 29                 m.M24 - m.M23,
 30                 m.M34 - m.M33,
 31                 m.M44 - m.M43
 32                 );
 33
 34             //right side plane
 35             this.planes[2] = new Plane(
 36                 m.M14 - m.M11, //a
 37                 m.M24 - m.M21, //b
 38                 m.M34 - m.M31, //c
 39                 m.M44 - m.M41 //d
 40                 );
 41
 42             //left side plane
 43             this.planes[3] = new Plane(
 44                 m.M14 + m.M11,    //a
 45                 m.M24 + m.M21,    //b
 46                 m.M34 + m.M31,    //c
 47                 m.M44 + m.M41    //d
 48                 );
 49
 50             //near plane
 51             this.planes[4] = new Plane(
 52                 m.M13,
 53                 m.M23,
 54                 m.M33,
 55                 m.M43);
 56
 57             //top (up) plane
 58             this.planes[5] = new Plane(
 59                 m.M14 - m.M12, //a
 60                 m.M24 - m.M22, //b
 61                 m.M34 - m.M32, //c
 62                 m.M44 - m.M42 //d
 63                 );
 64
 65             foreach(Plane p in this.planes)
 66                 p.Normalize();
 67         }
 68
 69         /// <summary>
 70         /// Test if a sphere intersects or is completely inside the frustum.
 71         /// </summary>
 72         /// <returns>true when the sphere intersects.</returns>
 73         public bool Intersects(BoundingSphere c)
 74         {
 75             foreach(Plane p in this.planes)
 76             {
 77                 float distancePlaneToPoint = p.A * c.Center.X + p.B * c.Center.Y + p.C * c.Center.Z + p.D;
 78                 if(distancePlaneToPoint < -c.Radius)
 79                     // More than 1 radius outside the plane = outside
 80                     return false;
 81             }
 82
 83             //else it's in view
 84             return true;
 85         }
 86
 87         /// <summary>
 88         /// Test if a point is inside the frustum.
 89         /// </summary>
 90         /// <returns>true when the point is inside.</returns>
 91         /// <param name="v">XYZ in world coordinates of the point to test.</param>
 92         public bool ContainsPoint(Vector3 v)
 93         {
 94             foreach(Plane p in this.planes)
 95                 if(Vector3.Dot(new Vector3(p.A, p.B, p.C), v) + p.D < 0)
 96                     return false;
 97
 98             return true;
 99         }
100
101         /// <summary>
102         /// Tests if the view frustum fully contains the bounding box.
103         /// </summary>
104         /// <returns>true when the box is complete enclosed by the frustum.</returns>
105         public bool Contains(BoundingBox bb)
106         {
107             //Code taken from Flip Code Article:
108             // http://www.flipcode.com/articles/article_frustumculling.shtml
109             int iTotalIn = 0;
110             foreach(Plane p in this.planes)
111             {
112                 int iInCount = 8;
113                 int iPtIn = 1;
114                 // TODO: Modify bounding box and only check 2 corners.
115                 for(int i = 0; i < 8; i++)
116                 {
117                     if(Vector3.Dot(new Vector3(p.A,p.B,p.C), bb.corners[i]) + p.D < 0)
118                     {
119                         iPtIn = 0;
120                         --iInCount;
121                     }
122                 }
123
124                 if(iInCount == 0)
125                     return false;
126
127                 iTotalIn += iPtIn;
128             }
129
130             if(iTotalIn == 6)
131                 return true;
132
133             return false;
134         }
135
136         /// <summary>
137         /// Tests if the bounding box specified intersects with or is fully contained in the frustum.
138         /// </summary>
139         /// <returns>true when the box intersects with the frustum.</returns>
140         public bool Intersects(BoundingBox bb)
141         {
142             foreach(Plane p in this.planes)
143             {
144                 Vector3 v = new Vector3(p.A,p.B,p.C);
145                 bool isInside = false;
146                 // TODO: Modify bounding box and only check 2 corners.
147                 for(int i = 0; i < 8; i++)
148                 {
149                     if(Vector3.Dot(v, bb.corners[i]) + p.D >= 0)
150                     {
151                         isInside = true;
152                         break;
153                     }
154                 }
155
156                 if(!isInside)
157                     return false;
158             }
159
160             return true;
161         }
162
163         public override string ToString()
164         {
165             string res = string.Format("Near:\n{0}Far:\n{1}", planes[4], planes[1] );
166             return res;
167         }
168     }
169 }

该类实现的方法主要包括下面5个,后面四个主要是进行相交检测和包含检测:

public void Update(Matrix m);

public bool Intersects(BoundingSphere c);

public bool ContainsPoint(Vector3 v);

public bool Contains(BoundingBox bb);

public bool Intersects(BoundingBox bb);

调用了Frustum对象的类其实不多,不过Frustum的重要程度和CameraBase捆绑在一起。

  QuadTileSet类中的调用方式主要是通过调用camera.ViewFrustum来获取并进行相关的判断。在QuadTileSet中总共有3处地方可以查见camera.ViewFrustum,一个是在Update方法中,一个是在GetClosestDownloadRequest,还有一个是在ResetCacheForCurrentView方法中。

  QuadTile类中调用方式通过调用camera.ViewFrustum实现,主要在在Update方法中和Render方法中。

转载于:https://www.cnblogs.com/yhlx125/archive/2013/05/29/3103333.html

[WorldWind学习]17.视域调度(视域体裁剪)相关推荐

  1. FedDG:在连续频率空间中通过情景学习进行医学图像分割的联合域泛化

    摘要 论文地址:https://arxiv.org/pdf/2103.06030.pdf 联邦学习使分布式医疗机构可​​以共同学习具有隐私保护功能的共享预测模型.在进行临床部署时,如果将联合学习中训练 ...

  2. 【深度学习】医学图像处理之视杯视盘分割调研分析

    [深度学习]医学图像处理之视杯视盘分割数据集和评价指标 文章目录 [深度学习]医学图像处理之视杯视盘分割数据集和评价指标 1 数据集(公开) 2.1 视盘标签 2.2 视杯视盘标签 2 评价指标 2. ...

  3. 【深度学习】眼底图像的视杯和视盘分割解析

    [深度学习]眼底图像的视杯和视盘分割解析 文章目录 1 背景 2 概念2.1 视盘2.2 视杯 3 数据 4 医学图像分割-Attention Unet 5 注意力机制到底是什么-资源分配给更重要的特 ...

  4. 基于自适应图学习的不完整多视图谱聚类

    论文:IEEE Xplore Full-Text PDF:https://ieeexplore.ieee.org/stamp/stamp.jsp?tp=&arnumber=8587123&am ...

  5. matlab频率域滤波器,频率域滤波的MATLAB设计与实现_课程设计

    频率域滤波的MATLAB设计与实现_课程设计 综合课程设计设计题目 频率域滤波的 MATLAB 设计与实现专业名称班级学号学生姓名指导教师设计时间目 录摘 要 .- 3 -1. 数字图像处理 - 1 ...

  6. Windows sever中域、域树、域森林之间的区别与联系

    域(Domain) 在说域这个概念之前,我们先来回忆一下工作组. 首先,工作组中,每一台计算机都独立维护自己的资源,不能集中管理所有网络资源. 其次,每一台计算机都在本地存储用户的帐户 第三,一个账户 ...

  7. vue-resource ajax跨域,ajax 跨域请求 vue-resource jsonp跨域

    aj体朋几一级发等点确层数框的很屏果行4带域ax 跨域请求 vue-resource j直分调浏器代,刚求的一学础过功互有解小久宗点差维含数如数围请sonp跨域 最近在学习vue.js 碰到个ajax ...

  8. windows server中 森林、域树、域(AD)的区别与联系

    域(Domain) 域 既是Windows网络系统的逻辑组织单元,也是Internet的逻辑组织单元,在Windows 2000系统中,域是安全边界.域管理员只能管理域的内部,除非其他的域显式地赋予他 ...

  9. 直接广播地址_计算机网络之网桥、冲突域、广播域是什么?

    网桥(Bridge)又称为桥接器.和中继器类似,传统的网桥只有两个端口,用于连接不同的网段.和中继器不同的是,网桥具有一定的"智能"性,可以"学习"网络上主机的 ...

最新文章

  1. nginx 修改html header,nginx 安全笔记 (修改nginx的header信息和错误显示版本号)
  2. 不要以为用了云,就不要运维
  3. 用于参考的学生信息管理系统(数据库简单 可自己参考创建)
  4. 导入shape文件到SDE数据库
  5. python处理完数据导入数据库_python 将execl测试数据导入数据库操作
  6. php r很卡,Laravel 在高并发下很卡?求大神解答
  7. java简单功能测试,java 自动化测试小功能集锦
  8. 公司周刊-非常6+1—营销平台小组
  9. try{}catch(){}finally{}执行顺序和return结果顺序的理解03
  10. HTC 一个基站老无法定位
  11. 微信内提示浏览器打开遮罩层
  12. 微信小程序 java网上购物商城系统
  13. 白盒测试用例设计方法(语句覆盖、判定覆盖、条件覆盖、判定/条件覆盖、组合覆盖、路径覆盖、基本路径覆盖)
  14. Multi-Instance Multi-Label Learning Networks for Aspect-Category Sentiment Analysis
  15. 面试题:看数字找规律
  16. both methods have same erasure, yet neither overrides the other
  17. 【公众号】高级配色“马卡龙调色板”必须码住!
  18. 【python量化】国内外基于python开发的量化回测框架
  19. iOS中使用基于RSA使用公钥加密和公钥解密
  20. 前端实现图片标记符号化以及标注

热门文章

  1. java类Timer和TimerTask的使用
  2. 8.继续分析一破解加密码获取-最最最简单的注册机
  3. hdu4279 找规律+小想法
  4. 【五线谱】踏板标记 ( 踩下踏板 Ped 标记 | 松开踏板 * 标记 | MIDI 中的对应踏板指令 | 连续控制信号 | 开关控制信号 )
  5. 【C 语言】指针数据类型 ( 指针类型变量 与 指针指向的内存块 概念区别 | 指针赋值 | 指针运算 | 内存赋值 | 内存取值 | 内存修改注意事项 )
  6. 【约束布局】ConstraintLayout 之 Chains 链式约束 ( Chains 简介 | 代码 及 布局分析 | 链头设置 | 间距设置 | 风格设置 | 权重设置 )
  7. Linux 下 pmap 命令的使用
  8. 病毒木马防御与分析实战
  9. nested exception is java.lang.IllegalStateException: Context namespace element 'annotation-config' a
  10. 给自己新申请的阿里云服务器ECS免费搭建WDCP环境