当前位置: 首页 > wzjs >正文

wap网站生成小程序百度竞价产品

wap网站生成小程序,百度竞价产品,桂林做网站哪家好,做暧暧网站免费注:软件版本Unity 6.0 Timeline 1.8.7 作者:CSDN RingleaderWang 原文:《Unity第25期——Timeline结构及其源码浅析》 文章首发Github👍:《Timeline结构及其源码浅析》 Bilibili 视频版👍👍&a…

注:软件版本Unity 6.0 + Timeline 1.8.7

作者:CSDN @ RingleaderWang
原文:《Unity第25期——Timeline结构及其源码浅析》
文章首发Github👍:《Timeline结构及其源码浅析》

Bilibili 视频版👍👍:《Timeline结构及其源码解析》https://www.bilibili.com/video/BV1bHjYzNE35

Unity的 Timeline 本质是一个包含很多可播放片段(Playable Clip)的区间树(IntervalTree),这个区间树可以排序、搜索、以及控制所有 Clip的激活与停止,最后利用底层的Playable系统,运行所激活的Clips,就是这么个东西。

(当然这么定义不够准确,IntervalTree不控制clip激活,只是排序和搜索clip。IntervalTree本质是装clip的容器,不考虑性能的话用数组也行。这么定义只是方便理解Timeline的底层结构罢了)

下面便详细解析下 IntervalTree 的结构。

TimelinePlayable利用IntervalTree来管理RuntimeClip,UML类图如下:

IntervalTree UML类图
  • m_Entries:记录所有 RuntimeClip 和其左右边界的List
  • m_Nodes:IntervalTree中的节点
    • node first/last: 表示存储在当前节点中的所有Runtimeclip中的首和尾index
    • center:排序前比较重要,表示待排序Runtimeclip左右边界中点,用于后续递归地进行二分排序
    • left/right:左右子节点

Build IntervalTree 逻辑:

private void Rebuild()
{m_Nodes.Clear();m_Nodes.Capacity = m_Entries.Capacity;Rebuild(0, m_Entries.Count - 1);
}private int Rebuild(int start, int end)
{IntervalTreeNode intervalTreeNode = new IntervalTreeNode();// minimum size, don't subdivideint count = end - start + 1;if (count < kMinNodeSize){intervalTreeNode = new IntervalTreeNode() { center = kCenterUnknown, first = start, last = end, left = kInvalidNode, right = kInvalidNode };m_Nodes.Add(intervalTreeNode);return m_Nodes.Count - 1;}var min = Int64.MaxValue;var max = Int64.MinValue;for (int i = start; i <= end; i++){var o = m_Entries[i];min = Math.Min(min, o.intervalStart);max = Math.Max(max, o.intervalEnd);}var center = (max + min) / 2;intervalTreeNode.center = center;// first pass, put every thing left of center, leftint x = start;int y = end;while (true){while (x <= end && m_Entries[x].intervalEnd < center)x++;while (y >= start && m_Entries[y].intervalEnd >= center)y--;if (x > y)break;var nodeX = m_Entries[x];var nodeY = m_Entries[y];m_Entries[y] = nodeX;m_Entries[x] = nodeY;}intervalTreeNode.first = x;// second pass, put every start passed the center righty = end;while (true){while (x <= end && m_Entries[x].intervalStart <= center)x++;while (y >= start && m_Entries[y].intervalStart > center)y--;if (x > y)break;var nodeX = m_Entries[x];var nodeY = m_Entries[y];m_Entries[y] = nodeX;m_Entries[x] = nodeY;}intervalTreeNode.last = y;// reserve a placem_Nodes.Add(new IntervalTreeNode());int index = m_Nodes.Count - 1;intervalTreeNode.left = kInvalidNode;intervalTreeNode.right = kInvalidNode;if (start < intervalTreeNode.first)intervalTreeNode.left = Rebuild(start, intervalTreeNode.first - 1);if (end > intervalTreeNode.last)intervalTreeNode.right = Rebuild(intervalTreeNode.last + 1, end);m_Nodes[index] = intervalTreeNode;return index;
}

构建思路非常简单:

  • 排序开始时,遍历所有Runtimeclip,确定最左端和最右端边界,然后取边界的中点作为根节点的center,这样构建的tree不至于一边短一边长。
  • 然后把所有Runtimeclip完全在中间值center左侧的放到m_Entries靠下位置,把所有Runtimeclip完全在中间值center右侧的放到m_Entries靠上位置,被center贯穿的Runtimeclip保留在当前节点中。
  • 这样就完成了初步排序,然后再递归地排序靠下的这坨,并作为左子节点;再递归地排序靠上的这坨,并作为右子节点。这样整棵IntervalTree就构建完成了。

最终结构如下图所示:

IntervalTree内部结构示例

RuntimeClip 结构

下面就以 AnimationClip 为例,讲解IntervalTreeNode中RuntimeClip的创建逻辑:

  1. 创建TimelineClip (主逻辑在TrackAsset)

    1. 根据TrackClipTypeAttribute的定义获取限定的ClipTypeGetType().GetCustomAttributes(typeof(TrackClipTypeAttribute))
    2. 创建限定ClipType的 TimelineClip 容器newClip = CreateNewClipContainerInternal()
    3. 把特定类型 ClipPlayableAsset 比如AnimationPlayableAsset塞进TimelineClip中asset参数中。(此时AnimationPlayableAsset中clip为null)
  2. 将具体AnimationClip塞进AnimationPlayableAsset的clip变量中AddClipOnTrack(newClip, parentTrack, candidateTime, assignableObject, state)

  3. 创建RuntimeClip (主逻辑在TrackAsset 的 CompileClips方法)

    1. 根据timelineClip和clip对应的Playable创建RuntimeClip
    2. 将新建的RuntimeClip加入区间树IntervalTree
  4. 重新排序区间树节点(可延迟执行)

最终,TimelineClip 与 RuntimeClip结构如下:

TimelineClip 与 RuntimeClip结构

运行时 IntervalTree

我们使用区间树 IntervalTree 最主要目的就是能快速搜索RuntimeClip,为什么呢?

因为每帧Timeline都会执行PrepareFrame方法,指明哪些clip在当前时间激活,哪些clip在当前时间停止,如果只是用List结构,搜索时间复杂度 O(n),而使用IntervalTree,时间复杂度便降到 O(logn)了。

TimelinePlayable PrepareFrame 方法执行逻辑:

  1. 利用IntervalTree获取当前帧所有激活的RuntimeClip
  2. disable上一帧激活,这一帧未激活的clip(会执行Playable的Pause()方法 )
  3. enable这一帧激活的clip(会执行Playable的Play()方法 )
  4. 根据mixin/mixout curve设置此clip所在的mixer input weight权重

http://www.dtcms.com/wzjs/76112.html

相关文章:

  • 用模板建商城购物网站百度获客平台怎么收费的
  • 做北美市场的外贸网站百度文库首页
  • 网站建设制作定制网站设计费用
  • 旅行网站定制公司推广公司是做什么的
  • python制作网站开发推广发帖网站
  • 软件开发前景和收入百度搜索优化建议
  • wordpress如何写网站seo排名影响因素主要有
  • 金塔精神文明建设网站seo网络推广优化教程
  • 如何快速提高网站排名资源平台
  • 网站为什么做重定向网络软文投放
  • 武汉软件网站建设怎么网站推广
  • 长沙精品网站建设公司百度网站关键词优化
  • 公司变更说明关键词优化有哪些作用
  • 响应式网站建设服务商百度首页优化
  • 网站建设方面的知识新闻媒体发布平台
  • 石家庄做网站优化网络推广网站程序
  • 昆山推广用什么网站比较好优化关键词是什么意思
  • 做网站做本地服务器吗佛山网络公司 乐云seo
  • 做网站需要花多少钱一个具体网站的seo优化
  • 专业做俄语网站建设司怎么看百度关键词的搜索量
  • 什么网站可以有人做详情页专业网络推广公司
  • 做java的源码网站小红书软文推广
  • 乌鲁木齐网站的建设网络推广的含义
  • 字画价格网站建设方案河北seo技术
  • wordpress模板 美女站诊断网站seo现状的方法
  • 网站模板搭建百度小程序关键词优化
  • 网站建设与开发网站定制开发
  • html怎么做移动端网站东莞免费建站公司
  • 网站界面设计毕业论文搜索引擎优化实训
  • 线上销售水果营销方案seo优化网站快速排名