最长的一帧
Cesium原理篇:3最长的一帧之地形(4:重采样)

Cesium原理篇:3最长的⼀帧之地形(4:重采样)地形部分的原理介绍的差不多了,但之前还有⼀个刻意忽略的地⽅,就是地形的重采样。
通俗的讲,如果当前Tile没有地形数据的话,则会从他⽗类的地形数据中取它所对应的四分之⼀的地形数据。
打个⽐⽅,当我们快速缩放影像的时候,下⼀级的影像还没来得及更新,所以会暂时把当前Level的影像数据放⼤显⽰,⼀旦对应的影像数据下载到当前客户端后再更新成精细的数据。
Cesium中对地形也采⽤了这样的思路。
下⾯我们具体介绍其中的详细内容。
上图是⼀个⼤概流程,在创建Tile的时候(prepareNewTile),第⼀时间会获取该Tile⽗节点的地形数据(upsampleTileDetails),然后构造出upsampledTerrain对象,它是TileTerrain对象,只是⼀个包含⽗类地形信息的空壳。
接着,开始创建地形⽹格(processTerrainStateMachine)。
这⾥就有两个逻辑,如果当前没有地形数据,也就是EllipsoidTerrainProvider的情况,这样会直接创建HeightmapTerrainData。
因此状态是TerrainState.RECEIVED,这种情况下不需要重采样;如果请求了真实的地形数据,⽐如CesiumTerrainProvider,⽆论是请求⾼度图还是STK,只要有异步请求,则会执⾏processUpsampleStateMachine韩式,最终实现重采样(sourceData.upsample)。
HeightmapTerrainData.prototype.upsample我们先了解⼀下⾼度图下的实现。
⾼度图,顾名思义也是⼀种图了,所以这个重采样的⽅式和普通的图⽚拉伸算法⼀致。
⽐如⼀个2*2的图⽚,放⼤⾄4*4的⼤⼩,这⾥就有⼀个插值的过程。
⽐如线性差值,会取相邻的两个像素颜⾊,加权求值,或者双线性插值,取周边四个像素,加权求值。
在传统以太网中为什么要有最小帧长度和最大帧长度的限制

在传统以太网中,为什么要有最小帧长度和最大帧长度的限制?以太网(IEEE 802.3)帧格式:1、前导码:7字节0x55,一串1、0间隔,用于信号同步2、帧起始定界符:1字节0xD5(10101011),表示一帧开始3、DA(目的MAC):6字节4、SA(源MAC):6字节5、类型/长度:2字节,0~1500保留为长度域值,1536~65535保留为类型域值(0x0600~0xFFFF)6、数据:46~1500字节7、帧校验序列(FCS):4字节,使用CRC计算从目的MAC到数据域这部分内容而得到的校验和。
以CSMA/CD作为MAC算法的一类LAN称为以太网。
CSMA/CD冲突避免的方法:先听后发、边听边发、随机延迟后重发。
一旦发生冲突,必须让每台主机都能检测到。
关于最小发送间隙和最小帧长的规定也是为了避免冲突。
考虑如下的情况,主机发送的帧很小,而两台冲突主机相距很远。
在主机A发送的帧传输到B的前一刻,B开始发送帧。
这样,当A的帧到达B时,B检测到冲突,于是发送冲突信号。
假如在B的冲突信号传输到A之前,A的帧已经发送完毕,那么A将检测不到冲突而误认为已发送成功。
由于信号传播是有时延的,因此检测冲突也需要一定的时间。
这也是为什么必须有个最小帧长的限制。
按照标准,10Mbps以太网采用中继器时,连接的最大长度是2500米,最多经过4个中继器,因此规定对10Mbps以太网一帧的最小发送时间为51.2微秒。
这段时间所能传输的数据为512位,因此也称该时间为512位时。
这个时间定义为以太网时隙,或冲突时槽。
512位=64字节,这就是以太网帧最小64字节的原因。
512位时是主机捕获信道的时间。
如果某主机发送一个帧的64字节仍无冲突,以后也就不会再发生冲突了,称此主机捕获了信道。
由于信道是所有主机共享的,如果数据帧太长就会出现有的主机长时间不能发送数据,而且有的发送数据可能超出接收端的缓冲区大小,造成缓冲溢出。
OSG_王锐《最长的一帧》

viewer.frame(); 就这样,用一个循环结构来反复地执行 frame()函数,直到 done()函数的返回值为 true 为止。每一次执行 frame()函数就相当于完成了 OSG 场景渲染的一帧,配置较好的计算机可 以达到每秒钟一二百帧的速率,而通常仿真程序顺利运行的最低帧速在 15~25 帧/秒即可。 很好,看来笔者的机器运行 frame()函数通常只需要 8~10ms 左右,比一眨眼的工夫都要 短。那么本文就到此结束吗? 答案当然是否定的,恰恰相反,这篇繁琐且可能错误百出的文字,其目的正是要深入 frame()函数,再深入函数中调用的函数……一直挖掘下去,直到我们期待的瑰宝出现;当然 也可能是一无所获,只是乐在其中。 这样的探索要到什么时候结束呢?从这短短的 10 毫秒中引申出来的,无比冗长的一帧, 又是多么丰富抑或无聊的内容呢?现在笔者也不知道,也许直到最后也不会明了,不过相信 深入源代码的过程就是一种享受,希望读者您也可以同我一起享受这份辛苦与快乐。 源代码版本:OpenSceneGraph 2.6.0;操作系统环境假设为 Win32 平台。为了保证教程 的篇幅不致被过多程序代码所占据,文中会适当地改写和缩编所列出的代码,仅保证其执行 效果不变,因此可能与实际源文件的内容有所区别。 由于作者水平和精力所限,本文暂时仅对单视景器(即使用 osgViewer::Viewer 类)的 情形作出介绍。 转载请注明作者和 本文在写作过程中将会用到一些专有名词,它们可能与读者阅读的其它文章中所述有所 差异,现列举如下: 场景图形-SceneGraph;场景子树-Subgraph;节点-Node;摄像机-Camera;渲染器-Renderer; 窗口-Window;视口-Viewport;场景-Scene;视图-View;视景器-Viewer;漫游器-Manipulator; 访问器-Visitor;回调-Callback;事件-Event;更新-Update;筛选-Cull;绘制-Draw。
构成一帧的基本元素

构成一帧的基本元素一帧是指在电影、动画、漫画等媒体表达中,由若干图像组成的一个单元。
在一帧中,各种元素相互结合,通过动态的操作和定格画面的展示方式来传达信息和表达故事。
以下是构成一帧基本元素的一些重要因素:1.画面构图:一帧的画面构图是整个场景的基础,它决定了画面中各个元素的分布、比例和位置关系。
画面构图的好坏直接影响到观众对画面的感受和理解。
构图中的元素包括前景、中景和背景,以及主体对象的位置、大小和姿态。
2.颜色和色彩搭配:颜色在一帧中起到了直接渲染画面情感和氛围的作用。
不同的色彩搭配能够营造出不同的情绪和场景。
冷色调通常用于表达沉郁、忧伤等情绪,而暖色调则能够传递温暖和欢快的感觉。
3.光线和阴影:光线是构成一帧的重要元素之一,它可以创造出各种不同的光影效果。
光线的亮度、颜色和方向都会直接影响画面的观感。
合理运用光线和阴影可以增强画面的层次感和立体感,使画面更加有趣和生动。
4.动作和姿态:动作和姿态是人物形象塑造的重要元素。
通过人物在一帧中的动作和姿态,可以传达出他们的情感、身份和性格特点。
合理安排人物的动作和姿态,可以使画面更有张力和戏剧性。
5.特效和细节:特效和细节是构成一帧的重要元素,它们能够增强画面的表现力和视觉效果。
特效可以是爆炸、火焰、风雨等自然现象,也可以是一些特殊的动画效果。
细节则是画面中的一些小物件和小动作,这些细节能够让画面更加真实、生动和精致。
6.文字和字幕:文字和字幕是一帧中传递信息和交代剧情的重要方式之一、通过在画面中加入文字和字幕,观众能够更好地理解画面中所发生的事情。
文字和字幕的字体、大小和位置等都需要经过精心设计,以保证文字的清晰度和易读性。
帧长度

最小长度60字节包含14字节的以太网帧头,但是不包括4个字节的以太网帧尾。
有一些书把最小长度定为64字节,它包括以太网的帧尾。
我们把最小长度定为46字节,是有意不包括14字节的帧首部,因为对应的最大长度(1500字节)指的是MTU—最大传输单元。
IPV6与IPV4比较在哪些新的特点一、扩展了路由和寻址的能力IPv6 把IP 地址由32 位增加到128 位,从而能够支持更大的地址空间,估计在地球表面每平米有4*10^18 个IPv6 地址,使IP 地址在可预见的将来不会用完。
IPv6 地址的编码采用类似于CIDR 的分层分级结构,如同电话号码。
简化了路由,加快了路由速度。
在多点传播地址中增加了一个“范围”域,从而使多点传播不仅仅局限在子网内,可以横跨不同的子网,不同的局域网。
二、报头格式的简化IPv 4 报头格式中一些冗余的域或被丢弃或被列为扩展报头,从而降低了包处理和报头带宽的开销。
虽然IPv6 的地址是IPv4 地址的 4 倍。
但报头只有它的 2 倍大。
三、对可选项更大的支持IPv6 的可选项不放入报头,而是放在一个个独立的扩展头部。
如果不指定路由器不会打开处理扩展头部. 这大大改变了路由性能。
IPv6 放宽了对可选项长度的严格要求(IPv4 的可选项总长最多为40 字节) ,并可根据需要随时引入新选项。
IPV6 的很多新的特点就是由选项来提供的,如对IP 层安全(IPSEC) 的支持,对巨报(jumbogram) 的支持以及对IP 层漫游(Mobile-IP) 的支持等。
四、QoS 的功能因特网不仅可以提供各种信息,缩短人们的距离. 还可以进行网上娱乐。
网上VOD 现正被商家炒得热火朝天,而大多还只是准VOD 的水平,且只能在局域网上实现,因特网上的VOD 都很不理想. 问题在于IPv4 的报头虽然有服务类型的字段,实际上现在的路由器实现中都忽略了这一字段。
在IPv6 的头部,有两个相应的优先权和流标识字段,允许把数据报指定为某一信息流的组成部分,并可对这些数据报进行流量控制。
100000帧高速摄像机

日本ACS-1M60高速摄像机最大辨率下帧速:100000帧/秒。
最大分辨率:1280x896
最高帧速:22万帧/秒
最高像素:114万像素
Memrecam ACS-1M60为日本nac公司2019年新推出的新一代高速摄像机系统,拥有最高114万像素,并在该满幅分辨率下帧速达100000帧/秒,最高速度可达220000帧/秒。
Memrecam ACS-1M60为用户的需求提供了优选的解决方案:高感光度及更快的拍摄速度。
特点
CMOS传感器:最大分辨率1280X896
感光度(ISO):100000
1280x192@220000fps
位深度:12/10/8位(可选)
电子快门:自适应<1.1μsec
帧数可调:实验中可连续或并行地调节多种帧速
多种触发模式:脉冲触发,多次触发,重置触发及图像触发
机械快门自动校正
由在21X16像素的最小区域感测到的强度偏移触发
双段记录模式:1x和1/2~1/100x
超高光灵敏度
外壳坚固:适用于各种场景
武汉中创联达科技有限公司,是日本NAC中国核心代理商。
我公司专业从事光电子影像产品(低照度相机、高速摄像机,超高速摄像机,高分辨率相机及其图像分析软件)的销售、研发,提供特殊环境下的拍摄、成像服务。
USB2.0与OTG规范及开发指南(全中文)(1)

吉尼斯纪录大全名单

吉尼斯纪录大全名单吉尼斯世界纪录,是一本全球性的世界纪录大全,它收录了全球各种各样的惊人纪录。
这些纪录涵盖了人类的各个领域,包括自然界、科技、体育、艺术等等。
下面,我们将为大家介绍一些吉尼斯纪录大全名单中的惊人纪录。
1. 最高的山峰,珠穆朗玛峰,位于喜马拉雅山脉,海拔8848米,是世界上海拔最高的山峰。
2. 最长的河流,亚马逊河,全长约6950公里,是世界上最长的河流,流经南美洲多个国家。
3. 最大的陆地动物,非洲象,体重可达6吨,是世界上体型最大的陆地动物。
4. 最快的动物,猎豹,时速可达112公里,是世界上奔跑速度最快的动物。
5. 最多产的艺术家,巴赫,德国作曲家,创作了大量音乐作品,被誉为史上最多产的音乐家。
6. 最长时间连续阅读,Howard Berg,美国人,他连续阅读了500小时,创下了吉尼斯世界纪录。
7. 最大的花坛,迪拜的迪拜蓝湾酒店建造了世界上最大的花坛,面积达到了39,000平方米。
8. 最高的建筑,迪拜塔,高828米,是世界上最高的建筑物。
9. 最长的海岸线,加拿大,拥有世界上最长的海岸线,总长达到202,080公里。
10. 最大的冰川,南极洲的兰森冰川,面积达到了487,000平方公里,是世界上最大的冰川。
11. 最多产的作家,塞壬·克里斯蒂,英国作家,创作了66部侦探小说,被誉为史上最多产的作家之一。
12. 最大的动物群落,南极洲的帝企鹅,拥有世界上最大的动物群落,数量达到了几百万只。
13. 最长的隧道,瑞士的哥达德隧道,全长57.1公里,是世界上最长的铁路隧道。
14. 最高的瀑布,委内瑞拉的安赫尔瀑布,高979米,是世界上最高的瀑布。
15. 最大的城市,东京,人口超过了3800万,是世界上最大的城市之一。
以上就是吉尼斯纪录大全名单中的一部分惊人纪录。
这些纪录向我们展示了人类和自然界的不可思议之处,也激励着我们不断探索、创新,创造更多的奇迹。
让我们一起为这个美丽而神奇的世界而自豪吧!。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
好了,在开始第一天的行程之前,请先打开您最惯用的编程工具吧:VisualStudio? CodeBlocks?UltraEdit?SourceInsight?Emacs?Vim?或者只是附件里那个制作低劣的记事 本 … … 总 之 请 打 开 它 们 , 打 开 OpenSceneGraph-2.6.0 的 源 代 码 文 件 夹 , 打 开
new osgViewer::GraphicsWindowWin32::WindowData(hWnd); traits->x = 0; traits->y = 0; …… traits->inheritedWindowData = windata; osg::GraphicsContext* gc = osg::GraphicsContext::createGraphicsContext(traits.get()); Camera* camera = viewer.getCamera(); camera->setGraphicsContext(gc); …… viewer.setCamera(camera); 这个过程虽然比较繁杂,但是顺序还是十分清楚的:首先设置嵌入窗口的特性(Traits), 例如 X、Y 位置,宽度和高度,以及父窗口的句柄(inheritedWindowData);然后根据特性 的设置创建一个新的图形设备上下文(GraphicsContext),将其赋予场景所用的摄像机。而 我们在 getContexts 函数中所要获取的,也许就包括这样一个用户建立的 GraphicsContext 设 备。
_cameraManipulator->init(*initEvent, *this); 从变量的名称可以猜测出_eventQueue 的功能,它用于储存该视景器的事件队列。OSG 中代表事件的类是 osgGA::GUIEventAdapter,它可以用于表达各种类型的鼠标、键盘、触压 笔和窗口事件。在用户程序中,我们往往通过继承 osgGA::GUIEventHandler 类,并重写 handle 函数的方法,获取实时的鼠标/键盘输入,并进而实现相应的用户代码(参见 osgkeyboardmouse)。 _eventQueue 除了保存一个 GUIEventAdapter 的链表之外,还提供了一系列对链表及其 元素的操作函数,这其中,createEvent 函数的作用是分配和返回一个新的 GUIEventAdapter 事件的指针。 随后,这个新事件的类型被指定为 FRAME 事件,即每帧都会触发的一个事件。 那么,_cameraManipulator 呢?没错,它就是视景器中所用的场景漫游器的实例。通常 我 们 都 会 使 用 setCameraManipulator 来 设 置 这 个 变 量 的 内 容 , 例 如 轨 迹 球 漫 游 器 (TrackballManipulator)可以使用鼠标拖动来观察场景,而驾驶漫游器(DriveManipulator) 则使用类似于汽车驾驶的效果来实现场景的漫游。 上面的代码将新创建的 FRAME 事件和 Viewer 对象本身传递给_cameraManipulator 的 init 函数,不同的漫游器(如 TrackballManipulator、DriveManipulator)会重写各自的 init 函 数,实现自己所需的初始化工作。如果读者希望自己编写一个场景的漫游器,那么覆写并使 用 osgGA::MatrixManipulator::init 就可以灵活地初始化自定义漫游器的功能了,它的调用时 机就在这里。 那么,回到 viewerInit 函数……很好,这次似乎没有更多的内容了。没想到一个短短的 函数竟然包含了那么多的信息,看来草率地阅读还真是使不得。
好了,废话不再多说。我们这就开始。
当前位置:osgViewer/ViewerBase.cpp 第 571 行,osgViewer::ViewerBase::frame() frame 函数的内容本身几乎一眼就可以看完。不过要注意的是,这个函数是 ViewerBase 类的成员函数,而非 Viewer 类。因此,无论对于单视景器的 Viewer 类,还是多视景器的 CompositeViewer 类,frame 函数的内容都是相同的(因为它们都没有再重写这个函数的内容)。 该函数所执行的主要工作如下: 1、如果这是仿真系统启动后的第一帧,则执行 viewerInit();此时如果还没有执行 realize() 函数,则执行它。 2、执行 advance 函数。 3、执行 eventTraversal 函数,顾名思义,这个函数将负责处理系统产生的各种事件,诸 如鼠标的移动,点击,键盘的响应,窗口的关闭等等,以及摄像机与场景图形的事件回调 (EventCallback)。 4、执行 updateTraversal 函数,这个函数负责遍历所有的更新回调(UpdateCallback); 除此之外,它的另一个重要任务就是负责更新 DatabasePager 与 ImagePager 这两个重要的分 页数据处理组件。 5、执行 renderingTraversals 函数,这里将使用较为复杂的线程处理方法,完成场景的筛 选(cull)和绘制(draw)工作。 下面我们就按照 1~5 的顺序,开始我们的源代码解读之旅。
解读成果: osgGA::EventQueue::createEvent,osgGA::MatrixManipulator::init,osgViewer::View::init, osgViewer::Viewer::viewerInit。 悬疑列表: 无。
第二日
当前位置:osgViewer/Viewer.cpp 第 385 行,osgViewer::Viewer::realize() Viewer::realize 函数是我们十分熟悉的另一个函数,从 OSG 问世以来,我们就习惯于在 进入仿真循环之前调用它(现在的 OSG 会自动调用这个函数,如果我们忘记的话),以完成 窗口和场景的“设置”工作。那么,什么叫做“设置”,这句简单的场景设置又包含了多少 内容呢?艰辛的旅程就此开始吧。 首先是一行:setCameraWithFocus(0),其内容无非是设置类变量_cameraWithFocus 指向 的内容为 NULL。至于这个“带有焦点的摄像机”是什么意思,我们似乎明白,似乎又不明 白,就先放入一个“悬疑列表”(Todo List)中好了。 下面遇到的函数就比较重要了,因为我们将会在很多地方遇到它: Contexts contexts; getContexts(contexts); 变量 contexts 是一个保存了 osg::GraphicsContext 指针的向量组,而 Viewer::getContexts
当前位置:osgViewer/View.cpp 第 227 行,osgViewer::View::init() Viewer::viewerInit 函数只做了一件事,就是调用 View::init()函数,而这个 init 函数的工 作似乎也是一目了然的:无非就是完成视景器的初始化工作而已。 不过在我们离开这个函数,继续我们的旅程之前,还是仔细探究一下,这个初始化工作 到底包含了什么? 阅读某个函数的源代码过程中,如果能够大致知道这个函数的主要工作,并了解其中用 到的变量的功能,那么即使只有很少的注释内容,应该也可以顺利地读完所有代码。如果对 一些命名晦涩的变量不甚理解,或者根本不知道这个函数于运行流程中有何用途,那么理解 源代码的过程就会麻烦很多。 View::init 函数中出现了两个重要的类成员变量:_eventQueue 和_cameraManipulator, 并且还将一个 osgGA::GUIEventAdapter 的实例传入后者的初始化函数。 代码如下:
不过不用担心,如果您已经耐着性子读到了这里,并且已经看到了 ViewerBase.cpp 中总 共 752 行规规矩矩的代码,那么我会尽全力协助您继续走完漫长的一帧的旅程,并在其中把 自己所知所得(不仅仅局限于那个该死的 frame 函数,而是遍及 OSG 的方方面面)全数灌 输给您。当然也希望您尽全力给我以打压、批评和指正,我只是一个普普通通的梦想着先找 个女朋友成家立业的毛头小子而已,如果我的话全都是对的,那么那些真正的图形学权威们 一定都住在寒风刺骨的珠穆朗玛峰顶上。
对 OSG 有所了解之后,我们也许可以很快地回答这个问题,正如下面的代码所示: while (!viewer.done())
viewer.frame(); 就这样,用一个循环结构来反复地执行 frame()函数,直到 done()函数的返回值为 true 为止。每一次执行 frame()函数就相当于完成了 OSG 场景渲染的一帧,配置较好的计算机可 以达到每秒钟一二百帧的速率,而通常仿真程序顺利运行的最低帧速在 15~25 帧/秒即可。 很好,看来笔者的机器运行 frame()函数通常只需要 8~10ms 左右,比一眨眼的工夫都要 短。那么本文就到此结束吗? 答案当然是否定的,恰恰相反,这篇繁琐且可能错误百出的文字,其目的正是要深入 frame()函数,再深入函数中调用的函数……一直挖掘下去,直到我们期待的瑰宝出现;当然 也可能是一无所获,只是乐在其中。 这样的探索要到什么时候结束呢?从这短短的 10 毫秒中引申出来的,无比冗长的一帧, 又是多么丰富抑或无聊的内容呢?现在笔者也不知道,也许直到最后也不会明了,不过相信 深入源代码的过程就是一种享受,希望读者您也可以同我一起享受这份辛苦与快乐。 源代码版本:OpenSceneGraph 2.6.0;操作系统环境假设为 Win32 平台。为了保证教程 的篇幅不致被过多程序代码所占据,文中会适当地改写和缩编所列出的代码,仅保证其执行 效果不变,因此可能与实际源文件的内容有所区别。 由于作者水平和精力所限,本文暂时仅对单视景器(即使用 osgViewer::Viewer 类)的 情形作出介绍。 转载请注明作者和 本文在写作过程中将会用到一些专有名词,它们可能与读者阅读的其它文章中所述有所 差异,现列举如下: 场景图形-SceneGraph;场景子树-Subgraph;节点-Node;摄像机-Camera;渲染器-Renderer; 窗口-Window;视口-Viewport;场景-Scene;视图-View;视景器-Viewer;漫游器-Manipulator; 访问器-Visitor;回调-Callback;事件-Event;更新-Update;筛选-Cull;绘制-Draw。