From 0f4734bdf7445fc1fe7c3a4772b417d2d92fdf25 Mon Sep 17 00:00:00 2001 From: fallenatlas Date: Wed, 6 Sep 2023 22:26:56 +0100 Subject: [PATCH] docs(engine): cleanup and document cars sample --- docs/pages/3_examples/2_engine/main.md | 1 + engine/samples/cars/components.hpp | 2 + engine/samples/cars/main.cpp | 88 +++++++++++++++++++++----- engine/samples/cars/page.md | 58 +++++++++++++++++ 4 files changed, 132 insertions(+), 17 deletions(-) create mode 100644 engine/samples/cars/page.md diff --git a/docs/pages/3_examples/2_engine/main.md b/docs/pages/3_examples/2_engine/main.md index 9e63f45881..2fd312a11d 100644 --- a/docs/pages/3_examples/2_engine/main.md +++ b/docs/pages/3_examples/2_engine/main.md @@ -6,3 +6,4 @@ The following examples have fully documented tutorials on how to use the multiple plugins of the engine: - @subpage examples-engine-renderer - @copybrief examples-engine-renderer +- @subpage examples-engine-cars - @copybrief examples-engine-cars diff --git a/engine/samples/cars/components.hpp b/engine/samples/cars/components.hpp index d38eecaa40..845b324e04 100644 --- a/engine/samples/cars/components.hpp +++ b/engine/samples/cars/components.hpp @@ -2,8 +2,10 @@ #include +/// [Car component] struct [[cubos::component("car", VecStorage)]] Car { glm::vec3 vel = {1.0f, 0.0f, 0.0f}; float angVel = 1.0f; }; +/// [Car component] diff --git a/engine/samples/cars/main.cpp b/engine/samples/cars/main.cpp index ea7ef50892..b442eec306 100644 --- a/engine/samples/cars/main.cpp +++ b/engine/samples/cars/main.cpp @@ -17,30 +17,47 @@ using cubos::core::gl::Grid; using cubos::core::gl::Palette; using namespace cubos::engine; +/// [Get handles to assets] static const Asset CarAsset = AnyAsset("059c16e7-a439-44c7-9bdc-6e069dba0c75"); static const Asset PaletteAsset = AnyAsset("1aa5e234-28cb-4386-99b4-39386b0fc215"); +/// [Get handles to assets] +/// [Spawner resource] struct Spawner { float timer = 0.0F; int x = -1; int y = -1; }; +/// [Spawner resource] -static void settings(Write settings) +/// [Set settings] +static void settingsSystem(Write settings) { settings->setString("assets.io.path", SAMPLE_ASSETS_FOLDER); } +/// [Set settings] -static void setup(Commands cmds, Write assets, Write renderer, Write activeCameras) +/// [Load, add materials and set pallete] +static void setPalleteSystem(Write assets, Write renderer) { // Load the palette asset and add two colors to it. auto palette = assets->write(PaletteAsset); - auto black = palette->add({{0.1F, 0.1F, 0.1F, 1.0F}}); - auto white = palette->add({{0.9F, 0.9F, 0.9F, 1.0F}}); + palette->add({{0.1F, 0.1F, 0.1F, 1.0F}}); + palette->add({{0.9F, 0.9F, 0.9F, 1.0F}}); // Set the renderer's palette to the one we just modified. (*renderer)->setPalette(*palette); +} +/// [Load, add materials and set pallete] + +/// [Create and spawn floor] +static void spawnFloorSystem(Commands cmds, Write assets) +{ + // Get the materials previously added to the palette + auto palette = assets->read(PaletteAsset); + auto black = palette->find({{0.1F, 0.1F, 0.1F, 1.0F}}); + auto white = palette->find({{0.9F, 0.9F, 0.9F, 1.0F}}); // Generate a new grid asset for the floor. auto floorGrid = Grid({256, 1, 256}); @@ -57,22 +74,40 @@ static void setup(Commands cmds, Write assets, Write renderer, auto floorAsset = assets->create(std::move(floorGrid)); // Spawn the floor entity. + cmds.create() + .add(RenderableGrid{floorAsset, floorOffset}) + .add(LocalToWorld{}) + .add(Scale{4.0F}); +} +/// [Create and spawn floor] - cmds.create(RenderableGrid{floorAsset, floorOffset}, LocalToWorld{}, Scale{4.0F}); - +/// [Spawn camera] +static void spawnCameraSystem(Commands cmds, Write activeCameras) +{ // Spawn the camera entity. activeCameras->entities[0] = - cmds.create(Camera{60.0F, 0.1F, 1000.0F}, LocalToWorld{}) + cmds.create() + .add(Camera{.fovY = 60.0F, .zNear = 0.1F, .zFar = 1000.0F}) + .add(LocalToWorld{}) .add(Position{{0.0F, 120.0F, -200.0F}}) .add(Rotation{glm::quatLookAt(glm::normalize(glm::vec3{0.0F, -1.0F, 1.0F}), glm::vec3{0.0F, 1.0F, 0.0F})}) .entity(); +} +/// [Spawn camera] +/// [Spawn light] +static void spawnLightSystem(Commands cmds) +{ // Spawn the sun. - cmds.create(DirectionalLight{glm::vec3(1.0F), 1.0F}, LocalToWorld{}, - Rotation{glm::quat(glm::vec3(glm::radians(45.0F), glm::radians(45.0F), 0))}); + cmds.create() + .add(DirectionalLight{glm::vec3(1.0F), 1.0F}) + .add(LocalToWorld{}) + .add(Rotation{glm::quat(glm::vec3(glm::radians(45.0F), glm::radians(45.0F), 0))}); } +/// [Spawn light] -static void spawn(Commands cmds, Write spawner, Read deltaTime, Read assets) +/// [Spawn system] +static void spawnSystem(Commands cmds, Write spawner, Read deltaTime, Read assets) { spawner->timer += deltaTime->value; if (spawner->timer >= 1.0F && spawner->y < 2) @@ -80,11 +115,15 @@ static void spawn(Commands cmds, Write spawner, Read deltaTi auto car = assets->read(CarAsset); glm::vec3 offset = glm::vec3(car->size().x, 0.0F, car->size().z) / -2.0F; - cmds.create(Car{}, RenderableGrid{CarAsset, offset}, LocalToWorld{}) + cmds.create() + .add(Car{}) + .add(RenderableGrid{CarAsset, offset}) + .add(LocalToWorld{}) .add(Position{{80.0F * static_cast(spawner->x), 0.0F, 80.0F * static_cast(spawner->y)}}) .add(Rotation{}); spawner->timer = 0; + /// [Spawn system] spawner->x += 1; if (spawner->x == 2) { @@ -94,7 +133,8 @@ static void spawn(Commands cmds, Write spawner, Read deltaTi } } -static void move(Query, Write, Write> query, Read deltaTime) +/// [Move system] +static void moveSystem(Query, Write, Write> query, Read deltaTime) { for (auto [entity, car, position, rotation] : query) { @@ -105,20 +145,34 @@ static void move(Query, Write, Write> query, Read rotation->quat = glm::angleAxis(deltaTime->value * car->angVel, glm::vec3(0.0F, 1.0F, 0.0F)) * rotation->quat; } } +/// [Move system] int main(int argc, char** argv) { Cubos cubos{argc, argv}; + /// [Adding the env settings plugin] cubos.addPlugin(envSettingsPlugin); + /// [Adding the env settings plugin] + + /// [Adding the render and voxels plugin] cubos.addPlugin(rendererPlugin); cubos.addPlugin(voxelsPlugin); + /// [Adding the render and voxels plugin] + + /// [Adding component and resource] cubos.addComponent(); cubos.addResource(); - - cubos.startupSystem(settings).tagged("cubos.settings"); - cubos.startupSystem(setup).tagged("cubos.assets").after("cubos.renderer.init"); - cubos.system(spawn); - cubos.system(move); + /// [Adding component and resource] + + /// [Adding systems] + cubos.startupSystem(settingsSystem).tagged("cubos.settings"); + cubos.startupSystem(setPalleteSystem).tagged("palette.set").after("cubos.renderer.init"); + cubos.startupSystem(spawnFloorSystem).after("palette.set"); + cubos.startupSystem(spawnCameraSystem); + cubos.startupSystem(spawnLightSystem); + cubos.system(spawnSystem); + cubos.system(moveSystem); + /// [Adding systems] cubos.run(); } \ No newline at end of file diff --git a/engine/samples/cars/page.md b/engine/samples/cars/page.md new file mode 100644 index 0000000000..3238f9d52e --- /dev/null +++ b/engine/samples/cars/page.md @@ -0,0 +1,58 @@ +# Cars {#examples-engine-cars} + +@brief Sample that spawns multiple assets and updates them every frame. + +This example shows how the @ref renderer-plugin plugin, @ref voxels-plugin plugin and @ref env-settings-plugin, can be used in a scene to spawn and move assets. + +The first thing we're going to worry about is setting up the path for the assets we're going to use in our settings resource. In this example, the path is set in a macro defined in a CMakeLists.txt file but you can give it the path directly as a string. + +@snippet cars/main.cpp Set settings + +Alternatively, the path can be set from the command line arguments given when starting cubos. For this we need the @ref env-settings-plugin, included from the @ref engine/env_settings/plugin.hpp header. + +@snippet cars/main.cpp Adding the env settings plugin + +Each asset has an id through which we can get a handle to it. This id is specified in the .meta file associated to the asset. + +@snippet cars/main.cpp Get handles to assets + +Next, we are going to set up the scene. + +We'll need to render and load assets. + +@snippet cars/main.cpp Adding the render and voxels plugin + +In our assets folder we already have a palette, let's load it and give it some more colors. + +@snippet cars/main.cpp Load, add materials and set pallete + +Now, let's give our scene a floor. To achieve this, we'll create a grid, assign one of the materials we added to the pallete to each voxel of that grid and then spawn it. + +@snippet cars/main.cpp Create and spawn floor + +To finish the setup, we need to spawn a camera and a light. On this sample we use a directional light. For more info on how to configure the @ref renderer-plugin plugin, refer to the @ref examples-renderer-sample sample. + +@snippet cars/main.cpp Spawn camera +@snippet cars/main.cpp Spawn light + +In this sample we want to spawn a car every second and move every car in the scene at a constant speed. To do this, we'll use 2 systems. One will spawn the cars and the other will move them. + +Let's start with the spawn system. In this system, we'll need to load the asset and spawn the car at a given position, when it's time to do so. + +@snippet cars/main.cpp Spawn system + +For this to work, we'll need 2 more things, the Car component, which contains the car velocity and angular velocity, and the Spawner resource, used to keep track of the time and the position to spawn the car. + +@snippet cars/components.hpp Car component +@snippet cars/main.cpp Spawner resource +@snippet cars/main.cpp Adding component and resource + +Lastly, the move system will simply query through all the cars and change the values of their components. Note how we also use the Delta Time resource to make the speed independent from the frame rate. + +@snippet cars/main.cpp Move system + +Now, to make everything come to life, we just add all of these systems. + +@snippet cars/main.cpp Adding systems + +And voilá, you now have a screen full of cars doing ballet!