inexorgame / vulkan-renderer

A new 3D game engine for Linux and Windows using C++20 and Vulkan API 1.3, in very early but ongoing development
https://inexor.org
MIT License
757 stars 33 forks source link

Random world generator with non-uniform child cube depth #519

Open IAmNotHanni opened 1 year ago

IAmNotHanni commented 1 year ago

Is your feature request related to a problem?

The current implementation of our random world generator is fine, but it creates only octrees which have uniform depth in all child cubes:

std::shared_ptr<Cube> create_random_world(const float size, const std::uint32_t max_depth,
                                          const glm::vec3 &pos, const std::optional<std::uint32_t> seed) {
    static std::random_device rd;
    std::mt19937 mt(seed ? *seed : rd());
    std::uniform_int_distribution<std::uint32_t> indent(0, 44);
    std::uniform_int_distribution<std::uint32_t> cube_type(0, 100);

    std::shared_ptr<Cube> cube = std::make_shared<Cube>(size, pos);
    cube->set_type(Cube::Type::OCTANT);
    std::function<void(const Cube &, std::uint32_t)> populate_cube = [&](const Cube &parent, std::uint32_t depth) {
        for (const auto &child : parent.get_children()) {
            if (depth != max_depth) {
                child->set_type(Cube::Type::OCTANT);
                populate_cube(*child, depth + 1);
                continue;
            }
            const auto ty = cube_type(mt);
            if (ty < 30) {
                child->set_type(Cube::Type::EMPTY);
                continue;
            }
            if (ty < 60) {
                child->set_type(Cube::Type::SOLID);
                continue;
            }
            if (ty < 100) {
                child->set_type(Cube::Type::NORMAL);
                for (int i = 0; i < 12; i++) {
                    child->set_indent(i, Indentation(indent(mt)));
                }
                continue;
            }
        }
    };
    populate_cube(*cube, 0);
    return cube;
}

An example can be seen in the following screenshot: The root cube is an octant, meaning that it has 8 child cubes. Each child itself is an octant as well, although some could be empty, solid, or normal cube types instead. The leaf cubes however are all either solid, empty, or normal cubes:

image

We should implement a random world generator where the decision to go deeper in the cube node hierarchy should be randomized as well. We should discuss if we want to keep both functions in cube.hpp though or if we want to make a separate header file just for that.

Description

create_random_world creates a random world which is nice for quick testing.

Alternatives

none

Affected Code

The octree code

Operating System

All operating systems

Additional Context

No response

IceflowRE commented 1 year ago

I would add a parameter probably. Also this implementation was by choice so we have a maximum of cubes.

IAmNotHanni commented 1 year ago

Good idea. This way we don't to write another additional method.