Rajesh
Rajesh

Reputation: 13

World moving algorithm doesn't work as intended

So I'm working on a voxel engine in C++, and I've put together an algorithm for moving the world based on a new position (only in the +x/+y direction). It works as follows:

I attempted to write the algorithm on my other computer while away, and got it to work in the way I expected. However, upon arriving home and running it on my main computer, it no longer works and produces erroneous results.

Upon further testing I can confirm that all functions used within the move function are correct and function as intended. The problem lies within the move function and I suspect it to be some form of memory corruption.

Here is the move function:

void Level::move(i64 x, i64 y) {
    Chunk **old = new Chunk*[this->view_distance * this->view_distance];

    // some of the edge chunks might need to be updated
    std::vector<Chunk*> mesh_update_chunks = this->get_edge_chunks();

    this->corner_x = x;
    this->corner_y = y;

    // copy all chunk pointers into old
    for (u32 i = 0; i < this->view_distance; i++) {
        std::memcpy(
            (char*)old + i * sizeof(Chunk*) * this->view_distance,
            this->loaded_chunks[i],
            sizeof(Chunk*) * this->view_distance
        );
        std::memset(
            this->loaded_chunks[i],
            0,
            sizeof(Chunk*) * this->view_distance
        );
    }

    // check if a chunk remains in bounds, placing it at the correct index into
    // the chunk array if it does
    for (u32 i = 0; i < this->view_distance; i++) {
        for (u32 j = 0; j < this->view_distance; j++) {
            Chunk *c = old[j + i * this->view_distance];
            if (c->x >= this->corner_x && c->y >= this->corner_y &&
                c->x <=
                    (this->corner_x + this->view_distance * CHUNK_SIZE_XZ) &&
                c->y <=
                    (this->corner_y + this->view_distance * CHUNK_SIZE_XZ)) {
                // chunk remains in bounds
                u32 index_x = (c->x - this->corner_x) / CHUNK_SIZE_XZ;
                u32 index_y = (c->y - this->corner_y) / CHUNK_SIZE_XZ;

                this->loaded_chunks[index_x][index_y] = c;
                continue;
            }

            // if the chunk that is being deleted is in our mesh_update_chunks
            // vector, then we need to erase it
            mesh_update_chunks.erase(
                std::remove(
                    mesh_update_chunks.begin(),
                    mesh_update_chunks.end(),
                    c
                ), mesh_update_chunks.end()
            );

            // delete all data allocated to the chunk
            c->destroy();
            delete c;
        }
    }

    // fill in all of the deleted chunks with new chunks at the correct
    // coordinates
    for (u32 i = 0; i < this->view_distance; i++) {
        for (u32 j = 0; j < this->view_distance; j++) {
            if (this->loaded_chunks[i][j] == NULL) {
                this->loaded_chunks[i][j] = new Chunk;
                this->loaded_chunks[i][j]->x =
                    i * CHUNK_SIZE_XZ + this->corner_x;
                this->loaded_chunks[i][j]->y =
                    j * CHUNK_SIZE_XZ + this->corner_y;

                this->level_generator.run(this->loaded_chunks[i][j]);
                mesh_update_chunks.push_back(this->loaded_chunks[i][j]);
            }
        }
    }

    // mesh all of the chunks that require it
    for (const auto &c : mesh_update_chunks) {
        c->mesh();
    }

    delete[] old;
}

I have not been able to find any bugs though, and upon attempting a trace table I also found no issues with the code as is. Does anyone know where the error could be?

Upvotes: 0

Views: 54

Answers (0)

Related Questions