1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
use crate::*;
use crate::aegp::*;
use ae_sys::PF_ProgPtr;
define_suite!(
/// These functions provide a way for effects (and AEGPs) to obtain information about the context of an applied effect.
/// ## Notes On Effect Context
/// Any time you modify or rely on data from outside the normal render pipeline, you run the risk of dependency problems.
///
/// There is no way for After Effects to know that you depend on this external information; consequently, you will not be notified if it changes out from under you.
PFInterfaceSuite,
AEGP_PFInterfaceSuite1,
kAEGPPFInterfaceSuite,
kAEGPPFInterfaceSuiteVersion1
);
impl PFInterfaceSuite {
/// Acquire this suite from the host. Returns error if the suite is not available.
/// Suite is released on drop.
pub fn new() -> Result<Self, Error> {
crate::Suite::new()
}
/// Obtain the layer handle of the layer to which the effect is applied.
pub fn effect_layer(&self, effect_ref: impl AsPtr<ae_sys::PF_ProgPtr>) -> Result<LayerHandle, Error> {
Ok(LayerHandle::from_raw(
call_suite_fn_single!(self, AEGP_GetEffectLayer -> ae_sys::AEGP_LayerH, effect_ref.as_ptr())?
))
}
/// Obtain the [`EffectRefHandle`] corresponding to the effect.
pub fn new_effect_for_effect(&self, effect_ref: impl AsPtr<PF_ProgPtr>, plugin_id: PluginId) -> Result<EffectRefHandle, Error> {
Ok(EffectRefHandle::from_raw(
call_suite_fn_single!(self, AEGP_GetNewEffectForEffect -> ae_sys::AEGP_EffectRefH, plugin_id, effect_ref.as_ptr())?
))
}
/// Retrieve the composition time corresponding to the effect's layer time.
pub fn convert_effect_to_comp_time(&self, effect_ref: impl AsPtr<PF_ProgPtr>, time: i32, time_scale: u32) -> Result<Time, Error> {
Ok(call_suite_fn_single!(self, AEGP_ConvertEffectToCompTime -> ae_sys::A_Time, effect_ref.as_ptr(), time, time_scale)?.into())
}
/// Obtain the camera (if any) being used by After Effects to view the effect's layer.
pub fn effect_camera(&self, effect_ref: impl AsPtr<PF_ProgPtr>, time: Time) -> Result<Option<LayerHandle>, Error> {
let camera_handle = call_suite_fn_single!(self, AEGP_GetEffectCamera -> ae_sys::AEGP_LayerH, effect_ref.as_ptr(), &time.into() as *const _)?;
if camera_handle.is_null() {
Ok(None)
} else {
Ok(Some(LayerHandle::from_raw(camera_handle)))
}
}
/// Obtain the transform used to move between the layer's coordinate space and that of the containing composition.
///
/// NOTE: In cases where the effect's input layer has square pixels, but is in a non-square pixel composition,
/// you must correct for the pixel aspect ratio by premultiplying the matrix by `(1/parF, 1, 1)`.
///
/// The model view for the camera matrix is inverse of the matrix obtained from [`effect_camera_matrix()`](Self::effect_camera_matrix).
///
/// Also note that our matrix is row-based; OpenGL's is column-based.
///
/// Returns a tuple containing: (matrix, dist_to_image_plane, image_plane_width, image_plane_height)
pub fn effect_camera_matrix(&self, effect_ref: impl AsPtr<PF_ProgPtr>, time: Time) -> Result<(Matrix4, f64, i16, i16), Error> {
let mut matrix: ae_sys::A_Matrix4 = unsafe { std::mem::zeroed() };
let mut dist_to_image_plane: f64 = 0.0;
let mut image_plane_width = 0;
let mut image_plane_height = 0;
call_suite_fn!(self, AEGP_GetEffectCameraMatrix, effect_ref.as_ptr(), &time.into() as *const _, &mut matrix, &mut dist_to_image_plane, &mut image_plane_width, &mut image_plane_height)?;
Ok((matrix.into(), dist_to_image_plane, image_plane_width, image_plane_height))
}
}