diff --git a/node-graph/libraries/core-types/src/context.rs b/node-graph/libraries/core-types/src/context.rs index 2ee87a39..1ad2005f 100644 --- a/node-graph/libraries/core-types/src/context.rs +++ b/node-graph/libraries/core-types/src/context.rs @@ -334,7 +334,7 @@ impl ExtractPointer for OwnedContextImpl { } impl ExtractIndex for OwnedContextImpl { fn try_index(&self) -> Option> { - self.index.clone().map(|x| x.into_iter().rev()) + self.index.clone().map(|x| x.into_iter()) } } impl ExtractVarArgs for OwnedContextImpl { @@ -523,7 +523,7 @@ impl OwnedContextImpl { } pub fn with_index(mut self, index: usize) -> Self { if let Some(current_index) = &mut self.index { - current_index.push(index); + current_index.insert(0, index); } else { self.index = Some(vec![index]); } diff --git a/node-graph/nodes/vector/src/instance.rs b/node-graph/nodes/vector/src/instance.rs index f80a7fb5..e420946d 100644 --- a/node-graph/nodes/vector/src/instance.rs +++ b/node-graph/nodes/vector/src/instance.rs @@ -108,8 +108,18 @@ async fn instance_position(ctx: impl Ctx + ExtractVarArgs) -> DVec2 { // TODO: Return u32, u64, or usize instead of f64 after #1621 is resolved and has allowed us to implement automatic type conversion in the node graph for nodes with generic type inputs. // TODO: (Currently automatic type conversion only works for concrete types, via the Graphene preprocessor and not the full Graphene type system.) +/// Produces the index of the current iteration of a loop by reading from the evaluation context, which is supplied by downstream nodes such as *Instance Repeat*. +/// +/// Nested loops can enable 2D or higher-dimensional iteration by using the *Loop Level* parameter to read the index from outer levels of loops. #[node_macro::node(category("Instancing"), path(core_types::vector))] -async fn instance_index(ctx: impl Ctx + ExtractIndex, _primary: (), loop_level: u32) -> f64 { +async fn instance_index( + ctx: impl Ctx + ExtractIndex, + _primary: (), + /// The number of nested loops to traverse outwards (from the innermost loop) to get the index from. The most upstream loop is level 0, and downstream loops add levels. + /// + /// In programming terms: inside the double loop `i { j { ... } }`, *Loop Level* 0 = `j` and 1 = `i`. After inserting a third loop `k { ... }`, inside it, levels would be 0 = `k`, 1 = `j`, and 2 = `i`. + loop_level: u32, +) -> f64 { let Some(index_iter) = ctx.try_index() else { return 0. }; let mut last = 0; for (i, index) in index_iter.enumerate() {