Ae内部时间定义:A_Time
(本文未经许可禁止转载)
分数式定义
在Ae SDK CC 2017
中,时间被定义为如下这种形式:
typedef struct {
A_long value;
A_u_long scale;
} A_Time;
一般的软件中,我们会倾向于把时间定义为double(秒)
的形式,但对于非常大的时间数据来说,double
难免会存在浮点误差,Ae的这种定义是采用分数定义的。我们获取秒的方法很简单:
A_Time aetime;
/* 从AEGP套件获取Ae时间数据*/
double sec_time = ( (double)aetime.value )/((double) aetime.scale )
最后这里的sec_time
就是A_Time
的直观秒数据。
Ae这里的设计方式会把时间误差产生的位置从Ae主体转移(甩锅)到插件上。不过从另一个角度上也看出Ae在时间设计这上面的良苦用心233。
从PF插件框架获取合成时间
一般在渲染函数(Smart render
)里,我们通过in_data
获取的time_value
和time_scale
只是插件所在图层的图层时间
,而图层时间不会随用户平移图层而发生改变。
有些时候我们希望插件能获取到图层所在的合成的总时间,这时候就需要用到AEGP插件框架下的函数帮我们逐一获取我们想要的数据。
以下是
PixelsWorld
工程中使用的获取合成时间的源码
do
{
A_Time comptime;
ERR(suites.PFInterfaceSuite1()->AEGP_ConvertEffectToCompTime(
in_data->effect_ref,
in_data->time_step,
in_data->time_scale,
&comptime));
}while(0);
最后我们再把comptime
拿去做我们想要的处理即可。
举例
最后,我们观察一下以下图层的A_Time
信息
Debug 结果
键 | 值 |
---|---|
in_data->current_time | 12000 |
in_data->time_scale | 23976 |
comptime.value | 24000 |
comptime.scale | 23976 |
结论
time_scale
的值没有和fps
的直观转换方式。比如我们上面的图的帧率是29.97
,但scale值并没有出现诸如29970
之类的形式。- 但是
time_scale
的存在能保证目前时间数据是足够精准的。
获取fps数据
那么我们怎么获取fps
数据呢?这里就需要我们进行以下操作逐一获取fps
下面的代码也是在
PixelsWorld
中服役的源码
AEGP_LayerH layerH;
ERR(suites.PFInterfaceSuite1()->AEGP_GetEffectLayer(in_data->effect_ref, &layerH));
AEGP_CompH compH;
ERR(suites.LayerSuite8()->AEGP_GetLayerParentComp(layerH,&compH));
A_FpLong fps;
ERR(suites.CompSuite11()->AEGP_GetCompFramerate(compH, &fps));
Time scale的计算方法
虽然前面说scale
好像没有统一的公式能计算它。但是我们仍能猜测出Ae是怎么算出它的。它的基本公式如下:
Scale=Step \times Fps
其中这里的Fps
不是浮点数,是十进制小数。新出现的Step
目前只能看出来是Ae随性定义的(它在in_data->time_step
)。Ae保证这两个数相乘出来的Scale
一定是个足够大的整数。
一些测试数据
我测了两个fps下的scale和step
- fps:29.97, step:800,scale:23976
- fps:60, step:512,scale:30720
他们均满足上面的等式。
两帧之间的关键帧
我们时常会看到有一些奇葩的工程,关键帧出现在两帧之间,其实这就是因为两帧之间还存在step
个细分单位允许继续分配关键帧。比如fps为60的时候,step为512。那么这时两个帧之间理论上就有511
个等均的位置可以分配关键帧。