///|
/// Deterministic frame clock for export and offline previews.
pub struct FrameSchedule2 {
start : Double
end : Double
frame_rate : Double
first_frame : Int
} derive(Debug)
///|
pub fn frame_schedule2(
start : Double,
end : Double,
frame_rate : Double,
first_frame? : Int = 0,
) -> FrameSchedule2 {
{ start, end: end.max(start), frame_rate: frame_rate.max(0.001), first_frame }
}
///|
pub fn FrameSchedule2::start(self : FrameSchedule2) -> Double {
self.start
}
///|
pub fn FrameSchedule2::end(self : FrameSchedule2) -> Double {
self.end
}
///|
pub fn FrameSchedule2::frame_rate(self : FrameSchedule2) -> Double {
self.frame_rate
}
///|
pub fn FrameSchedule2::duration(self : FrameSchedule2) -> Double {
self.end - self.start
}
///|
pub fn FrameSchedule2::frame_duration(self : FrameSchedule2) -> Double {
1.0 / self.frame_rate
}
///|
pub fn FrameSchedule2::frame_count(self : FrameSchedule2) -> Int {
@math.floor(self.duration() * self.frame_rate + 0.000001).to_int() + 1
}
///|
pub fn FrameSchedule2::time_at(self : FrameSchedule2, index : Int) -> Double {
self.start + index.to_double() * self.frame_duration()
}
///|
pub fn FrameSchedule2::index_at(self : FrameSchedule2, time : Double) -> Int {
@math.floor((time - self.start) * self.frame_rate + 0.5).to_int() +
self.first_frame
}
///|
pub fn FrameSchedule2::contains(self : FrameSchedule2, time : Double) -> Bool {
time >= self.start && time <= self.end
}
///|
pub fn FrameSchedule2::timestamps(self : FrameSchedule2) -> Array[Double] {
let values : Array[Double] = []
for index in 0.. Int {
self.index
}
///|
pub fn FrameStamp2::time(self : FrameStamp2) -> Double {
self.time
}
///|
pub fn FrameStamp2::duration(self : FrameStamp2) -> Double {
self.duration
}
///|
pub fn FrameSchedule2::stamp(self : FrameSchedule2, index : Int) -> FrameStamp2 {
{
index: self.first_frame + index,
time: self.time_at(index),
duration: self.frame_duration(),
}
}
///|
pub enum FrameChannel2 {
ScalarChannel
Point2Channel
Point3Channel
ColorChannel
Transform3Channel
} derive(Debug)
///|
pub fn frame_channels2() -> Array[FrameChannel2] {
[ScalarChannel, Point2Channel, Point3Channel, ColorChannel, Transform3Channel]
}
///|
pub struct FramePacket2 {
stamp : FrameStamp2
scalar_values : Array[Double]
point_values : Array[Point2]
point3_values : Array[Point3]
color_values : Array[Rgba]
transform_values : Array[Transform3D]
} derive(Debug)
///|
pub fn FramePacket2::stamp(self : FramePacket2) -> FrameStamp2 {
self.stamp
}
///|
pub fn FramePacket2::scalar_values(self : FramePacket2) -> Array[Double] {
self.scalar_values.copy()
}
///|
pub fn FramePacket2::point_values(self : FramePacket2) -> Array[Point2] {
self.point_values.copy()
}
///|
pub fn FramePacket2::point3_values(self : FramePacket2) -> Array[Point3] {
self.point3_values.copy()
}
///|
pub fn FramePacket2::color_values(self : FramePacket2) -> Array[Rgba] {
self.color_values.copy()
}
///|
pub fn FramePacket2::transform_values(
self : FramePacket2,
) -> Array[Transform3D] {
self.transform_values.copy()
}
///|
fn empty_frame_packet(stamp : FrameStamp2) -> FramePacket2 {
{
stamp,
scalar_values: [],
point_values: [],
point3_values: [],
color_values: [],
transform_values: [],
}
}
///|
pub fn FramePacket2::with_scalar(
self : FramePacket2,
value : Double,
) -> FramePacket2 {
let values = self.scalar_values.copy()
values.push(value)
{
stamp: self.stamp,
scalar_values: values,
point_values: self.point_values,
point3_values: self.point3_values,
color_values: self.color_values,
transform_values: self.transform_values,
}
}
///|
pub fn FramePacket2::with_point(
self : FramePacket2,
value : Point2,
) -> FramePacket2 {
let values = self.point_values.copy()
values.push(value)
{
stamp: self.stamp,
scalar_values: self.scalar_values,
point_values: values,
point3_values: self.point3_values,
color_values: self.color_values,
transform_values: self.transform_values,
}
}
///|
pub fn FramePacket2::with_point3(
self : FramePacket2,
value : Point3,
) -> FramePacket2 {
let values = self.point3_values.copy()
values.push(value)
{
stamp: self.stamp,
scalar_values: self.scalar_values,
point_values: self.point_values,
point3_values: values,
color_values: self.color_values,
transform_values: self.transform_values,
}
}
///|
pub fn FramePacket2::with_color(
self : FramePacket2,
value : Rgba,
) -> FramePacket2 {
let values = self.color_values.copy()
values.push(value)
{
stamp: self.stamp,
scalar_values: self.scalar_values,
point_values: self.point_values,
point3_values: self.point3_values,
color_values: values,
transform_values: self.transform_values,
}
}
///|
pub fn FramePacket2::with_transform(
self : FramePacket2,
value : Transform3D,
) -> FramePacket2 {
let values = self.transform_values.copy()
values.push(value)
{
stamp: self.stamp,
scalar_values: self.scalar_values,
point_values: self.point_values,
point3_values: self.point3_values,
color_values: self.color_values,
transform_values: values,
}
}
///|
pub struct FrameTable2 {
schedule : FrameSchedule2
packets : Array[FramePacket2]
} derive(Debug)
///|
pub fn FrameTable2::empty(schedule : FrameSchedule2) -> FrameTable2 {
{ schedule, packets: [] }
}
///|
pub fn FrameTable2::schedule(self : FrameTable2) -> FrameSchedule2 {
self.schedule
}
///|
pub fn FrameTable2::packets(self : FrameTable2) -> Array[FramePacket2] {
self.packets.copy()
}
///|
pub fn FrameTable2::length(self : FrameTable2) -> Int {
self.packets.length()
}
///|
pub fn FrameTable2::packet(self : FrameTable2, index : Int) -> FramePacket2 {
self.packets[index]
}
///|
pub fn FrameTable2::from_scalar(
schedule : FrameSchedule2,
track : ScalarTrack,
) -> FrameTable2 {
let packets : Array[FramePacket2] = []
for index in 0.. FrameTable2 {
let packets : Array[FramePacket2] = []
for index in 0.. FrameTable2 {
let packets : Array[FramePacket2] = []
for index in 0.. FrameTable2 {
let packets : Array[FramePacket2] = []
for index in 0.. FrameTable2 {
let packets : Array[FramePacket2] = []
for index in 0.. Rgba,
) -> FrameTable2 {
let packets : Array[FramePacket2] = []
for packet in self.packets {
let colors : Array[Rgba] = []
for color in packet.color_values {
colors.push(mapper(color))
}
packets.push({
stamp: packet.stamp,
scalar_values: packet.scalar_values,
point_values: packet.point_values,
point3_values: packet.point3_values,
color_values: colors,
transform_values: packet.transform_values,
})
}
{ schedule: self.schedule, packets }
}
///|
pub struct FrameDropReport2 {
expected : Int
actual : Int
missing : Int
duplicate : Int
maximum_gap : Int
} derive(Debug)
///|
pub fn FrameDropReport2::expected(self : FrameDropReport2) -> Int {
self.expected
}
///|
pub fn FrameDropReport2::actual(self : FrameDropReport2) -> Int {
self.actual
}
///|
pub fn FrameDropReport2::missing(self : FrameDropReport2) -> Int {
self.missing
}
///|
pub fn FrameDropReport2::duplicate(self : FrameDropReport2) -> Int {
self.duplicate
}
///|
pub fn FrameDropReport2::maximum_gap(self : FrameDropReport2) -> Int {
self.maximum_gap
}
///|
pub fn inspect_frame_indices(
schedule : FrameSchedule2,
indices : Array[Int],
) -> FrameDropReport2 {
let expected = schedule.frame_count()
if indices.length() == 0 {
return {
expected,
actual: 0,
missing: expected,
duplicate: 0,
maximum_gap: expected,
}
}
let mut duplicate = 0
let mut maximum_gap = 0
for index in 1.. (Double, Double) {
if self.packets.length() == 0 {
return (self.schedule.start, self.schedule.end)
}
(
self.packets[0].stamp.time,
self.packets[self.packets.length() - 1].stamp.time,
)
}