Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

MeshGroups. #103

Draft
wants to merge 6 commits into
base: main
Choose a base branch
from
Draft
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
8 changes: 8 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,2 +1,10 @@
# Rust
/target
/Cargo.lock

# Inochi2D project/model file
*.inp
*.inx

# renderdoc capture file
*.cap
1 change: 1 addition & 0 deletions .vscode/settings.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,5 +3,6 @@
"no-inline-html": false,
"first-line-heading": false
},
"cSpell.enabled": false,
// "rust-analyzer.cargo.target": "wasm32-unknown-unknown"
}
17 changes: 17 additions & 0 deletions inox2d/src/formats/payload.rs
Original file line number Diff line number Diff line change
Expand Up @@ -157,6 +157,7 @@ fn deserialize_simple_physics(obj: JsonObject) -> InoxParseResult<SimplePhysics>
map_mode: match obj.get_str("map_mode")? {
"AngleLength" => PhysicsParamMapMode::AngleLength,
"XY" => PhysicsParamMapMode::XY,
"YX" => PhysicsParamMapMode::YX,
unknown => return Err(InoxParseError::UnknownParamMapMode(unknown.to_owned())),
},

Expand Down Expand Up @@ -243,6 +244,15 @@ fn deserialize_transform(obj: JsonObject) -> InoxParseResult<TransformOffset> {
})
}

fn deserialize_meshgroup(obj: JsonObject) -> InoxParseResult<MeshGroup> {
Ok(MeshGroup {
dynamic: obj.get_bool("dynamic_deformation")?,
translate_children: obj.get_bool("translate_children")?,
})
}

// deserialization helpers

fn deserialize_f32s(val: &[json::JsonValue]) -> Vec<f32> {
val.iter().filter_map(JsonValue::as_f32).collect::<Vec<_>>()
}
Expand Down Expand Up @@ -333,6 +343,11 @@ impl Puppet {
"SimplePhysics" => {
self.node_comps.add(id, deserialize_simple_physics(data)?);
}
"MeshGroup" => {
self.node_comps.add(id, deserialize_meshgroup(data)?);
self.node_comps
.add(id, vals("mesh", deserialize_mesh(data.get_object("mesh")?))?);
}
custom => {
if let Some(func) = load_node_data_custom {
func(self, custom, data)?
Expand Down Expand Up @@ -454,6 +469,8 @@ fn deserialize_binding_values(param_name: &str, values: &[JsonValue]) -> InoxPar

BindingValues::Deform(Matrix2d::from_slice_vecs(&parsed, true)?)
}
// TODO
"opacity" => BindingValues::Opacity,
param_name => return Err(InoxParseError::UnknownParamName(param_name.to_owned())),
})
}
Expand Down
1 change: 1 addition & 0 deletions inox2d/src/math.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,3 +3,4 @@ pub mod deform;
pub mod interp;
pub mod matrix;
pub mod transform;
pub(crate) mod triangle;
Binary file added inox2d/src/math/bit_mask_test.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
45 changes: 44 additions & 1 deletion inox2d/src/math/deform.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use glam::Vec2;
use glam::{Mat2, Vec2};

/// Different kinds of deform.
// TODO: Meshgroup.
Expand All @@ -22,3 +22,46 @@ pub(crate) fn linear_combine<'deforms>(direct_deforms: impl Iterator<Item = &'de
.for_each(|(sum, addition)| *sum += *addition);
}
}

/// Input: two basis vectors `b0` and `b1`.
///
/// If the returned matrix is to be applied on a Vec2 V and X is obtained,
/// then `X.x * b0 + X.y * b1 = V`.
///
/// Panics if either basis is zero or they are not independent of each other.
pub fn vector_decompose_matrix(b0: Vec2, b1: Vec2) -> Mat2 {
// B X = V where:
// B: [ b0.x b1.x
// b0.y b1.y ]
// X: [ x
// y ]
// V: [ v.x
// v.y ]
// thus X = B^-1 V
let mat = Mat2::from_cols(b0, b1).inverse();
debug_assert_ne!(mat.determinant(), 0.0, "Provided two basis do not span the 2D plane.");
mat
}

/// Provide a parent triangle and its deforms by 3 points,
/// calculate how far should the provided points be moved by the triangle's deform.
///
/// For optimization, the "decompose_matrix" of parent should be provided, see `vector_decompose_matrix()`.
/// It is assumed that `parent[0]` is taken as the origin,
/// `parent[1] - parent[0]` is the first basis vector, and `parent[2] - parent[0]` the second.
#[inline]
pub fn deform_by_parent_triangle<'a>(
decompose_matrix: &'a Mat2,
parent_p0: Vec2,
parent_deforms: &'a [Vec2; 3],
points: impl Iterator<Item = &'a Vec2> + 'a,
) -> impl Iterator<Item = Vec2> + 'a {
let basis_0_deform = parent_deforms[1] - parent_deforms[0];
let basis_1_deform = parent_deforms[2] - parent_deforms[0];

points.map(move |p| {
let decomposed_coeffs = *decompose_matrix * (*p - parent_p0);
// deform by parent[0] + deform by basis change
parent_deforms[0] + decomposed_coeffs.x * basis_0_deform + decomposed_coeffs.y * basis_1_deform
})
}
Loading