Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 12 additions & 6 deletions inox2d/src/formats/payload.rs
Original file line number Diff line number Diff line change
Expand Up @@ -176,8 +176,8 @@ fn deserialize_simple_physics(obj: JsonObject) -> InoxParseResult<SimplePhysics>
}

fn deserialize_drawable(obj: JsonObject) -> InoxParseResult<Drawable> {
Ok(Drawable {
blending: Blending {
Ok(Drawable::new(
Blending {
mode: match obj.get_str("blend_mode")? {
"Normal" => BlendMode::Normal,
"Multiply" => BlendMode::Multiply,
Expand All @@ -192,7 +192,7 @@ fn deserialize_drawable(obj: JsonObject) -> InoxParseResult<Drawable> {
screen_tint: obj.get_vec3("screenTint").unwrap_or(vec3(0.0, 0.0, 0.0)),
opacity: obj.get_f32("opacity").unwrap_or(1.0),
},
masks: {
{
if let Ok(masks) = obj.get_list("masks") {
Some(Masks {
threshold: obj.get_f32("mask_threshold").unwrap_or(0.5),
Expand All @@ -209,7 +209,7 @@ fn deserialize_drawable(obj: JsonObject) -> InoxParseResult<Drawable> {
None
}
},
})
))
}

fn deserialize_mesh(obj: JsonObject) -> InoxParseResult<Mesh> {
Expand Down Expand Up @@ -446,6 +446,7 @@ fn deserialize_binding_values(param_name: &str, values: &[JsonValue]) -> InoxPar
"zSort" => BindingValues::ZSort(deserialize_inner_binding_values(values)?),
"transform.t.x" => BindingValues::TransformTX(deserialize_inner_binding_values(values)?),
"transform.t.y" => BindingValues::TransformTY(deserialize_inner_binding_values(values)?),
"transform.t.z" => BindingValues::TransformTZ(deserialize_inner_binding_values(values)?),
"transform.s.x" => BindingValues::TransformSX(deserialize_inner_binding_values(values)?),
"transform.s.y" => BindingValues::TransformSY(deserialize_inner_binding_values(values)?),
"transform.r.x" => BindingValues::TransformRX(deserialize_inner_binding_values(values)?),
Expand All @@ -464,8 +465,13 @@ fn deserialize_binding_values(param_name: &str, values: &[JsonValue]) -> InoxPar

BindingValues::Deform(Matrix2d::from_slice_vecs(&parsed, true)?)
}
// TODO
"opacity" => BindingValues::Opacity,
"tint.r" => BindingValues::TintR(deserialize_inner_binding_values(values)?),
"tint.g" => BindingValues::TintG(deserialize_inner_binding_values(values)?),
"tint.b" => BindingValues::TintB(deserialize_inner_binding_values(values)?),
"screenTint.r" => BindingValues::ScreenTintR(deserialize_inner_binding_values(values)?),
"screenTint.g" => BindingValues::ScreenTintG(deserialize_inner_binding_values(values)?),
"screenTint.b" => BindingValues::ScreenTintB(deserialize_inner_binding_values(values)?),
"opacity" => BindingValues::Opacity(deserialize_inner_binding_values(values)?),
param_name => return Err(InoxParseError::UnknownParamName(param_name.to_owned())),
})
}
Expand Down
10 changes: 9 additions & 1 deletion inox2d/src/math/interp.rs
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,15 @@ fn interpolate_linear(t: f32, range_in: InterpRange<f32>, range_out: InterpRange
range_in.end,
);

(t - range_in.beg) * (range_out.end - range_out.beg) / (range_in.end - range_in.beg) + range_out.beg
let range_out_delta = range_out.end - range_out.beg;
let range_in_delta = range_in.end - range_in.beg;
if range_out_delta == 0.0 {
// Calculus teachers HATE this ONE WEIRD TRICK to getting rid of
// divide-by-zero errors in your code!
return range_out.beg;
}

(t - range_in.beg) * range_out_delta / range_in_delta + range_out.beg
}

#[inline]
Expand Down
22 changes: 22 additions & 0 deletions inox2d/src/node/components.rs
Original file line number Diff line number Diff line change
Expand Up @@ -30,10 +30,32 @@ pub struct Composite {}
/// If has this as a component, the node should render something
pub struct Drawable {
pub blending: Blending,

/// The original parameters for this drawable.
/// Copied over `blending` on reset.
initial_blending: Blending,

/// If Some, the node should consider masking when rendering
pub masks: Option<Masks>,
}

impl Drawable {
pub fn new(blending: Blending, masks: Option<Masks>) -> Self {
Self {
blending,
initial_blending: blending,
masks,
}
}

/// Reset the drawable back to the initial configuration set when `new`
/// was called.
pub fn reset(&mut self) {
self.blending = self.initial_blending;
}
}

#[derive(Copy, Clone)]
pub struct Blending {
pub mode: BlendMode,
pub tint: Vec3,
Expand Down
79 changes: 70 additions & 9 deletions inox2d/src/params.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ use crate::math::{
matrix::Matrix2d,
};
use crate::node::{
components::{DeformSource, DeformStack, Mesh, TransformStore, ZSort},
components::{DeformSource, DeformStack, Drawable, Mesh, TransformStore, ZSort},
InoxNodeUuid,
};
use crate::puppet::{InoxNodeTree, Puppet, World};
Expand All @@ -26,14 +26,20 @@ pub enum BindingValues {
ZSort(Matrix2d<f32>),
TransformTX(Matrix2d<f32>),
TransformTY(Matrix2d<f32>),
TransformTZ(Matrix2d<f32>),
TransformSX(Matrix2d<f32>),
TransformSY(Matrix2d<f32>),
TransformRX(Matrix2d<f32>),
TransformRY(Matrix2d<f32>),
TransformRZ(Matrix2d<f32>),
Deform(Matrix2d<Vec<Vec2>>),
// TODO
Opacity,
TintR(Matrix2d<f32>),
TintG(Matrix2d<f32>),
TintB(Matrix2d<f32>),
ScreenTintR(Matrix2d<f32>),
ScreenTintG(Matrix2d<f32>),
ScreenTintB(Matrix2d<f32>),
Opacity(Matrix2d<f32>),
}

#[derive(Debug, Clone)]
Expand Down Expand Up @@ -142,6 +148,16 @@ impl Param {
.translation
.y += bi_interpolate_f32(val_normed, range_in, out_top, out_bottom, binding.interpolate_mode);
}
BindingValues::TransformTZ(ref matrix) => {
let (out_top, out_bottom) = ranges_out(matrix, x_mindex, x_maxdex, y_mindex, y_maxdex);

comps
.get_mut::<TransformStore>(binding.node)
.unwrap()
.relative
.translation
.z += bi_interpolate_f32(val_normed, range_in, out_top, out_bottom, binding.interpolate_mode);
}
BindingValues::TransformSX(ref matrix) => {
let (out_top, out_bottom) = ranges_out(matrix, x_mindex, x_maxdex, y_mindex, y_maxdex);

Expand Down Expand Up @@ -228,8 +244,48 @@ impl Param {
.expect("Nodes being deformed must have a DeformStack component.")
.push(DeformSource::Param(self.uuid), Deform::Direct(direct_deform));
}
// TODO
BindingValues::Opacity => {}
BindingValues::TintR(ref matrix) => {
let (out_top, out_bottom) = ranges_out(matrix, x_mindex, x_maxdex, y_mindex, y_maxdex);

comps.get_mut::<Drawable>(binding.node).unwrap().blending.tint.x *=
bi_interpolate_f32(val_normed, range_in, out_top, out_bottom, binding.interpolate_mode);
}
BindingValues::TintG(ref matrix) => {
let (out_top, out_bottom) = ranges_out(matrix, x_mindex, x_maxdex, y_mindex, y_maxdex);

comps.get_mut::<Drawable>(binding.node).unwrap().blending.tint.y *=
bi_interpolate_f32(val_normed, range_in, out_top, out_bottom, binding.interpolate_mode);
}
BindingValues::TintB(ref matrix) => {
let (out_top, out_bottom) = ranges_out(matrix, x_mindex, x_maxdex, y_mindex, y_maxdex);

comps.get_mut::<Drawable>(binding.node).unwrap().blending.tint.z *=
bi_interpolate_f32(val_normed, range_in, out_top, out_bottom, binding.interpolate_mode);
}
BindingValues::ScreenTintR(ref matrix) => {
let (out_top, out_bottom) = ranges_out(matrix, x_mindex, x_maxdex, y_mindex, y_maxdex);

comps.get_mut::<Drawable>(binding.node).unwrap().blending.screen_tint.x +=
bi_interpolate_f32(val_normed, range_in, out_top, out_bottom, binding.interpolate_mode);
}
BindingValues::ScreenTintG(ref matrix) => {
let (out_top, out_bottom) = ranges_out(matrix, x_mindex, x_maxdex, y_mindex, y_maxdex);

comps.get_mut::<Drawable>(binding.node).unwrap().blending.screen_tint.y +=
bi_interpolate_f32(val_normed, range_in, out_top, out_bottom, binding.interpolate_mode);
}
BindingValues::ScreenTintB(ref matrix) => {
let (out_top, out_bottom) = ranges_out(matrix, x_mindex, x_maxdex, y_mindex, y_maxdex);

comps.get_mut::<Drawable>(binding.node).unwrap().blending.screen_tint.z +=
bi_interpolate_f32(val_normed, range_in, out_top, out_bottom, binding.interpolate_mode);
}
BindingValues::Opacity(ref matrix) => {
let (out_top, out_bottom) = ranges_out(matrix, x_mindex, x_maxdex, y_mindex, y_maxdex);

comps.get_mut::<Drawable>(binding.node).unwrap().blending.opacity *=
bi_interpolate_f32(val_normed, range_in, out_top, out_bottom, binding.interpolate_mode);
}
}
}
}
Expand Down Expand Up @@ -264,14 +320,19 @@ impl ParamCtx {
}
}

pub fn get(&self, param_name: &str) -> Result<Vec2, SetParamError> {
if let Some(value) = self.values.get(param_name) {
Ok(*value)
} else {
Err(SetParamError::NoParameterNamed(param_name.to_string()))
}
}

/// Modify components as specified by all params. Must be called ONCE per frame.
pub(crate) fn apply(&self, params: &HashMap<String, Param>, nodes: &InoxNodeTree, comps: &mut World) {
// a correct implementation should not care about the order of `.apply()`
for (param_name, val) in self.values.iter() {
// TODO: a correct implementation should not fail on param value (0, 0)
if *val != Vec2::ZERO {
params.get(param_name).unwrap().apply(*val, nodes, comps);
}
params.get(param_name).unwrap().apply(*val, nodes, comps);
}
}
}
Expand Down
6 changes: 5 additions & 1 deletion inox2d/src/render.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ use std::collections::HashSet;
use std::mem::swap;

use crate::node::{
components::{DeformStack, Mask, Masks, ZSort},
components::{DeformStack, Drawable, Mask, Masks, ZSort},
drawables::{CompositeComponents, DrawableKind, TexturedMeshComponents},
InoxNodeUuid,
};
Expand Down Expand Up @@ -129,6 +129,10 @@ impl RenderCtx {
if let Some(deform_stack) = comps.get_mut::<DeformStack>(node.uuid) {
deform_stack.reset();
}

if let Some(drawable) = comps.get_mut::<Drawable>(node.uuid) {
drawable.reset();
}
}
}

Expand Down
Loading