///|
/// Render-layer metadata that connects motion sampling to an application
/// renderer without depending on a graphics backend.
pub enum RenderLayerKind2 {
BackgroundLayer
GeometryLayer
SpriteLayer
TextLayer
ParticleLayer
EffectLayer
} derive(Debug)
///|
pub fn render_layer_kinds2() -> Array[RenderLayerKind2] {
[
BackgroundLayer,
GeometryLayer,
SpriteLayer,
TextLayer,
ParticleLayer,
EffectLayer,
]
}
///|
pub struct RenderLayer2 {
id : Int
name : String
kind : RenderLayerKind2
order : Int
visible : Bool
opacity : Double
blend : BlendMode
bounds : Bounds2D
} derive(Debug)
///|
pub fn render_layer2(
id : Int,
name : String,
kind : RenderLayerKind2,
order : Int,
bounds : Bounds2D,
) -> RenderLayer2 {
{ id, name, kind, order, visible: true, opacity: 1.0, blend: Normal, bounds }
}
///|
pub fn RenderLayer2::id(self : RenderLayer2) -> Int {
self.id
}
///|
pub fn RenderLayer2::name(self : RenderLayer2) -> String {
self.name
}
///|
pub fn RenderLayer2::kind(self : RenderLayer2) -> RenderLayerKind2 {
self.kind
}
///|
pub fn RenderLayer2::order(self : RenderLayer2) -> Int {
self.order
}
///|
pub fn RenderLayer2::visible(self : RenderLayer2) -> Bool {
self.visible
}
///|
pub fn RenderLayer2::opacity(self : RenderLayer2) -> Double {
self.opacity
}
///|
pub fn RenderLayer2::blend(self : RenderLayer2) -> BlendMode {
self.blend
}
///|
pub fn RenderLayer2::bounds(self : RenderLayer2) -> Bounds2D {
self.bounds
}
///|
pub fn RenderLayer2::with_visibility(
self : RenderLayer2,
visible : Bool,
) -> RenderLayer2 {
{
id: self.id,
name: self.name,
kind: self.kind,
order: self.order,
visible,
opacity: self.opacity,
blend: self.blend,
bounds: self.bounds,
}
}
///|
pub fn RenderLayer2::with_opacity(
self : RenderLayer2,
opacity : Double,
) -> RenderLayer2 {
{
id: self.id,
name: self.name,
kind: self.kind,
order: self.order,
visible: self.visible,
opacity: clamp01(opacity),
blend: self.blend,
bounds: self.bounds,
}
}
///|
pub fn RenderLayer2::with_blend(
self : RenderLayer2,
blend : BlendMode,
) -> RenderLayer2 {
{
id: self.id,
name: self.name,
kind: self.kind,
order: self.order,
visible: self.visible,
opacity: self.opacity,
blend,
bounds: self.bounds,
}
}
///|
pub struct RenderPass2 {
layer_id : Int
active : Bool
opacity : Double
clip_start : Double
clip_end : Double
world_bounds : Bounds2D
} derive(Debug)
///|
pub fn RenderPass2::layer_id(self : RenderPass2) -> Int {
self.layer_id
}
///|
pub fn RenderPass2::active(self : RenderPass2) -> Bool {
self.active
}
///|
pub fn RenderPass2::opacity(self : RenderPass2) -> Double {
self.opacity
}
///|
pub fn RenderPass2::clip_start(self : RenderPass2) -> Double {
self.clip_start
}
///|
pub fn RenderPass2::clip_end(self : RenderPass2) -> Double {
self.clip_end
}
///|
pub fn RenderPass2::world_bounds(self : RenderPass2) -> Bounds2D {
self.world_bounds
}
///|
pub struct RenderPlan2 {
layers : Array[RenderLayer2]
start : Double
end : Double
clear_color : Rgba
} derive(Debug)
///|
pub fn render_plan2(
start : Double,
end : Double,
clear_color : Rgba,
) -> RenderPlan2 {
{ layers: [], start, end: end.max(start), clear_color }
}
///|
pub fn RenderPlan2::layers(self : RenderPlan2) -> Array[RenderLayer2] {
self.layers.copy()
}
///|
pub fn RenderPlan2::start(self : RenderPlan2) -> Double {
self.start
}
///|
pub fn RenderPlan2::end(self : RenderPlan2) -> Double {
self.end
}
///|
pub fn RenderPlan2::clear_color(self : RenderPlan2) -> Rgba {
self.clear_color
}
///|
pub fn RenderPlan2::add_layer(self : RenderPlan2, layer : RenderLayer2) -> Bool {
for existing in self.layers {
if existing.id == layer.id {
return false
}
}
self.layers.push(layer)
self.layers.sort_by(fn(left, right) { left.order.compare(right.order) })
true
}
///|
pub fn RenderPlan2::remove_layer(self : RenderPlan2, id : Int) -> Bool {
for index in 0.. RenderLayer2? {
for layer in self.layers {
if layer.id == id {
return Some(layer)
}
}
None
}
///|
pub fn RenderPlan2::active_layers(
self : RenderPlan2,
time : Double,
) -> Array[RenderLayer2] {
let result : Array[RenderLayer2] = []
if time < self.start || time > self.end {
return result
}
for layer in self.layers {
if layer.visible && layer.opacity > 0.0 {
result.push(layer)
}
}
result
}
///|
pub fn RenderPlan2::passes(
self : RenderPlan2,
time : Double,
) -> Array[RenderPass2] {
let result : Array[RenderPass2] = []
for layer in self.layers {
let active = time >= self.start &&
time <= self.end &&
layer.visible &&
layer.opacity > 0.0
result.push({
layer_id: layer.id,
active,
opacity: if active {
layer.opacity
} else {
0.0
},
clip_start: self.start,
clip_end: self.end,
world_bounds: layer.bounds,
})
}
result
}
///|
pub fn RenderPlan2::bounds(self : RenderPlan2) -> Bounds2D {
if self.layers.length() == 0 {
return { minimum: point2(x=0.0, y=0.0), maximum: point2(x=0.0, y=0.0) }
}
let mut result = self.layers[0].bounds
for index in 1.. RenderPlan2 {
{
layers: self.layers.copy(),
start: self.start + delta,
end: self.end + delta,
clear_color: self.clear_color,
}
}
///|
pub struct RenderFrame2 {
time : Double
passes : Array[RenderPass2]
clear_color : Rgba
visible_count : Int
} derive(Debug)
///|
pub fn RenderFrame2::time(self : RenderFrame2) -> Double {
self.time
}
///|
pub fn RenderFrame2::passes(self : RenderFrame2) -> Array[RenderPass2] {
self.passes.copy()
}
///|
pub fn RenderFrame2::clear_color(self : RenderFrame2) -> Rgba {
self.clear_color
}
///|
pub fn RenderFrame2::visible_count(self : RenderFrame2) -> Int {
self.visible_count
}
///|
pub fn RenderPlan2::frame(self : RenderPlan2, time : Double) -> RenderFrame2 {
let passes = self.passes(time)
let mut visible_count = 0
for pass in passes {
if pass.active {
visible_count = visible_count + 1
}
}
{ time, passes, clear_color: self.clear_color, visible_count }
}
///|
pub struct RenderPlanStats2 {
layer_count : Int
visible_count : Int
total_area : Double
start : Double
end : Double
} derive(Debug)
///|
pub fn RenderPlanStats2::layer_count(self : RenderPlanStats2) -> Int {
self.layer_count
}
///|
pub fn RenderPlanStats2::visible_count(self : RenderPlanStats2) -> Int {
self.visible_count
}
///|
pub fn RenderPlanStats2::total_area(self : RenderPlanStats2) -> Double {
self.total_area
}
///|
pub fn RenderPlanStats2::start(self : RenderPlanStats2) -> Double {
self.start
}
///|
pub fn RenderPlanStats2::end(self : RenderPlanStats2) -> Double {
self.end
}
///|
pub fn RenderPlan2::stats(self : RenderPlan2) -> RenderPlanStats2 {
let mut area = 0.0
let mut visible = 0
for layer in self.layers {
let width = layer.bounds.maximum().x() - layer.bounds.minimum().x()
let height = layer.bounds.maximum().y() - layer.bounds.minimum().y()
area = area + width * height
if layer.visible && layer.opacity > 0.0 {
visible = visible + 1
}
}
{
layer_count: self.layers.length(),
visible_count: visible,
total_area: area,
start: self.start,
end: self.end,
}
}
///|
pub enum RenderQuality2 {
PreviewQuality
DraftQuality
FinalQuality
} derive(Debug)
///|
pub fn render_qualities2() -> Array[RenderQuality2] {
[PreviewQuality, DraftQuality, FinalQuality]
}
///|
pub fn quality_sample_count2(quality : RenderQuality2) -> Int {
match quality {
PreviewQuality => 16
DraftQuality => 64
FinalQuality => 256
}
}