How to implement octree division?

I a trying to implement an octree structure to store voxels in, but i failed when it came to dividing the octree. here is the relevant code:

pub struct Voxel<'a> {
    pub voxel_type: VoxelId,
    pub children: Option<[&'a Voxel<'a>; 8]>,
}

impl Voxel<'_> {
    pub fn new (voxel_id: u16) -> Self {

        Self{
            voxel_type: VoxelId{id: voxel_id},
            children: None,
        }
    }

    pub fn divide<'a>(&mut self){
        self.children = Some([
            &Voxel::new(self.voxel_type.id),
            &Voxel::new(self.voxel_type.id),
            &Voxel::new(self.voxel_type.id),
            &Voxel::new(self.voxel_type.id),
            &Voxel::new(self.voxel_type.id),
            &Voxel::new(self.voxel_type.id),
            &Voxel::new(self.voxel_type.id),
            &Voxel::new(self.voxel_type.id),
        ])
    }
}

i know this code won't work since the new sub voxels are dropped once the function ends, but i failed to find a different solution

Why do you use a reference? I don't know exactly what you will use the Voxel struct for, but I'd start simple, with something without references, like:

pub struct Voxel {
    pub voxel_type: VoxelId,
    pub children: Option<Box<[Voxel; 8]>>,
}

Then your divide function can just be:

pub fn divide(&mut self){
    self.children = Some(Box::new([
        Voxel::new(self.voxel_type.id),
        Voxel::new(self.voxel_type.id),
        Voxel::new(self.voxel_type.id),
        Voxel::new(self.voxel_type.id),
        Voxel::new(self.voxel_type.id),
        Voxel::new(self.voxel_type.id),
        Voxel::new(self.voxel_type.id),
        Voxel::new(self.voxel_type.id),
    ]));
}
2 Likes

Thanks, that seems to me working just fine

A general of thumb for Rust: don't put references in types.

More accurately, don't try to use lifetime parameters (like 'a) in anything "long lived" (survives a function call.) As a feature it's useful, but it's more for making nice to use and efficient APIs, not something "normal" application code should find itself doing.

I'm curious what the path you went in to get this type: it would be unfortunate if the error messages guided you to the code you posted then gave up on you. Perhaps there is a better suggestion that it could make?

i think it was partially error messages, and partially me trying things out. in terms of error messages it would be nice if they hinted another way of doing recursive structs, but to be fair to me if i only scrolled down a bit further on stackoverflow i could have found the solution myself

1 Like