diff --git a/src/main.cpp b/src/main.cpp index b36e779..7e90d78 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -7,149 +7,165 @@ #include #include -static void CreateLight(Nz::EnttWorld &world) -{ - entt::handle lightEntity = world.CreateEntity(); - { - auto &lightNode = lightEntity.emplace(); - lightNode.SetPosition({0, 1, 0}); - - auto &entityLight = lightEntity.emplace(); - auto &spotLight = entityLight.AddLight(1); - spotLight.EnableShadowCasting(true); - spotLight.UpdateShadowMapSize(1024); - } - +static Nz::Vector3f Get2DDirectionVectorFromRotation(float yaw) { + return { + -std::sin(yaw), + 0, + -std::cos(yaw), + }; } -static void CreateBoxes(Nz::EnttWorld& world) +static void CreateLight(Nz::EnttWorld &world) { - constexpr float BoxDims = 16.f; + entt::handle lightEntity = world.CreateEntity(); + { + auto &lightNode = lightEntity.emplace(); + lightNode.SetPosition({0, 5, 0}); - std::mt19937 rd(42); + auto &entityLight = lightEntity.emplace(); + auto &spotLight = entityLight.AddLight(1); + spotLight.EnableShadowCasting(true); + spotLight.UpdateShadowMapSize(1024); + spotLight.UpdateRadius(10.0f); + spotLight.UpdateDiffuseFactor(0.5f); + } +} + +static void CreateBoxes(Nz::EnttWorld &world) +{ + constexpr float BoxDims = 1.f; + + std::mt19937 rd(42); std::uniform_real_distribution colorDis(0.f, 360.f); std::uniform_real_distribution radiusDis(0.1f, 0.5f); - std::uniform_real_distribution lengthDis(0.2f, 1.5f); - std::shared_ptr boxMesh = Nz::GraphicalMesh::Build(Nz::Primitive::Box(Nz::Vector3f(1.f))); + std::uniform_real_distribution lengthDis(0.2f, 1.5f); + std::shared_ptr boxMesh = Nz::GraphicalMesh::Build(Nz::Primitive::Box(Nz::Vector3f(1.f))); - constexpr std::size_t BoxCount = 100; - for (std::size_t i = 0; i < BoxCount; ++i) - { - float width = lengthDis(rd); - float height = lengthDis(rd); - float depth = lengthDis(rd); + constexpr std::size_t BoxCount = 100; + for (std::size_t i = 0; i < BoxCount; ++i) + { + float width = lengthDis(rd); + float height = lengthDis(rd); + float depth = lengthDis(rd); - std::uniform_real_distribution xRandom(-BoxDims * 0.5f + width, BoxDims * 0.5f - width); - std::uniform_real_distribution yRandom(-BoxDims * 0.5f + height, BoxDims * 0.5f - height); - std::uniform_real_distribution zRandom(-BoxDims * 0.5f + depth, BoxDims * 0.5f - depth); + std::uniform_real_distribution xRandom(-BoxDims * 0.5f + width, BoxDims * 0.5f - width); + std::uniform_real_distribution yRandom(-BoxDims * 0.5f + height, BoxDims * 0.5f - height); + std::uniform_real_distribution zRandom(-BoxDims * 0.5f + depth, BoxDims * 0.5f - depth); - entt::handle boxEntity = world.CreateEntity(); + entt::handle boxEntity = world.CreateEntity(); - std::shared_ptr boxMaterial = Nz::MaterialInstance::Instantiate(Nz::MaterialType::Phong); - boxMaterial->SetValueProperty("BaseColor", Nz::Color::sRGBToLinear(Nz::Color::FromHSV(colorDis(rd), 1.f, 1.f))); + std::shared_ptr boxMaterial = Nz::MaterialInstance::Instantiate(Nz::MaterialType::Phong); + boxMaterial->SetValueProperty("BaseColor", Nz::Color::sRGBToLinear(Nz::Color::FromHSV(colorDis(rd), 1.f, 1.f))); - std::shared_ptr sphereModel = std::make_shared(boxMesh); - sphereModel->SetMaterial(0, std::move(boxMaterial)); + std::shared_ptr sphereModel = std::make_shared(boxMesh); + sphereModel->SetMaterial(0, std::move(boxMaterial)); - boxEntity.emplace(std::move(sphereModel)); + boxEntity.emplace(std::move(sphereModel)); - auto &ballNode = boxEntity.emplace(); - ballNode.SetPosition({xRandom(rd), yRandom(rd), zRandom(rd)}); - ballNode.SetScale({width, height, depth}); + auto &ballNode = boxEntity.emplace(); + ballNode.SetPosition({xRandom(rd), yRandom(rd) + 20.0f, zRandom(rd)}); + ballNode.SetScale({width, height, depth}); - std::shared_ptr boxCollider = std::make_shared(Nz::Vector3f(width, height, depth)); + std::shared_ptr boxCollider = std::make_shared(Nz::Vector3f(width, height, depth)); - Nz::RigidBody3D::DynamicSettings settings; - settings.geom = boxCollider; - settings.mass = width * height * depth; + Nz::RigidBody3D::DynamicSettings settings; + settings.geom = boxCollider; + settings.mass = width * height * depth; - boxEntity.emplace(settings); - } + boxEntity.emplace(settings); + } } static void CreateModel(Nz::EnttWorld &world) { - std::filesystem::path resourceDir = "assets/models"; + std::filesystem::path resourceDir = "assets/models"; - Nz::MeshParams meshParams; - meshParams.center = true; - meshParams.vertexRotation = Nz::EulerAnglesf(0.f, 0.f, 0.f); - meshParams.vertexScale = Nz::Vector3f(1.0f); - meshParams.vertexDeclaration = Nz::VertexDeclaration::Get(Nz::VertexLayout::XYZ_Normal_UV_Tangent); + Nz::MeshParams meshParams; + meshParams.center = true; + meshParams.vertexRotation = Nz::EulerAnglesf(0.f, 0.f, 0.f); + meshParams.vertexScale = Nz::Vector3f(1.0f); + meshParams.vertexDeclaration = Nz::VertexDeclaration::Get(Nz::VertexLayout::XYZ_Normal_UV_Tangent); - std::shared_ptr deambuMesh = Nz::Mesh::LoadFromFile(resourceDir / "sol.obj", meshParams); - if (!deambuMesh) - { - NazaraError("failed to load model"); - return; - } + std::shared_ptr deambuMesh = Nz::Mesh::LoadFromFile(resourceDir / "sol.obj", meshParams); + if (!deambuMesh) + { + NazaraError("failed to load model"); + return; + } - std::shared_ptr gfxMesh = Nz::GraphicalMesh::BuildFromMesh(*deambuMesh); - std::shared_ptr deambModel = std::make_shared(std::move(gfxMesh)); + std::shared_ptr gfxMesh = Nz::GraphicalMesh::BuildFromMesh(*deambuMesh); + std::shared_ptr deambModel = std::make_shared(std::move(gfxMesh)); - entt::handle deambEntity = world.CreateEntity(); - { - auto &entityGfx = deambEntity.emplace(); - entityGfx.AttachRenderable(deambModel); + entt::handle deambEntity = world.CreateEntity(); + { + auto &entityGfx = deambEntity.emplace(); + entityGfx.AttachRenderable(deambModel); - auto &entityNode = deambEntity.emplace(); - entityNode.SetPosition(Nz::Vector3f(0.f, 0.f, 0.f)); - } + auto &entityNode = deambEntity.emplace(); + entityNode.SetPosition(Nz::Vector3f(0.f, 0.f, 0.f)); + } - std::shared_ptr device = Nz::Graphics::Instance()->GetRenderDevice(); + std::shared_ptr device = Nz::Graphics::Instance()->GetRenderDevice(); - std::shared_ptr material = Nz::MaterialInstance::Instantiate(Nz::MaterialType::Phong); - for (std::string_view passName : {"DepthPass", "ForwardPass"}) - { - material->UpdatePassStates(passName, [](Nz::RenderStates &states) - { + std::shared_ptr material = Nz::MaterialInstance::Instantiate(Nz::MaterialType::Phong); + for (std::string_view passName : {"DepthPass", "ForwardPass"}) + { + material->UpdatePassStates(passName, [](Nz::RenderStates &states) + { states.depthClamp = true; return true; }); - } + } - std::mt19937 rd(42); - std::uniform_real_distribution colorDis(0.f, 360.f); - material->SetValueProperty("BaseColor", Nz::Color::sRGBToLinear(Nz::Color::FromHSV(colorDis(rd), 1.f, 1.f))); + std::mt19937 rd(42); + std::uniform_real_distribution colorDis(0.f, 360.f); + material->SetValueProperty("BaseColor", Nz::Color::sRGBToLinear(Nz::Color::FromHSV(colorDis(rd), 1.f, 1.f))); - for (std::size_t i = 0; i < deambModel->GetSubMeshCount(); ++i) - deambModel->SetMaterial(i, material); + for (std::size_t i = 0; i < deambModel->GetSubMeshCount(); ++i) + deambModel->SetMaterial(i, material); - - Nz::VertexMapper vertexMapper(*deambuMesh->GetSubMesh(0)); + Nz::VertexMapper vertexMapper(*deambuMesh->GetSubMesh(0)); Nz::SparsePtr vertices = vertexMapper.GetComponentPtr(Nz::VertexComponent::Position); auto shipCollider = std::make_shared(vertices, vertexMapper.GetVertexCount(), 0.1f); - Nz::RigidBody3D::StaticSettings settings; - settings.geom = shipCollider; + Nz::RigidBody3D::StaticSettings settings; + settings.geom = shipCollider; - deambEntity.emplace(settings); + deambEntity.emplace(settings); } static Nz::EulerAnglesf camAngles(0.f, 0.f, 0.f); -static void CreateCamera(Nz::EnttWorld &world, Nz::Window &window) +static void CreateCamera(Nz::EnttWorld &world, Nz::Window &window, Nz::Application &app) { - Nz::RenderSystem &renderSystem = world.AddSystem(); + Nz::RenderSystem &renderSystem = world.AddSystem(); - Nz::SwapchainParameters params; - params.presentMode.clear(); - params.presentMode.push_back(Nz::PresentMode::VerticalSync); + Nz::SwapchainParameters params; + params.presentMode.clear(); + params.presentMode.push_back(Nz::PresentMode::VerticalSync); - Nz::WindowSwapchain &windowSwapchain = renderSystem.CreateSwapchain(window, params); + Nz::WindowSwapchain &windowSwapchain = renderSystem.CreateSwapchain(window, params); - // Création de la caméra - entt::handle cameraEntity = world.CreateEntity(); + // Création de la caméra + entt::handle cameraEntity = world.CreateEntity(); - auto &cameraNode = cameraEntity.emplace(); - cameraNode.SetPosition({0, 5, 0}); + auto &cameraNode = cameraEntity.emplace(); + cameraNode.SetPosition({0, 1, 0}); - auto &cameraComponent = cameraEntity.emplace(std::make_shared(windowSwapchain), Nz::ProjectionType::Perspective); - cameraComponent.UpdateClearColor(Nz::Color(0.3f, 0.8f, 1.0f)); + auto &cameraComponent = cameraEntity.emplace(std::make_shared(windowSwapchain), Nz::ProjectionType::Perspective); + cameraComponent.UpdateClearColor(Nz::Color(0.3f, 0.8f, 1.0f)); + cameraComponent.UpdateZNear(0.1f); + cameraComponent.UpdateZFar(100.0f); - window.GetEventHandler().OnMouseMoved.Connect([&](const Nz::WindowEventHandler * /*eventHandler*/, const Nz::WindowEvent::MouseMoveEvent &event) - { + entt::handle playerEntity = world.CreateEntity(); + + auto &playerNode = playerEntity.emplace(); + playerNode.SetPosition({0, 5, 0}); + cameraNode.SetParent(playerEntity); + + window.GetEventHandler().OnMouseMoved.Connect([&](const Nz::WindowEventHandler * /*eventHandler*/, const Nz::WindowEvent::MouseMoveEvent &event) + { constexpr float sensitivity = 0.3f; camAngles.yaw -= event.deltaX * sensitivity; @@ -157,47 +173,88 @@ static void CreateCamera(Nz::EnttWorld &world, Nz::Window &window) camAngles.pitch = Nz::Clamp(camAngles.pitch - event.deltaY * sensitivity, -89.f, 89.f); - cameraNode.SetRotation(camAngles); }); + camAngles.roll = 0.0f; + cameraNode.SetRotation(camAngles); + + }); + + std::shared_ptr boxCollider = std::make_shared(Nz::Vector3f(1, 2, 1)); + + + + static const int playerMass = 100000; + + Nz::RigidBody3D::DynamicSettings settings; + settings.geom = boxCollider; + settings.mass = playerMass; + auto &playerBody = playerEntity.emplace(settings); + + app.AddUpdaterFunc([&](){ + static Nz::MillisecondClock updateClock; + if (std::optional deltaTime = updateClock.RestartIfOver(Nz::Time::TickDuration(60))) + { + camAngles.roll = 0; + cameraNode.SetRotation(camAngles); + + Nz::Vector3f front = Get2DDirectionVectorFromRotation(camAngles.yaw.ToRadians()); + Nz::Vector3f left = Get2DDirectionVectorFromRotation(camAngles.yaw.ToRadians() + 3.1415926535/2.0); + + if (Nz::Keyboard::IsKeyPressed(Nz::Keyboard::VKey::Z)) + playerBody.AddForce(front * 10.f * playerMass, Nz::CoordSys::Local); + + if (Nz::Keyboard::IsKeyPressed(Nz::Keyboard::VKey::S)) + playerBody.AddForce(-front * 10.f * playerMass, Nz::CoordSys::Local); + + if (Nz::Keyboard::IsKeyPressed(Nz::Keyboard::VKey::Q)) + playerBody.AddForce(left * 10.f * playerMass, Nz::CoordSys::Local); + + if (Nz::Keyboard::IsKeyPressed(Nz::Keyboard::VKey::D)) + playerBody.AddForce(-left * 10.f * playerMass, Nz::CoordSys::Local); + + if (Nz::Keyboard::IsKeyPressed(Nz::Keyboard::VKey::Space)) + playerBody.AddForce(Nz::Vector3f::Up() * 15.f * playerMass, Nz::CoordSys::Local); + } + }); } int main(int argc, char **argv) { - Nz::Application app(argc, argv); + Nz::Application app(argc, argv); - auto &windowing = app.AddComponent(); + auto &windowing = app.AddComponent(); - std::string windowTitle = "Blitz 2"; - Nz::Window &window = windowing.CreateWindow(Nz::VideoMode(1920, 1080, 32), windowTitle); + std::string windowTitle = "Blitz 2"; + Nz::Window &window = windowing.CreateWindow(Nz::VideoMode(1920, 1080, 32), windowTitle); - auto &ecs = app.AddComponent(); + auto &ecs = app.AddComponent(); - auto &world = ecs.AddWorld(); + auto &world = ecs.AddWorld(); - auto& physSystem = world.AddSystem(); + auto &physSystem = world.AddSystem(); physSystem.GetPhysWorld().SetMaxStepCount(1); physSystem.GetPhysWorld().SetStepSize(Nz::Time::TickDuration(50)); physSystem.GetPhysWorld().SetGravity(Nz::Vector3f::Down() * 9.81f); - CreateCamera(world, window); - CreateBoxes(world); - CreateModel(world); - CreateLight(world); + CreateCamera(world, window, app); + CreateBoxes(world); + CreateModel(world); + CreateLight(world); - Nz::Mouse::SetRelativeMouseMode(true); + Nz::Mouse::SetRelativeMouseMode(true); - Nz::MillisecondClock fpsClock; + Nz::MillisecondClock fpsClock; unsigned int fps = 0; - app.AddUpdaterFunc([&](){ + app.AddUpdaterFunc([&]() + { fps++; if (fpsClock.RestartIfOver(Nz::Time::Second())) { window.SetTitle(windowTitle + " - " + Nz::NumberToString(fps) + " FPS" + " - " + Nz::NumberToString(world.GetAliveEntityCount()) + " entities"); fps = 0; - } - }); + } }); - return app.Run(); + return app.Run(); }