Fix a bug where Transform nodes would cause a reversal of the 'Instance Index' node's 'Loop Level' counting direction

This commit is contained in:
Keavon Chambers 2026-01-13 23:15:42 -08:00
parent 654a05bb41
commit 20a595db39
2 changed files with 13 additions and 3 deletions

View File

@ -334,7 +334,7 @@ impl ExtractPointer for OwnedContextImpl {
} }
impl ExtractIndex for OwnedContextImpl { impl ExtractIndex for OwnedContextImpl {
fn try_index(&self) -> Option<impl Iterator<Item = usize>> { fn try_index(&self) -> Option<impl Iterator<Item = usize>> {
self.index.clone().map(|x| x.into_iter().rev()) self.index.clone().map(|x| x.into_iter())
} }
} }
impl ExtractVarArgs for OwnedContextImpl { impl ExtractVarArgs for OwnedContextImpl {
@ -523,7 +523,7 @@ impl OwnedContextImpl {
} }
pub fn with_index(mut self, index: usize) -> Self { pub fn with_index(mut self, index: usize) -> Self {
if let Some(current_index) = &mut self.index { if let Some(current_index) = &mut self.index {
current_index.push(index); current_index.insert(0, index);
} else { } else {
self.index = Some(vec![index]); self.index = Some(vec![index]);
} }

View File

@ -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: 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.) // 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))] #[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 Some(index_iter) = ctx.try_index() else { return 0. };
let mut last = 0; let mut last = 0;
for (i, index) in index_iter.enumerate() { for (i, index) in index_iter.enumerate() {