Merge branch 'nazara-next' of https://github.com/DigitalPulseSoftware/NazaraEngine into nazara-next
This commit is contained in:
commit
8eb1eb71ba
|
|
@ -0,0 +1,410 @@
|
|||
#include <Nazara/Core.hpp>
|
||||
#include <Nazara/Core/ECS.hpp>
|
||||
#include <Nazara/Platform.hpp>
|
||||
#include <Nazara/Graphics.hpp>
|
||||
#include <Nazara/Graphics/Components.hpp>
|
||||
#include <Nazara/Math/PidController.hpp>
|
||||
#include <Nazara/Physics3D.hpp>
|
||||
#include <Nazara/Physics3D/Components.hpp>
|
||||
#include <Nazara/Physics3D/Systems.hpp>
|
||||
#include <Nazara/Renderer.hpp>
|
||||
#include <Nazara/Shader.hpp>
|
||||
#include <Nazara/Shader/SpirvConstantCache.hpp>
|
||||
#include <Nazara/Shader/SpirvPrinter.hpp>
|
||||
#include <Nazara/Utility.hpp>
|
||||
#include <Nazara/Utility/Components.hpp>
|
||||
#include <entt/entt.hpp>
|
||||
#include <array>
|
||||
#include <iostream>
|
||||
|
||||
int main()
|
||||
{
|
||||
std::filesystem::path resourceDir = "resources";
|
||||
if (!std::filesystem::is_directory(resourceDir) && std::filesystem::is_directory(".." / resourceDir))
|
||||
resourceDir = ".." / resourceDir;
|
||||
|
||||
Nz::Renderer::Config rendererConfig;
|
||||
std::cout << "Run using Vulkan? (y/n)" << std::endl;
|
||||
if (std::getchar() != 'n')
|
||||
rendererConfig.preferredAPI = Nz::RenderAPI::Vulkan;
|
||||
else
|
||||
rendererConfig.preferredAPI = Nz::RenderAPI::OpenGL;
|
||||
|
||||
Nz::Modules<Nz::Graphics, Nz::Physics3D, Nz::ECS> nazara(rendererConfig);
|
||||
|
||||
Nz::RenderWindow window;
|
||||
|
||||
Nz::MeshParams meshParams;
|
||||
meshParams.center = true;
|
||||
meshParams.storage = Nz::DataStorage::Software;
|
||||
meshParams.matrix = Nz::Matrix4f::Rotate(Nz::EulerAnglesf(0.f, 90.f, 0.f)) * Nz::Matrix4f::Scale(Nz::Vector3f(0.002f));
|
||||
meshParams.vertexDeclaration = Nz::VertexDeclaration::Get(Nz::VertexLayout::XYZ_UV);
|
||||
|
||||
std::shared_ptr<Nz::RenderDevice> device = Nz::Graphics::Instance()->GetRenderDevice();
|
||||
|
||||
std::string windowTitle = "Graphics Test";
|
||||
if (!window.Create(device, Nz::VideoMode(1920, 1080, 32), windowTitle))
|
||||
{
|
||||
std::cout << "Failed to create Window" << std::endl;
|
||||
return __LINE__;
|
||||
}
|
||||
|
||||
std::shared_ptr<Nz::Mesh> spaceshipMesh = Nz::Mesh::LoadFromFile(resourceDir / "Spaceship/spaceship.obj", meshParams);
|
||||
if (!spaceshipMesh)
|
||||
{
|
||||
NazaraError("Failed to load model");
|
||||
return __LINE__;
|
||||
}
|
||||
|
||||
std::shared_ptr<Nz::GraphicalMesh> gfxMesh = std::make_shared<Nz::GraphicalMesh>(*spaceshipMesh);
|
||||
|
||||
// Texture
|
||||
std::shared_ptr<Nz::Image> diffuseImage = Nz::Image::LoadFromFile(resourceDir / "Spaceship/Texture/diffuse.png");
|
||||
if (!diffuseImage || !diffuseImage->Convert(Nz::PixelFormat::RGBA8_SRGB))
|
||||
{
|
||||
NazaraError("Failed to load image");
|
||||
return __LINE__;
|
||||
}
|
||||
|
||||
Nz::TextureParams texParams;
|
||||
texParams.renderDevice = device;
|
||||
texParams.loadFormat = Nz::PixelFormat::RGBA8_SRGB;
|
||||
|
||||
std::shared_ptr<Nz::Material> material = std::make_shared<Nz::Material>(Nz::BasicMaterial::GetSettings());
|
||||
material->EnableDepthBuffer(true);
|
||||
material->EnableFaceCulling(true);
|
||||
|
||||
Nz::TextureSamplerInfo samplerInfo;
|
||||
samplerInfo.anisotropyLevel = 8;
|
||||
|
||||
Nz::BasicMaterial basicMat(*material);
|
||||
basicMat.EnableAlphaTest(false);
|
||||
basicMat.SetAlphaMap(Nz::Texture::LoadFromFile(resourceDir / "alphatile.png", texParams));
|
||||
basicMat.SetDiffuseMap(Nz::Texture::LoadFromFile(resourceDir / "Spaceship/Texture/diffuse.png", texParams));
|
||||
basicMat.SetDiffuseSampler(samplerInfo);
|
||||
|
||||
std::shared_ptr<Nz::Model> model = std::make_shared<Nz::Model>(std::move(gfxMesh));
|
||||
for (std::size_t i = 0; i < model->GetSubMeshCount(); ++i)
|
||||
model->SetMaterial(i, material);
|
||||
|
||||
Nz::Vector2ui windowSize = window.GetSize();
|
||||
|
||||
Nz::ViewerInstance viewerInstance;
|
||||
viewerInstance.UpdateTargetSize(Nz::Vector2f(window.GetSize()));
|
||||
viewerInstance.UpdateProjViewMatrices(Nz::Matrix4f::Perspective(Nz::DegreeAnglef(70.f), float(windowSize.x) / windowSize.y, 0.1f, 1000.f), Nz::Matrix4f::Translate(Nz::Vector3f::Backward() * 1));
|
||||
|
||||
Nz::VertexMapper vertexMapper(*spaceshipMesh->GetSubMesh(0), Nz::BufferAccess::ReadOnly);
|
||||
Nz::SparsePtr<Nz::Vector3f> vertices = vertexMapper.GetComponentPtr<Nz::Vector3f>(Nz::VertexComponent::Position);
|
||||
|
||||
|
||||
entt::registry registry;
|
||||
|
||||
Nz::Physics3DSystem physSytem(registry);
|
||||
|
||||
|
||||
auto shipCollider = std::make_shared<Nz::ConvexCollider3D>(vertices, vertexMapper.GetVertexCount(), 0.01f);
|
||||
|
||||
std::shared_ptr<Nz::Material> colliderMat = std::make_shared<Nz::Material>(Nz::BasicMaterial::GetSettings());
|
||||
colliderMat->EnableDepthBuffer(true);
|
||||
colliderMat->SetPrimitiveMode(Nz::PrimitiveMode::LineList);
|
||||
|
||||
Nz::BasicMaterial colliderBasicMat(*colliderMat);
|
||||
colliderBasicMat.SetDiffuseColor(Nz::Color::Green);
|
||||
|
||||
std::shared_ptr<Nz::Model> colliderModel;
|
||||
{
|
||||
std::shared_ptr<Nz::Mesh> colliderMesh = Nz::Mesh::Build(shipCollider->GenerateMesh());
|
||||
std::shared_ptr<Nz::GraphicalMesh> colliderGraphicalMesh = std::make_shared<Nz::GraphicalMesh>(*colliderMesh);
|
||||
|
||||
colliderModel = std::make_shared<Nz::Model>(colliderGraphicalMesh);
|
||||
for (std::size_t i = 0; i < colliderModel->GetSubMeshCount(); ++i)
|
||||
colliderModel->SetMaterial(i, colliderMat);
|
||||
}
|
||||
|
||||
entt::entity playerEntity = registry.create();
|
||||
Nz::Node headingNode;
|
||||
{
|
||||
auto& entityNode = registry.emplace<Nz::NodeComponent>(playerEntity);
|
||||
entityNode.SetPosition(Nz::Vector3f(12.5f, 0.f, 25.f));
|
||||
|
||||
auto& entityGfx = registry.emplace<Nz::GraphicsComponent>(playerEntity);
|
||||
entityGfx.AttachRenderable(model);
|
||||
|
||||
auto& entityPhys = registry.emplace<Nz::RigidBody3DComponent>(playerEntity, physSytem.CreateRigidBody(shipCollider));
|
||||
entityPhys.SetMass(50.f);
|
||||
entityPhys.SetAngularDamping(Nz::Vector3f::Zero());
|
||||
|
||||
headingNode.SetParent(entityNode);
|
||||
headingNode.SetInheritRotation(false);
|
||||
headingNode.SetRotation(entityNode.GetRotation());
|
||||
}
|
||||
|
||||
|
||||
Nz::Node cameraNode;
|
||||
cameraNode.SetParent(headingNode);
|
||||
cameraNode.SetPosition(Nz::Vector3f::Backward() * 2.5f + Nz::Vector3f::Up() * 1.f);
|
||||
|
||||
for (std::size_t x = 0; x < 1; ++x)
|
||||
{
|
||||
for (std::size_t y = 0; y < 1; ++y)
|
||||
{
|
||||
for (std::size_t z = 0; z < 10; ++z)
|
||||
{
|
||||
entt::entity entity = registry.create();
|
||||
auto& entityNode = registry.emplace<Nz::NodeComponent>(entity);
|
||||
entityNode.SetPosition(Nz::Vector3f(x * 2.f, y * 1.5f, z * 2.f));
|
||||
|
||||
auto& entityGfx = registry.emplace<Nz::GraphicsComponent>(entity);
|
||||
entityGfx.AttachRenderable(model);
|
||||
|
||||
auto& entityPhys = registry.emplace<Nz::RigidBody3DComponent>(entity, physSytem.CreateRigidBody(shipCollider));
|
||||
entityPhys.SetMass(1.f);
|
||||
entityPhys.SetAngularDamping(Nz::Vector3f::Zero());
|
||||
entityPhys.SetLinearDamping(0.f);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Nz::RenderWindowImpl* windowImpl = window.GetImpl();
|
||||
std::shared_ptr<Nz::CommandPool> commandPool = windowImpl->CreateCommandPool(Nz::QueueType::Graphics);
|
||||
|
||||
Nz::CommandBufferPtr drawCommandBuffer;
|
||||
auto RebuildCommandBuffer = [&]
|
||||
{
|
||||
Nz::Vector2ui windowSize = window.GetSize();
|
||||
drawCommandBuffer = commandPool->BuildCommandBuffer([&](Nz::CommandBufferBuilder& builder)
|
||||
{
|
||||
Nz::Recti renderRect(0, 0, window.GetSize().x, window.GetSize().y);
|
||||
|
||||
Nz::CommandBufferBuilder::ClearValues clearValues[2];
|
||||
clearValues[0].color = Nz::Color(80, 80, 80);
|
||||
clearValues[1].depth = 1.f;
|
||||
clearValues[1].stencil = 0;
|
||||
|
||||
builder.BeginDebugRegion("Main window rendering", Nz::Color::Green);
|
||||
{
|
||||
builder.BeginRenderPass(windowImpl->GetFramebuffer(), windowImpl->GetRenderPass(), renderRect, { clearValues[0], clearValues[1] });
|
||||
{
|
||||
builder.SetScissor(Nz::Recti{ 0, 0, int(windowSize.x), int(windowSize.y) });
|
||||
builder.SetViewport(Nz::Recti{ 0, 0, int(windowSize.x), int(windowSize.y) });
|
||||
builder.BindShaderBinding(Nz::Graphics::ViewerBindingSet, viewerInstance.GetShaderBinding());
|
||||
|
||||
auto view = registry.view<const Nz::GraphicsComponent>();
|
||||
for (auto [entity, gfxComponent] : view.each())
|
||||
{
|
||||
const Nz::WorldInstance& worldInstance = gfxComponent.GetWorldInstance();
|
||||
for (const auto& renderable : gfxComponent.GetRenderables())
|
||||
renderable->Draw(builder, worldInstance);
|
||||
}
|
||||
}
|
||||
builder.EndRenderPass();
|
||||
}
|
||||
builder.EndDebugRegion();
|
||||
});
|
||||
};
|
||||
|
||||
|
||||
Nz::Vector3f viewerPos = Nz::Vector3f::Zero();
|
||||
|
||||
Nz::EulerAnglesf camAngles(0.f, 0.f, 0.f);
|
||||
Nz::Quaternionf camQuat(camAngles);
|
||||
|
||||
window.EnableEventPolling(true);
|
||||
|
||||
Nz::Clock updateClock;
|
||||
Nz::Clock secondClock;
|
||||
unsigned int fps = 0;
|
||||
|
||||
Nz::Mouse::SetRelativeMouseMode(true);
|
||||
|
||||
float elapsedTime = 0.f;
|
||||
Nz::UInt64 time = Nz::GetElapsedMicroseconds();
|
||||
|
||||
Nz::PidController<Nz::Vector3f> headingController(0.5f, 0.f, 0.05f);
|
||||
Nz::PidController<Nz::Vector3f> upController(1.f, 0.f, 0.1f);
|
||||
|
||||
bool showColliders = false;
|
||||
bool rebuildCommandBuffer = false;
|
||||
while (window.IsOpen())
|
||||
{
|
||||
Nz::UInt64 now = Nz::GetElapsedMicroseconds();
|
||||
elapsedTime = (now - time) / 1'000'000.f;
|
||||
time = now;
|
||||
|
||||
Nz::WindowEvent event;
|
||||
while (window.PollEvent(&event))
|
||||
{
|
||||
switch (event.type)
|
||||
{
|
||||
case Nz::WindowEventType::Quit:
|
||||
window.Close();
|
||||
break;
|
||||
|
||||
case Nz::WindowEventType::KeyPressed:
|
||||
if (event.key.virtualKey == Nz::Keyboard::VKey::A)
|
||||
{
|
||||
basicMat.EnableAlphaTest(!basicMat.IsAlphaTestEnabled());
|
||||
rebuildCommandBuffer = true;
|
||||
}
|
||||
else if (event.key.virtualKey == Nz::Keyboard::VKey::B)
|
||||
{
|
||||
showColliders = !showColliders;
|
||||
if (showColliders)
|
||||
{
|
||||
auto view = registry.view<Nz::GraphicsComponent>();
|
||||
for (auto [entity, gfxComponent] : view.each())
|
||||
gfxComponent.AttachRenderable(colliderModel);
|
||||
}
|
||||
else
|
||||
{
|
||||
auto view = registry.view<Nz::GraphicsComponent>();
|
||||
for (auto [entity, gfxComponent] : view.each())
|
||||
gfxComponent.DetachRenderable(colliderModel);
|
||||
}
|
||||
rebuildCommandBuffer = true;
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case Nz::WindowEventType::MouseMoved:
|
||||
{
|
||||
float sensitivity = 0.3f;
|
||||
|
||||
camAngles.yaw = camAngles.yaw - event.mouseMove.deltaX * sensitivity;
|
||||
camAngles.pitch = camAngles.pitch - event.mouseMove.deltaY * sensitivity;
|
||||
|
||||
camAngles.Normalize();
|
||||
|
||||
camQuat = camAngles;
|
||||
|
||||
headingNode.SetRotation(camQuat);
|
||||
break;
|
||||
}
|
||||
|
||||
case Nz::WindowEventType::Resized:
|
||||
{
|
||||
Nz::Vector2ui windowSize = window.GetSize();
|
||||
viewerInstance.UpdateProjectionMatrix(Nz::Matrix4f::Perspective(Nz::DegreeAnglef(70.f), float(windowSize.x) / windowSize.y, 0.1f, 1000.f));
|
||||
viewerInstance.UpdateTargetSize(Nz::Vector2f(windowSize));
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (updateClock.GetMilliseconds() > 1000 / 60)
|
||||
{
|
||||
float updateTime = updateClock.Restart() / 1'000'000.f;
|
||||
|
||||
float cameraSpeed = 20.f * updateTime;
|
||||
|
||||
physSytem.Update(registry, 1000.f / 60.f);
|
||||
|
||||
Nz::RigidBody3DComponent& playerShipBody = registry.get<Nz::RigidBody3DComponent>(playerEntity);
|
||||
Nz::Quaternionf currentRotation = playerShipBody.GetRotation();
|
||||
|
||||
Nz::Vector3f desiredHeading = headingNode.GetForward();
|
||||
Nz::Vector3f currentHeading = currentRotation * Nz::Vector3f::Forward();
|
||||
Nz::Vector3f headingError = currentHeading.CrossProduct(desiredHeading);
|
||||
|
||||
Nz::Vector3f desiredUp = headingNode.GetUp();
|
||||
Nz::Vector3f currentUp = currentRotation * Nz::Vector3f::Up();
|
||||
Nz::Vector3f upError = currentUp.CrossProduct(desiredUp);
|
||||
|
||||
playerShipBody.AddTorque(headingController.Update(headingError, elapsedTime) * 10.f);
|
||||
playerShipBody.AddTorque(upController.Update(upError, elapsedTime) * 10.f);
|
||||
|
||||
float mass = playerShipBody.GetMass();
|
||||
|
||||
if (Nz::Keyboard::IsKeyPressed(Nz::Keyboard::VKey::Up) || Nz::Keyboard::IsKeyPressed(Nz::Keyboard::VKey::Z))
|
||||
playerShipBody.AddForce(Nz::Vector3f::Forward() * 2.5f * mass, Nz::CoordSys::Local);
|
||||
|
||||
if (Nz::Keyboard::IsKeyPressed(Nz::Keyboard::VKey::Down) || Nz::Keyboard::IsKeyPressed(Nz::Keyboard::VKey::S))
|
||||
playerShipBody.AddForce(Nz::Vector3f::Backward() * 2.5f * mass, Nz::CoordSys::Local);
|
||||
|
||||
if (Nz::Keyboard::IsKeyPressed(Nz::Keyboard::VKey::Left) || Nz::Keyboard::IsKeyPressed(Nz::Keyboard::VKey::Q))
|
||||
playerShipBody.AddForce(Nz::Vector3f::Left() * 2.5f * mass, Nz::CoordSys::Local);
|
||||
|
||||
if (Nz::Keyboard::IsKeyPressed(Nz::Keyboard::VKey::Right) || Nz::Keyboard::IsKeyPressed(Nz::Keyboard::VKey::D))
|
||||
playerShipBody.AddForce(Nz::Vector3f::Right() * 2.5f * mass, Nz::CoordSys::Local);
|
||||
|
||||
if (Nz::Keyboard::IsKeyPressed(Nz::Keyboard::VKey::LShift) || Nz::Keyboard::IsKeyPressed(Nz::Keyboard::VKey::RShift))
|
||||
playerShipBody.AddForce(Nz::Vector3f::Up() * 3.f * mass, Nz::CoordSys::Local);
|
||||
|
||||
if (Nz::Keyboard::IsKeyPressed(Nz::Keyboard::VKey::LControl) || Nz::Keyboard::IsKeyPressed(Nz::Keyboard::VKey::RControl))
|
||||
playerShipBody.AddForce(Nz::Vector3f::Down() * 3.f * mass, Nz::CoordSys::Local);
|
||||
}
|
||||
|
||||
Nz::RenderFrame frame = windowImpl->Acquire();
|
||||
if (!frame)
|
||||
continue;
|
||||
|
||||
Nz::UploadPool& uploadPool = frame.GetUploadPool();
|
||||
|
||||
viewerInstance.UpdateViewMatrix(Nz::Matrix4f::ViewMatrix(cameraNode.GetPosition(Nz::CoordSys::Global), cameraNode.GetRotation(Nz::CoordSys::Global)));
|
||||
|
||||
frame.Execute([&](Nz::CommandBufferBuilder& builder)
|
||||
{
|
||||
builder.BeginDebugRegion("UBO Update", Nz::Color::Yellow);
|
||||
{
|
||||
builder.PreTransferBarrier();
|
||||
|
||||
viewerInstance.UpdateBuffers(uploadPool, builder);
|
||||
/*
|
||||
modelInstance.UpdateBuffers(uploadPool, builder);
|
||||
modelInstance2.UpdateBuffers(uploadPool, builder);
|
||||
*/
|
||||
|
||||
auto view = registry.view<Nz::GraphicsComponent, const Nz::NodeComponent>();
|
||||
for (auto [entity, gfxComponent, nodeComponent] : view.each())
|
||||
{
|
||||
Nz::WorldInstance& worldInstance = gfxComponent.GetWorldInstance();
|
||||
worldInstance.UpdateWorldMatrix(nodeComponent.GetTransformMatrix());
|
||||
|
||||
worldInstance.UpdateBuffers(uploadPool, builder);
|
||||
}
|
||||
|
||||
if (material->Update(frame, builder))
|
||||
rebuildCommandBuffer = true;
|
||||
|
||||
if (colliderMat->Update(frame, builder))
|
||||
rebuildCommandBuffer = true;
|
||||
|
||||
builder.PostTransferBarrier();
|
||||
}
|
||||
builder.EndDebugRegion();
|
||||
}, Nz::QueueType::Transfer);
|
||||
|
||||
if (rebuildCommandBuffer || frame.IsFramebufferInvalidated())
|
||||
{
|
||||
frame.PushForRelease(std::move(drawCommandBuffer));
|
||||
RebuildCommandBuffer();
|
||||
}
|
||||
|
||||
frame.SubmitCommandBuffer(drawCommandBuffer.get(), Nz::QueueType::Graphics);
|
||||
|
||||
frame.Present();
|
||||
|
||||
window.Display();
|
||||
|
||||
rebuildCommandBuffer = false;
|
||||
|
||||
fps++;
|
||||
|
||||
if (secondClock.GetMilliseconds() >= 1000)
|
||||
{
|
||||
window.SetTitle(windowTitle + " - " + Nz::NumberToString(fps) + " FPS");
|
||||
|
||||
fps = 0;
|
||||
|
||||
secondClock.Restart();
|
||||
}
|
||||
}
|
||||
|
||||
registry.clear();
|
||||
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
|
|
@ -0,0 +1,6 @@
|
|||
target("PhysicsDemo")
|
||||
set_group("Examples")
|
||||
set_kind("binary")
|
||||
add_deps("NazaraGraphics", "NazaraPhysics3D")
|
||||
add_packages("entt")
|
||||
add_files("main.cpp")
|
||||
|
|
@ -0,0 +1,46 @@
|
|||
// Copyright (C) 2020 Jérôme Leclercq
|
||||
// This file is part of the "Nazara Engine - Core module"
|
||||
// For conditions of distribution and use, see copyright notice in Config.hpp
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifndef NAZARA_ECS_HPP
|
||||
#define NAZARA_ECS_HPP
|
||||
|
||||
#include <Nazara/Prerequisites.hpp>
|
||||
#include <Nazara/Core/Core.hpp>
|
||||
#include <entt/entt.hpp>
|
||||
|
||||
namespace Nz
|
||||
{
|
||||
class GraphicsComponent;
|
||||
class NodeComponent;
|
||||
class RigidBody3DComponent;
|
||||
|
||||
class ECS : public ModuleBase<ECS>
|
||||
{
|
||||
friend ModuleBase;
|
||||
friend class Audio;
|
||||
friend class Graphics;
|
||||
friend class Physics2D;
|
||||
friend class Physics3D;
|
||||
friend class Utility;
|
||||
|
||||
public:
|
||||
using Dependencies = TypeList<Core>;
|
||||
|
||||
struct Config {};
|
||||
|
||||
inline ECS(Config /*config*/);
|
||||
~ECS() = default;
|
||||
|
||||
private:
|
||||
static inline void RegisterComponents();
|
||||
|
||||
NAZARA_CORE_API static ECS* s_instance;
|
||||
};
|
||||
}
|
||||
|
||||
#include <Nazara/Core/ECS.inl>
|
||||
|
||||
#endif
|
||||
|
|
@ -0,0 +1,35 @@
|
|||
// Copyright (C) 2020 Jérôme Leclercq
|
||||
// This file is part of the "Nazara Engine - Core module"
|
||||
// For conditions of distribution and use, see copyright notice in Config.hpp
|
||||
|
||||
#include <Nazara/Core/ECS.hpp>
|
||||
#include <stdexcept>
|
||||
#include <Nazara/Core/Debug.hpp>
|
||||
|
||||
namespace Nz
|
||||
{
|
||||
/*!
|
||||
* \ingroup core
|
||||
* \class Nz::ECS
|
||||
* \brief Core class that represents the ECS module
|
||||
*/
|
||||
inline ECS::ECS(Config /*config*/) :
|
||||
ModuleBase("ECS", this)
|
||||
{
|
||||
RegisterComponents();
|
||||
}
|
||||
|
||||
inline void ECS::RegisterComponents()
|
||||
{
|
||||
if (entt::type_seq<NodeComponent>() != 0)
|
||||
throw std::runtime_error("NodeComponent has wrong index, please initialize Nazara ECS before instancing your own components");
|
||||
|
||||
if (entt::type_seq<GraphicsComponent>() != 1)
|
||||
throw std::runtime_error("GraphicsComponent has wrong index, please initialize Nazara ECS before instancing your own components");
|
||||
|
||||
if (entt::type_seq<RigidBody3DComponent>() != 2)
|
||||
throw std::runtime_error("GraphicsComponent has wrong index, please initialize Nazara ECS before instancing your own components");
|
||||
}
|
||||
}
|
||||
|
||||
#include <Nazara/Core/DebugOff.hpp>
|
||||
|
|
@ -39,6 +39,7 @@
|
|||
#include <Nazara/Graphics/FramePassAttachment.hpp>
|
||||
#include <Nazara/Graphics/GraphicalMesh.hpp>
|
||||
#include <Nazara/Graphics/Graphics.hpp>
|
||||
#include <Nazara/Graphics/InstancedRenderable.hpp>
|
||||
#include <Nazara/Graphics/Material.hpp>
|
||||
#include <Nazara/Graphics/MaterialPipeline.hpp>
|
||||
#include <Nazara/Graphics/MaterialSettings.hpp>
|
||||
|
|
|
|||
|
|
@ -0,0 +1,34 @@
|
|||
// This file was automatically generated
|
||||
|
||||
/*
|
||||
Nazara Engine - Graphics module
|
||||
|
||||
Copyright (C) 2020 Jérôme "Lynix" Leclercq (Lynix680@gmail.com)
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
this software and associated documentation files (the "Software"), to deal in
|
||||
the Software without restriction, including without limitation the rights to
|
||||
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
|
||||
of the Software, and to permit persons to whom the Software is furnished to do
|
||||
so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifndef NAZARA_GLOBAL_GRAPHICS_COMPONENTS_HPP
|
||||
#define NAZARA_GLOBAL_GRAPHICS_COMPONENTS_HPP
|
||||
|
||||
#include <Nazara/Graphics/Components/GraphicsComponent.hpp>
|
||||
|
||||
#endif // NAZARA_GLOBAL_GRAPHICS_COMPONENTS_HPP
|
||||
|
|
@ -0,0 +1,45 @@
|
|||
// Copyright (C) 2021 Jérôme Leclercq
|
||||
// This file is part of the "Nazara Engine - Graphics module"
|
||||
// For conditions of distribution and use, see copyright notice in Config.hpp
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifndef NAZARA_GRAPHICSCOMPONENT_HPP
|
||||
#define NAZARA_GRAPHICSCOMPONENT_HPP
|
||||
|
||||
#include <Nazara/Prerequisites.hpp>
|
||||
#include <Nazara/Core/ECS.hpp>
|
||||
#include <Nazara/Graphics/InstancedRenderable.hpp>
|
||||
#include <Nazara/Graphics/WorldInstance.hpp>
|
||||
#include <memory>
|
||||
#include <vector>
|
||||
|
||||
namespace Nz
|
||||
{
|
||||
class NAZARA_GRAPHICS_API GraphicsComponent
|
||||
{
|
||||
public:
|
||||
GraphicsComponent() = default;
|
||||
GraphicsComponent(const GraphicsComponent&) = default;
|
||||
GraphicsComponent(GraphicsComponent&&) = default;
|
||||
~GraphicsComponent() = default;
|
||||
|
||||
inline void AttachRenderable(std::shared_ptr<InstancedRenderable> renderable);
|
||||
inline void DetachRenderable(const std::shared_ptr<InstancedRenderable>& renderable);
|
||||
|
||||
inline const std::vector<std::shared_ptr<InstancedRenderable>>& GetRenderables() const;
|
||||
inline WorldInstance& GetWorldInstance();
|
||||
inline const WorldInstance& GetWorldInstance() const;
|
||||
|
||||
GraphicsComponent& operator=(const GraphicsComponent&) = default;
|
||||
GraphicsComponent& operator=(GraphicsComponent&&) = default;
|
||||
|
||||
private:
|
||||
std::vector<std::shared_ptr<InstancedRenderable>> m_renderables;
|
||||
WorldInstance m_worldInstance;
|
||||
};
|
||||
}
|
||||
|
||||
#include <Nazara/Graphics/Components/GraphicsComponent.inl>
|
||||
|
||||
#endif
|
||||
|
|
@ -0,0 +1,37 @@
|
|||
// Copyright (C) 2021 Jérôme Leclercq
|
||||
// This file is part of the "Nazara Engine - Utility module"
|
||||
// For conditions of distribution and use, see copyright notice in Prerequisites.hpp
|
||||
|
||||
#include <Nazara/Utility/Components/NodeComponent.hpp>
|
||||
#include <Nazara/Utility/Debug.hpp>
|
||||
#include "GraphicsComponent.hpp"
|
||||
|
||||
namespace Nz
|
||||
{
|
||||
inline void GraphicsComponent::AttachRenderable(std::shared_ptr<InstancedRenderable> renderable)
|
||||
{
|
||||
m_renderables.push_back(std::move(renderable));
|
||||
}
|
||||
|
||||
inline void GraphicsComponent::DetachRenderable(const std::shared_ptr<InstancedRenderable>& renderable)
|
||||
{
|
||||
auto it = std::find(m_renderables.begin(), m_renderables.end(), renderable);
|
||||
if (it != m_renderables.end())
|
||||
m_renderables.erase(it);
|
||||
}
|
||||
|
||||
inline const std::vector<std::shared_ptr<InstancedRenderable>>& GraphicsComponent::GetRenderables() const
|
||||
{
|
||||
return m_renderables;
|
||||
}
|
||||
|
||||
inline WorldInstance& GraphicsComponent::GetWorldInstance()
|
||||
{
|
||||
return m_worldInstance;
|
||||
}
|
||||
|
||||
inline const WorldInstance& GraphicsComponent::GetWorldInstance() const
|
||||
{
|
||||
return m_worldInstance;
|
||||
}
|
||||
}
|
||||
|
|
@ -23,7 +23,7 @@ namespace Nz
|
|||
InstancedRenderable(InstancedRenderable&&) noexcept = default;
|
||||
~InstancedRenderable();
|
||||
|
||||
virtual void Draw(CommandBufferBuilder& commandBuffer, WorldInstance& instance) const = 0;
|
||||
virtual void Draw(CommandBufferBuilder& commandBuffer, const WorldInstance& instance) const = 0;
|
||||
|
||||
InstancedRenderable& operator=(const InstancedRenderable&) = delete;
|
||||
InstancedRenderable& operator=(InstancedRenderable&&) noexcept = default;
|
||||
|
|
|
|||
|
|
@ -68,6 +68,7 @@ namespace Nz
|
|||
inline const std::shared_ptr<MaterialPipeline>& GetPipeline() const;
|
||||
inline const MaterialPipelineInfo& GetPipelineInfo() const;
|
||||
inline float GetPointSize() const;
|
||||
inline PrimitiveMode GetPrimitiveMode() const;
|
||||
inline const std::shared_ptr<const MaterialSettings>& GetSettings() const;
|
||||
inline const std::shared_ptr<UberShader>& GetShader(ShaderStageType shaderStage) const;
|
||||
inline ShaderBinding& GetShaderBinding();
|
||||
|
|
@ -100,6 +101,7 @@ namespace Nz
|
|||
inline void SetFaceFilling(FaceFilling filling);
|
||||
inline void SetLineWidth(float lineWidth);
|
||||
inline void SetPointSize(float pointSize);
|
||||
inline void SetPrimitiveMode(PrimitiveMode mode);
|
||||
inline void SetTexture(std::size_t textureIndex, std::shared_ptr<Texture> texture);
|
||||
inline void SetTextureSampler(std::size_t textureIndex, TextureSamplerInfo samplerInfo);
|
||||
inline void SetUniformBuffer(std::size_t bufferIndex, std::shared_ptr<AbstractBuffer> uniformBuffer);
|
||||
|
|
|
|||
|
|
@ -425,6 +425,11 @@ namespace Nz
|
|||
return m_pipelineInfo.pointSize;
|
||||
}
|
||||
|
||||
inline PrimitiveMode Material::GetPrimitiveMode() const
|
||||
{
|
||||
return m_pipelineInfo.primitiveMode;
|
||||
}
|
||||
|
||||
inline const std::shared_ptr<const MaterialSettings>& Material::GetSettings() const
|
||||
{
|
||||
return m_settings;
|
||||
|
|
@ -693,6 +698,14 @@ namespace Nz
|
|||
InvalidatePipeline();
|
||||
}
|
||||
|
||||
|
||||
inline void Material::SetPrimitiveMode(PrimitiveMode mode)
|
||||
{
|
||||
m_pipelineInfo.primitiveMode = mode;
|
||||
|
||||
InvalidatePipeline();
|
||||
}
|
||||
|
||||
inline void Material::SetTexture(std::size_t textureIndex, std::shared_ptr<Texture> texture)
|
||||
{
|
||||
NazaraAssert(textureIndex < m_textures.size(), "Invalid texture index");
|
||||
|
|
|
|||
|
|
@ -28,7 +28,7 @@ namespace Nz
|
|||
Model(Model&&) noexcept = default;
|
||||
~Model() = default;
|
||||
|
||||
void Draw(CommandBufferBuilder& commandBuffer, WorldInstance& instance) const override;
|
||||
void Draw(CommandBufferBuilder& commandBuffer, const WorldInstance& instance) const override;
|
||||
|
||||
const std::shared_ptr<AbstractBuffer>& GetIndexBuffer(std::size_t subMeshIndex) const;
|
||||
std::size_t GetIndexCount(std::size_t subMeshIndex) const;
|
||||
|
|
|
|||
|
|
@ -31,6 +31,7 @@ namespace Nz
|
|||
inline std::shared_ptr<AbstractBuffer>& GetInstanceBuffer();
|
||||
inline const std::shared_ptr<AbstractBuffer>& GetInstanceBuffer() const;
|
||||
inline ShaderBinding& GetShaderBinding();
|
||||
inline const ShaderBinding& GetShaderBinding() const;
|
||||
|
||||
void UpdateBuffers(UploadPool& uploadPool, CommandBufferBuilder& builder);
|
||||
inline void UpdateWorldMatrix(const Matrix4f& worldMatrix);
|
||||
|
|
|
|||
|
|
@ -23,6 +23,11 @@ namespace Nz
|
|||
return *m_shaderBinding;
|
||||
}
|
||||
|
||||
inline const ShaderBinding& WorldInstance::GetShaderBinding() const
|
||||
{
|
||||
return *m_shaderBinding;
|
||||
}
|
||||
|
||||
inline void WorldInstance::UpdateWorldMatrix(const Matrix4f& worldMatrix)
|
||||
{
|
||||
m_worldMatrix = worldMatrix;
|
||||
|
|
|
|||
|
|
@ -40,6 +40,7 @@
|
|||
#include <Nazara/Math/Frustum.hpp>
|
||||
#include <Nazara/Math/Matrix4.hpp>
|
||||
#include <Nazara/Math/OrientedBox.hpp>
|
||||
#include <Nazara/Math/PidController.hpp>
|
||||
#include <Nazara/Math/Plane.hpp>
|
||||
#include <Nazara/Math/Quaternion.hpp>
|
||||
#include <Nazara/Math/Ray.hpp>
|
||||
|
|
|
|||
|
|
@ -0,0 +1,31 @@
|
|||
// Copyright (C) 2021 Jérôme Leclercq
|
||||
// This file is part of the "Nazara Engine - Mathematics module"
|
||||
// For conditions of distribution and use, see copyright notice in Config.hpp
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifndef NAZARA_PIDCONTROLLER_HPP
|
||||
#define NAZARA_PIDCONTROLLER_HPP
|
||||
|
||||
namespace Nz
|
||||
{
|
||||
template<typename T>
|
||||
class PidController
|
||||
{
|
||||
public:
|
||||
PidController(float p, float i, float d);
|
||||
|
||||
T Update(const T& currentError, float elapsedTime);
|
||||
|
||||
private:
|
||||
T m_lastError;
|
||||
T m_integral;
|
||||
float m_dFactor;
|
||||
float m_iFactor;
|
||||
float m_pFactor;
|
||||
};
|
||||
}
|
||||
|
||||
#include <Nazara/Math/PidController.inl>
|
||||
|
||||
#endif
|
||||
|
|
@ -0,0 +1,28 @@
|
|||
// Copyright (C) 2021 Jérôme Leclercq
|
||||
// This file is part of the "Nazara Engine - Mathematics module"
|
||||
// For conditions of distribution and use, see copyright notice in Config.hpp
|
||||
|
||||
#include <Nazara/Math/PidController.hpp>
|
||||
|
||||
namespace Nz
|
||||
{
|
||||
template<typename T>
|
||||
PidController<T>::PidController(float p, float i, float d) :
|
||||
m_lastError(0),
|
||||
m_integral(0),
|
||||
m_dFactor(d),
|
||||
m_iFactor(i),
|
||||
m_pFactor(p)
|
||||
{
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
T PidController<T>::Update(const T& currentError, float elapsedTime)
|
||||
{
|
||||
m_integral += currentError * elapsedTime;
|
||||
T deriv = (currentError - m_lastError) / elapsedTime;
|
||||
m_lastError = currentError;
|
||||
|
||||
return currentError * m_pFactor + m_integral * m_iFactor + deriv * m_dFactor;
|
||||
}
|
||||
}
|
||||
|
|
@ -31,6 +31,7 @@ namespace Nz
|
|||
|
||||
inline GLenum ToOpenGL(BlendEquation blendEquation);
|
||||
inline GLenum ToOpenGL(BlendFunc blendFunc);
|
||||
inline GLenum ToOpenGL(FaceFilling filling);
|
||||
inline GLenum ToOpenGL(FaceSide side);
|
||||
inline GLenum ToOpenGL(FrontFace face);
|
||||
inline GLenum ToOpenGL(PrimitiveMode primitiveMode);
|
||||
|
|
|
|||
|
|
@ -74,6 +74,19 @@ namespace Nz
|
|||
NazaraError("Unhandled BlendFunc 0x" + NumberToString(UnderlyingCast(blendFunc), 16));
|
||||
return {};
|
||||
}
|
||||
|
||||
inline GLenum ToOpenGL(FaceFilling side)
|
||||
{
|
||||
switch (side)
|
||||
{
|
||||
case FaceFilling::Fill: return GL_FILL;
|
||||
case FaceFilling::Line: return GL_LINE;
|
||||
case FaceFilling::Point: return GL_POINT;
|
||||
}
|
||||
|
||||
NazaraError("Unhandled FaceFilling 0x" + NumberToString(UnderlyingCast(side), 16));
|
||||
return {};
|
||||
}
|
||||
|
||||
inline GLenum ToOpenGL(FaceSide side)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -1,5 +1,29 @@
|
|||
// This file was automatically generated
|
||||
|
||||
/*
|
||||
Nazara Engine - OpenGL
|
||||
|
||||
Copyright (C) 2015 Jérôme "Lynix" Leclercq (Lynix680@gmail.com)
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
this software and associated documentation files (the "Software"), to deal in
|
||||
the Software without restriction, including without limitation the rights to
|
||||
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
|
||||
of the Software, and to permit persons to whom the Software is furnished to do
|
||||
so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifndef NAZARA_GLOBAL_OPENGLRENDERER_WRAPPER_HPP
|
||||
|
|
|
|||
|
|
@ -12,8 +12,12 @@
|
|||
#include <GLES2/gl2ext.h>
|
||||
|
||||
// Define some OpenGL (not ES) extensions
|
||||
#define GL_POINT 0x1B00
|
||||
#define GL_LINE 0x1B01
|
||||
#define GL_FILL 0x1B02
|
||||
#define GL_SHADER_BINARY_FORMAT_SPIR_V_ARB 0x9551
|
||||
#define GL_SPIR_V_BINARY_ARB 0x9552
|
||||
typedef void (GL_APIENTRYP PFNGLPOLYGONMODEPROC) (GLenum face, GLenum mode);
|
||||
typedef void (GL_APIENTRYP PFNGLSPECIALIZESHADERARBPROC) (GLuint shader, const GLchar* pEntryPoint, GLuint numSpecializationConstants, const GLuint* pConstantIndex, const GLuint* pConstantValue);
|
||||
|
||||
// OpenGL core
|
||||
|
|
@ -163,6 +167,8 @@ typedef void (GL_APIENTRYP PFNGLSPECIALIZESHADERARBPROC) (GLuint shader, const G
|
|||
\
|
||||
extCb(glDebugMessageCallback, PFNGLDEBUGMESSAGECALLBACKPROC) \
|
||||
\
|
||||
extCb(glPolygonMode, PFNGLPOLYGONMODEPROC) \
|
||||
\
|
||||
extCb(glMemoryBarrier, PFNGLMEMORYBARRIERPROC) \
|
||||
extCb(glMemoryBarrierByRegion, PFNGLMEMORYBARRIERBYREGIONPROC) \
|
||||
\
|
||||
|
|
|
|||
|
|
@ -30,6 +30,7 @@ namespace Nz
|
|||
|
||||
class PrimitiveList;
|
||||
class PhysWorld3D;
|
||||
class StaticMesh;
|
||||
|
||||
class NAZARA_PHYSICS3D_API Collider3D
|
||||
{
|
||||
|
|
@ -48,6 +49,8 @@ namespace Nz
|
|||
|
||||
virtual void ForEachPolygon(const std::function<void(const Vector3f* vertices, std::size_t vertexCount)>& callback) const;
|
||||
|
||||
virtual std::shared_ptr<StaticMesh> GenerateMesh() const;
|
||||
|
||||
NewtonCollision* GetHandle(PhysWorld3D* world) const;
|
||||
virtual ColliderType3D GetType() const = 0;
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,34 @@
|
|||
// This file was automatically generated
|
||||
|
||||
/*
|
||||
Nazara Engine - Physics 3D module
|
||||
|
||||
Copyright (C) 2015 Jérôme "Lynix" Leclercq (Lynix680@gmail.com)
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
this software and associated documentation files (the "Software"), to deal in
|
||||
the Software without restriction, including without limitation the rights to
|
||||
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
|
||||
of the Software, and to permit persons to whom the Software is furnished to do
|
||||
so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifndef NAZARA_GLOBAL_PHYSICS3D_COMPONENTS_HPP
|
||||
#define NAZARA_GLOBAL_PHYSICS3D_COMPONENTS_HPP
|
||||
|
||||
#include <Nazara/Physics3D/Components/RigidBody3DComponent.hpp>
|
||||
|
||||
#endif // NAZARA_GLOBAL_PHYSICS3D_COMPONENTS_HPP
|
||||
|
|
@ -0,0 +1,30 @@
|
|||
// Copyright (C) 2021 Jérôme Leclercq
|
||||
// This file is part of the "Nazara Engine - Physics 3D module"
|
||||
// For conditions of distribution and use, see copyright notice in Config.hpp
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifndef NAZARA_RIGIDBODYCOMPONENT_HPP
|
||||
#define NAZARA_RIGIDBODYCOMPONENT_HPP
|
||||
|
||||
#include <Nazara/Prerequisites.hpp>
|
||||
#include <Nazara/Physics3D/RigidBody3D.hpp>
|
||||
|
||||
namespace Nz
|
||||
{
|
||||
class NAZARA_PHYSICS3D_API RigidBody3DComponent : public RigidBody3D
|
||||
{
|
||||
public:
|
||||
using RigidBody3D::RigidBody3D;
|
||||
RigidBody3DComponent(const RigidBody3DComponent&) = default;
|
||||
RigidBody3DComponent(RigidBody3DComponent&&) noexcept = default;
|
||||
~RigidBody3DComponent() = default;
|
||||
|
||||
RigidBody3DComponent& operator=(const RigidBody3DComponent&) = default;
|
||||
RigidBody3DComponent& operator=(RigidBody3DComponent&&) noexcept = default;
|
||||
};
|
||||
}
|
||||
|
||||
#include <Nazara/Physics3D/Components/RigidBody3DComponent.inl>
|
||||
|
||||
#endif
|
||||
|
|
@ -0,0 +1,12 @@
|
|||
// Copyright (C) 2021 Jérôme Leclercq
|
||||
// This file is part of the "Nazara Engine - Physics 3D module"
|
||||
// For conditions of distribution and use, see copyright notice in Prerequisites.hpp
|
||||
|
||||
#include <Nazara/Physics3D/Components/RigidBody3DComponent.hpp>
|
||||
#include <Nazara/Physics3D/Debug.hpp>
|
||||
|
||||
namespace Nz
|
||||
{
|
||||
}
|
||||
|
||||
#include <Nazara/Physics3D/DebugOff.hpp>
|
||||
|
|
@ -33,7 +33,7 @@ namespace Nz
|
|||
|
||||
PhysWorld3D();
|
||||
PhysWorld3D(const PhysWorld3D&) = delete;
|
||||
PhysWorld3D(PhysWorld3D&&) noexcept = default;
|
||||
PhysWorld3D(PhysWorld3D&& ph) noexcept;
|
||||
~PhysWorld3D();
|
||||
|
||||
int CreateMaterial(std::string name = {});
|
||||
|
|
@ -62,7 +62,7 @@ namespace Nz
|
|||
void Step(float timestep);
|
||||
|
||||
PhysWorld3D& operator=(const PhysWorld3D&) = delete;
|
||||
PhysWorld3D& operator=(PhysWorld3D&&) noexcept = default;
|
||||
PhysWorld3D& operator=(PhysWorld3D&&) noexcept;
|
||||
|
||||
private:
|
||||
struct Callback
|
||||
|
|
|
|||
|
|
@ -9,6 +9,7 @@
|
|||
|
||||
#include <Nazara/Prerequisites.hpp>
|
||||
#include <Nazara/Core/Enums.hpp>
|
||||
#include <Nazara/Core/MovablePtr.hpp>
|
||||
#include <Nazara/Math/Matrix4.hpp>
|
||||
#include <Nazara/Math/Quaternion.hpp>
|
||||
#include <Nazara/Math/Vector3.hpp>
|
||||
|
|
@ -27,7 +28,7 @@ namespace Nz
|
|||
RigidBody3D(PhysWorld3D* world, const Matrix4f& mat = Matrix4f::Identity());
|
||||
RigidBody3D(PhysWorld3D* world, std::shared_ptr<Collider3D> geom, const Matrix4f& mat = Matrix4f::Identity());
|
||||
RigidBody3D(const RigidBody3D& object);
|
||||
RigidBody3D(RigidBody3D&& object);
|
||||
RigidBody3D(RigidBody3D&& object) noexcept;
|
||||
~RigidBody3D();
|
||||
|
||||
void AddForce(const Vector3f& force, CoordSys coordSys = CoordSys::Global);
|
||||
|
|
@ -74,7 +75,7 @@ namespace Nz
|
|||
void SetUserdata(void* ud);
|
||||
|
||||
RigidBody3D& operator=(const RigidBody3D& object);
|
||||
RigidBody3D& operator=(RigidBody3D&& object);
|
||||
RigidBody3D& operator=(RigidBody3D&& object) noexcept;
|
||||
|
||||
private:
|
||||
void UpdateBody();
|
||||
|
|
@ -83,9 +84,9 @@ namespace Nz
|
|||
|
||||
std::shared_ptr<Collider3D> m_geom;
|
||||
Matrix4f m_matrix;
|
||||
MovablePtr<NewtonBody> m_body;
|
||||
Vector3f m_forceAccumulator;
|
||||
Vector3f m_torqueAccumulator;
|
||||
NewtonBody* m_body;
|
||||
PhysWorld3D* m_world;
|
||||
void* m_userdata;
|
||||
float m_gravityFactor;
|
||||
|
|
|
|||
|
|
@ -0,0 +1,34 @@
|
|||
// This file was automatically generated
|
||||
|
||||
/*
|
||||
Nazara Engine - Physics 3D module
|
||||
|
||||
Copyright (C) 2015 Jérôme "Lynix" Leclercq (Lynix680@gmail.com)
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
this software and associated documentation files (the "Software"), to deal in
|
||||
the Software without restriction, including without limitation the rights to
|
||||
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
|
||||
of the Software, and to permit persons to whom the Software is furnished to do
|
||||
so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifndef NAZARA_GLOBAL_PHYSICS3D_SYSTEMS_HPP
|
||||
#define NAZARA_GLOBAL_PHYSICS3D_SYSTEMS_HPP
|
||||
|
||||
#include <Nazara/Physics3D/Systems/Physics3DSystem.hpp>
|
||||
|
||||
#endif // NAZARA_GLOBAL_PHYSICS3D_SYSTEMS_HPP
|
||||
|
|
@ -0,0 +1,45 @@
|
|||
// Copyright (C) 2021 Jérôme Leclercq
|
||||
// This file is part of the "Nazara Engine - Utility module"
|
||||
// For conditions of distribution and use, see copyright notice in Config.hpp
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifndef NAZARA_PHYSICS3DSYSTEM_HPP
|
||||
#define NAZARA_PHYSICS3DSYSTEM_HPP
|
||||
|
||||
#include <Nazara/Prerequisites.hpp>
|
||||
#include <Nazara/Core/ECS.hpp>
|
||||
#include <Nazara/Physics3D/PhysWorld3D.hpp>
|
||||
#include <Nazara/Physics3D/Components/RigidBody3DComponent.hpp>
|
||||
|
||||
namespace Nz
|
||||
{
|
||||
class NAZARA_PHYSICS3D_API Physics3DSystem
|
||||
{
|
||||
public:
|
||||
Physics3DSystem(entt::registry& registry);
|
||||
Physics3DSystem(const Physics3DSystem&) = delete;
|
||||
Physics3DSystem(Physics3DSystem&&) = delete;
|
||||
~Physics3DSystem();
|
||||
|
||||
template<typename... Args> RigidBody3DComponent CreateRigidBody(Args&&... args);
|
||||
|
||||
inline PhysWorld3D& GetPhysWorld();
|
||||
inline const PhysWorld3D& GetPhysWorld() const;
|
||||
|
||||
void Update(entt::registry& registry, float elapsedTime);
|
||||
|
||||
Physics3DSystem& operator=(const Physics3DSystem&) = delete;
|
||||
Physics3DSystem& operator=(Physics3DSystem&&) = delete;
|
||||
|
||||
private:
|
||||
static void OnConstruct(entt::registry& registry, entt::entity entity);
|
||||
|
||||
entt::connection m_constructConnection;
|
||||
PhysWorld3D m_physWorld;
|
||||
};
|
||||
}
|
||||
|
||||
#include <Nazara/Physics3D/Systems/Physics3DSystem.inl>
|
||||
|
||||
#endif
|
||||
|
|
@ -0,0 +1,27 @@
|
|||
// Copyright (C) 2021 Jérôme Leclercq
|
||||
// This file is part of the "Nazara Engine - Utility module"
|
||||
// For conditions of distribution and use, see copyright notice in Prerequisites.hpp
|
||||
|
||||
#include <Nazara/Physics3D/Systems/Physics3DSystem.hpp>
|
||||
#include <Nazara/Physics3D/Debug.hpp>
|
||||
|
||||
namespace Nz
|
||||
{
|
||||
template<typename... Args>
|
||||
RigidBody3DComponent Physics3DSystem::CreateRigidBody(Args&&... args)
|
||||
{
|
||||
return RigidBody3DComponent(&m_physWorld, std::forward<Args>(args)...);
|
||||
}
|
||||
|
||||
inline PhysWorld3D& Physics3DSystem::GetPhysWorld()
|
||||
{
|
||||
return m_physWorld;
|
||||
}
|
||||
|
||||
inline const PhysWorld3D& Physics3DSystem::GetPhysWorld() const
|
||||
{
|
||||
return m_physWorld;
|
||||
}
|
||||
}
|
||||
|
||||
#include <Nazara/Physics3D/DebugOff.hpp>
|
||||
|
|
@ -16,6 +16,7 @@ namespace Nz
|
|||
struct RenderDeviceFeatures
|
||||
{
|
||||
bool anisotropicFiltering = false;
|
||||
bool nonSolidFaceFilling = false;
|
||||
};
|
||||
|
||||
struct RenderDeviceLimits
|
||||
|
|
|
|||
|
|
@ -0,0 +1,34 @@
|
|||
// This file was automatically generated
|
||||
|
||||
/*
|
||||
Nazara Engine - Utility module
|
||||
|
||||
Copyright (C) 2015 Jérôme "Lynix" Leclercq (Lynix680@gmail.com)
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
this software and associated documentation files (the "Software"), to deal in
|
||||
the Software without restriction, including without limitation the rights to
|
||||
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
|
||||
of the Software, and to permit persons to whom the Software is furnished to do
|
||||
so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifndef NAZARA_GLOBAL_UTILITY_COMPONENTS_HPP
|
||||
#define NAZARA_GLOBAL_UTILITY_COMPONENTS_HPP
|
||||
|
||||
#include <Nazara/Utility/Components/NodeComponent.hpp>
|
||||
|
||||
#endif // NAZARA_GLOBAL_UTILITY_COMPONENTS_HPP
|
||||
|
|
@ -0,0 +1,34 @@
|
|||
// Copyright (C) 2021 Jérôme Leclercq
|
||||
// This file is part of the "Nazara Engine - Utility module"
|
||||
// For conditions of distribution and use, see copyright notice in Config.hpp
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifndef NAZARA_NODECOMPONENT_HPP
|
||||
#define NAZARA_NODECOMPONENT_HPP
|
||||
|
||||
#include <Nazara/Prerequisites.hpp>
|
||||
#include <Nazara/Core/ECS.hpp>
|
||||
#include <Nazara/Utility/Node.hpp>
|
||||
|
||||
namespace Nz
|
||||
{
|
||||
class NAZARA_UTILITY_API NodeComponent : public Node
|
||||
{
|
||||
public:
|
||||
NodeComponent() = default;
|
||||
NodeComponent(const NodeComponent&) = default;
|
||||
NodeComponent(NodeComponent&&) noexcept = default;
|
||||
~NodeComponent() = default;
|
||||
|
||||
void SetParent(entt::registry& registry, entt::entity entity, bool keepDerived = false);
|
||||
using Node::SetParent;
|
||||
|
||||
NodeComponent& operator=(const NodeComponent&) = default;
|
||||
NodeComponent& operator=(NodeComponent&&) noexcept = default;
|
||||
};
|
||||
}
|
||||
|
||||
#include <Nazara/Utility/Components/NodeComponent.inl>
|
||||
|
||||
#endif
|
||||
|
|
@ -0,0 +1,12 @@
|
|||
// Copyright (C) 2021 Jérôme Leclercq
|
||||
// This file is part of the "Nazara Engine - Utility module"
|
||||
// For conditions of distribution and use, see copyright notice in Prerequisites.hpp
|
||||
|
||||
#include <Nazara/Utility/Components/NodeComponent.hpp>
|
||||
#include <Nazara/Utility/Debug.hpp>
|
||||
|
||||
namespace Nz
|
||||
{
|
||||
}
|
||||
|
||||
#include <Nazara/Utility/DebugOff.hpp>
|
||||
|
|
@ -57,6 +57,7 @@ namespace Nz
|
|||
class Mesh;
|
||||
struct Primitive;
|
||||
class PrimitiveList;
|
||||
class StaticMesh;
|
||||
class SubMesh;
|
||||
|
||||
using MeshVertex = VertexStruct_XYZ_Normal_UV_Tangent;
|
||||
|
|
@ -132,6 +133,8 @@ namespace Nz
|
|||
Mesh& operator=(const Mesh&) = delete;
|
||||
Mesh& operator=(Mesh&&) = delete;
|
||||
|
||||
static inline std::shared_ptr<Mesh> Build(std::shared_ptr<StaticMesh> staticMesh);
|
||||
|
||||
static std::shared_ptr<Mesh> LoadFromFile(const std::filesystem::path& filePath, const MeshParams& params = MeshParams());
|
||||
static std::shared_ptr<Mesh> LoadFromMemory(const void* data, std::size_t size, const MeshParams& params = MeshParams());
|
||||
static std::shared_ptr<Mesh> LoadFromStream(Stream& stream, const MeshParams& params = MeshParams());
|
||||
|
|
|
|||
|
|
@ -4,16 +4,26 @@
|
|||
|
||||
#include <Nazara/Utility/Mesh.hpp>
|
||||
#include <memory>
|
||||
#include <Nazara/Utility/StaticMesh.hpp>
|
||||
#include <Nazara/Utility/Debug.hpp>
|
||||
|
||||
namespace Nz
|
||||
{
|
||||
Mesh::Mesh() :
|
||||
inline Mesh::Mesh() :
|
||||
m_materialData(1),
|
||||
m_aabbUpdated(false),
|
||||
m_isValid(false)
|
||||
{
|
||||
}
|
||||
|
||||
inline std::shared_ptr<Mesh> Mesh::Build(std::shared_ptr<StaticMesh> staticMesh)
|
||||
{
|
||||
std::shared_ptr<Mesh> mesh = std::make_shared<Mesh>();
|
||||
mesh->CreateStatic();
|
||||
mesh->AddSubMesh(std::move(staticMesh));
|
||||
|
||||
return mesh;
|
||||
}
|
||||
}
|
||||
|
||||
#include <Nazara/Utility/DebugOff.hpp>
|
||||
|
|
|
|||
|
|
@ -23,6 +23,7 @@ namespace Nz
|
|||
public:
|
||||
Node();
|
||||
Node(const Node& node);
|
||||
Node(Node&& node) noexcept;
|
||||
virtual ~Node();
|
||||
|
||||
void EnsureDerivedUpdate() const;
|
||||
|
|
@ -92,6 +93,7 @@ namespace Nz
|
|||
Vector3f ToLocalScale(const Vector3f& globalScale) const;
|
||||
|
||||
Node& operator=(const Node& node);
|
||||
Node& operator=(Node&& node) noexcept;
|
||||
|
||||
// Signals:
|
||||
NazaraSignal(OnNodeInvalidation, const Node* /*node*/);
|
||||
|
|
|
|||
|
|
@ -54,6 +54,5 @@
|
|||
#include <Nazara/VulkanRenderer/VulkanTexture.hpp>
|
||||
#include <Nazara/VulkanRenderer/VulkanTextureSampler.hpp>
|
||||
#include <Nazara/VulkanRenderer/VulkanUploadPool.hpp>
|
||||
#include <Nazara/VulkanRenderer/Wrapper.hpp>
|
||||
|
||||
#endif // NAZARA_GLOBAL_VULKANRENDERER_HPP
|
||||
|
|
|
|||
|
|
@ -1,5 +1,29 @@
|
|||
// This file was automatically generated
|
||||
|
||||
/*
|
||||
Nazara Engine - Vulkan
|
||||
|
||||
Copyright (C) 2015 Jérôme "Lynix" Leclercq (Lynix680@gmail.com)
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
this software and associated documentation files (the "Software"), to deal in
|
||||
the Software without restriction, including without limitation the rights to
|
||||
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
|
||||
of the Software, and to permit persons to whom the Software is furnished to do
|
||||
so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifndef NAZARA_GLOBAL_VULKANRENDERER_WRAPPER_HPP
|
||||
|
|
|
|||
|
|
@ -0,0 +1,11 @@
|
|||
// Copyright (C) 2020 Jérôme Leclercq
|
||||
// This file is part of the "Nazara Engine - Core module"
|
||||
// For conditions of distribution and use, see copyright notice in Config.hpp
|
||||
|
||||
#include <Nazara/Core/ECS.hpp>
|
||||
#include <Nazara/Core/Debug.hpp>
|
||||
|
||||
namespace Nz
|
||||
{
|
||||
NAZARA_CORE_API ECS* ECS::s_instance = nullptr;
|
||||
}
|
||||
|
|
@ -0,0 +1,10 @@
|
|||
// Copyright (C) 2021 Jérôme Leclercq
|
||||
// This file is part of the "Nazara Engine - Utility module"
|
||||
// For conditions of distribution and use, see copyright notice in Prerequisites.hpp
|
||||
|
||||
#include <Nazara/Graphics/Components/GraphicsComponent.hpp>
|
||||
#include <Nazara/Graphics/Debug.hpp>
|
||||
|
||||
namespace Nz
|
||||
{
|
||||
}
|
||||
|
|
@ -3,6 +3,7 @@
|
|||
// For conditions of distribution and use, see copyright notice in Config.hpp
|
||||
|
||||
#include <Nazara/Graphics/Graphics.hpp>
|
||||
#include <Nazara/Core/ECS.hpp>
|
||||
#include <Nazara/Graphics/MaterialPipeline.hpp>
|
||||
#include <Nazara/Graphics/PredefinedShaderStructs.hpp>
|
||||
#include <stdexcept>
|
||||
|
|
@ -18,6 +19,8 @@ namespace Nz
|
|||
Graphics::Graphics(Config config) :
|
||||
ModuleBase("Graphics", this)
|
||||
{
|
||||
ECS::RegisterComponents();
|
||||
|
||||
Renderer* renderer = Renderer::Instance();
|
||||
|
||||
const std::vector<RenderDeviceInfo>& renderDeviceInfo = renderer->QueryRenderDevices();
|
||||
|
|
@ -42,6 +45,7 @@ namespace Nz
|
|||
|
||||
RenderDeviceFeatures enabledFeatures;
|
||||
enabledFeatures.anisotropicFiltering = renderDeviceInfo[bestRenderDeviceIndex].features.anisotropicFiltering;
|
||||
enabledFeatures.nonSolidFaceFilling = renderDeviceInfo[bestRenderDeviceIndex].features.nonSolidFaceFilling;
|
||||
|
||||
m_renderDevice = renderer->InstanciateRenderDevice(bestRenderDeviceIndex, enabledFeatures);
|
||||
if (!m_renderDevice)
|
||||
|
|
|
|||
|
|
@ -29,7 +29,7 @@ namespace Nz
|
|||
}
|
||||
}
|
||||
|
||||
void Model::Draw(CommandBufferBuilder& commandBuffer, WorldInstance& instance) const
|
||||
void Model::Draw(CommandBufferBuilder& commandBuffer, const WorldInstance& instance) const
|
||||
{
|
||||
commandBuffer.BindShaderBinding(Graphics::WorldBindingSet, instance.GetShaderBinding());
|
||||
|
||||
|
|
|
|||
|
|
@ -56,6 +56,9 @@ namespace Nz
|
|||
if ((params.type == GL::ContextType::OpenGL && glVersion >= 460) || m_referenceContext->IsExtensionSupported(GL::Extension::TextureFilterAnisotropic))
|
||||
m_deviceInfo.features.anisotropicFiltering = true;
|
||||
|
||||
if (m_referenceContext->glPolygonMode) //< not supported in core OpenGL ES, but supported in OpenGL or with GL_NV_polygon_mode extension
|
||||
m_deviceInfo.features.nonSolidFaceFilling = true;
|
||||
|
||||
// Limits
|
||||
GLint minUboOffsetAlignment;
|
||||
m_referenceContext->glGetIntegerv(GL_UNIFORM_BUFFER_OFFSET_ALIGNMENT, &minUboOffsetAlignment);
|
||||
|
|
|
|||
|
|
@ -500,13 +500,11 @@ namespace Nz::GL
|
|||
m_state.renderStates.frontFace = targetFrontFace;
|
||||
}
|
||||
|
||||
/*
|
||||
TODO: Use glPolyonMode if available (OpenGL)
|
||||
if (m_state.renderStates.faceFilling != renderStates.faceFilling)
|
||||
if (glPolygonMode && m_state.renderStates.faceFilling != renderStates.faceFilling)
|
||||
{
|
||||
glPolygonMode(GL_FRONT_AND_BACK, FaceFilling[states.faceFilling]);
|
||||
glPolygonMode(GL_FRONT_AND_BACK, ToOpenGL(renderStates.faceFilling));
|
||||
m_state.renderStates.faceFilling = renderStates.faceFilling;
|
||||
}*/
|
||||
}
|
||||
|
||||
if (renderStates.stencilTest)
|
||||
{
|
||||
|
|
@ -663,6 +661,12 @@ namespace Nz::GL
|
|||
|
||||
return true;
|
||||
}
|
||||
else if (function == "glPolygonMode")
|
||||
{
|
||||
constexpr std::size_t functionIndex = UnderlyingCast(FunctionIndex::glPolygonMode);
|
||||
|
||||
return loader.Load<PFNGLPOLYGONMODENVPROC, functionIndex>(glPolygonMode, "glPolygonModeNV", false, false);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -5,6 +5,9 @@
|
|||
#include <Nazara/Physics3D/Collider3D.hpp>
|
||||
#include <Nazara/Core/PrimitiveList.hpp>
|
||||
#include <Nazara/Physics3D/PhysWorld3D.hpp>
|
||||
#include <Nazara/Utility/IndexBuffer.hpp>
|
||||
#include <Nazara/Utility/StaticMesh.hpp>
|
||||
#include <Nazara/Utility/VertexBuffer.hpp>
|
||||
#include <newton/Newton.h>
|
||||
#include <Nazara/Physics3D/Debug.hpp>
|
||||
|
||||
|
|
@ -139,6 +142,44 @@ namespace Nz
|
|||
NewtonCollisionForEachPolygonDo(m_handles.begin()->second, Nz::Matrix4f::Identity(), newtCallback, const_cast<void*>(static_cast<const void*>(&callback))); //< This isn't that bad; pointer will not be used for writing
|
||||
}
|
||||
|
||||
std::shared_ptr<StaticMesh> Collider3D::GenerateMesh() const
|
||||
{
|
||||
std::vector<Nz::Vector3f> colliderVertices;
|
||||
std::vector<Nz::UInt16> colliderIndices;
|
||||
|
||||
// Generate a line list
|
||||
ForEachPolygon([&](const Nz::Vector3f* vertices, std::size_t vertexCount)
|
||||
{
|
||||
Nz::UInt16 firstIndex = colliderVertices.size();
|
||||
for (std::size_t i = 0; i < vertexCount; ++i)
|
||||
colliderVertices.push_back(vertices[i]);
|
||||
|
||||
for (std::size_t i = 1; i < vertexCount; ++i)
|
||||
{
|
||||
colliderIndices.push_back(firstIndex + i - 1);
|
||||
colliderIndices.push_back(firstIndex + i);
|
||||
}
|
||||
|
||||
if (vertexCount > 2)
|
||||
{
|
||||
colliderIndices.push_back(firstIndex + vertexCount - 1);
|
||||
colliderIndices.push_back(firstIndex);
|
||||
}
|
||||
});
|
||||
|
||||
std::shared_ptr<Nz::VertexBuffer> colliderVB = std::make_shared<Nz::VertexBuffer>(Nz::VertexDeclaration::Get(Nz::VertexLayout::XYZ), colliderVertices.size(), Nz::DataStorage::Software, 0);
|
||||
colliderVB->Fill(colliderVertices.data(), 0, colliderVertices.size());
|
||||
|
||||
std::shared_ptr<Nz::IndexBuffer> colliderIB = std::make_shared<Nz::IndexBuffer>(false, colliderIndices.size(), Nz::DataStorage::Software, 0);
|
||||
colliderIB->Fill(colliderIndices.data(), 0, colliderIndices.size());
|
||||
|
||||
std::shared_ptr<Nz::StaticMesh> colliderSubMesh = std::make_shared<Nz::StaticMesh>(std::move(colliderVB), std::move(colliderIB));
|
||||
colliderSubMesh->GenerateAABB();
|
||||
colliderSubMesh->SetPrimitiveMode(Nz::PrimitiveMode::LineList);
|
||||
|
||||
return colliderSubMesh;
|
||||
}
|
||||
|
||||
NewtonCollision* Collider3D::GetHandle(PhysWorld3D* world) const
|
||||
{
|
||||
auto it = m_handles.find(world);
|
||||
|
|
|
|||
|
|
@ -0,0 +1,10 @@
|
|||
// Copyright (C) 2021 Jérôme Leclercq
|
||||
// This file is part of the "Nazara Engine - Physics 3D module"
|
||||
// For conditions of distribution and use, see copyright notice in Prerequisites.hpp
|
||||
|
||||
#include <Nazara/Physics3D/Components/RigidBody3DComponent.hpp>
|
||||
#include <Nazara/Physics3D/Debug.hpp>
|
||||
|
||||
namespace Nz
|
||||
{
|
||||
}
|
||||
|
|
@ -22,9 +22,22 @@ namespace Nz
|
|||
m_materialIds.emplace("default", NewtonMaterialGetDefaultGroupID(m_world));
|
||||
}
|
||||
|
||||
PhysWorld3D::PhysWorld3D(PhysWorld3D&& physWorld) noexcept :
|
||||
m_callbacks(std::move(physWorld.m_callbacks)),
|
||||
m_materialIds(std::move(physWorld.m_materialIds)),
|
||||
m_maxStepCount(std::move(physWorld.m_maxStepCount)),
|
||||
m_world(std::move(physWorld.m_world)),
|
||||
m_gravity(std::move(physWorld.m_gravity)),
|
||||
m_stepSize(std::move(physWorld.m_stepSize)),
|
||||
m_timestepAccumulator(std::move(physWorld.m_timestepAccumulator))
|
||||
{
|
||||
NewtonWorldSetUserData(m_world, this);
|
||||
}
|
||||
|
||||
PhysWorld3D::~PhysWorld3D()
|
||||
{
|
||||
NewtonDestroy(m_world);
|
||||
if (m_world)
|
||||
NewtonDestroy(m_world);
|
||||
}
|
||||
|
||||
int PhysWorld3D::CreateMaterial(std::string name)
|
||||
|
|
@ -159,6 +172,24 @@ namespace Nz
|
|||
}
|
||||
}
|
||||
|
||||
PhysWorld3D& PhysWorld3D::operator=(PhysWorld3D&& physWorld) noexcept
|
||||
{
|
||||
if (m_world)
|
||||
NewtonDestroy(m_world);
|
||||
|
||||
m_callbacks = std::move(physWorld.m_callbacks);
|
||||
m_materialIds = std::move(physWorld.m_materialIds);
|
||||
m_maxStepCount = std::move(physWorld.m_maxStepCount);
|
||||
m_world = std::move(physWorld.m_world);
|
||||
m_gravity = std::move(physWorld.m_gravity);
|
||||
m_stepSize = std::move(physWorld.m_stepSize);
|
||||
m_timestepAccumulator = std::move(physWorld.m_timestepAccumulator);
|
||||
|
||||
NewtonWorldSetUserData(m_world, this);
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
int PhysWorld3D::OnAABBOverlap(const NewtonJoint* const contactJoint, float /*timestep*/, int /*threadIndex*/)
|
||||
{
|
||||
RigidBody3D* bodyA = static_cast<RigidBody3D*>(NewtonBodyGetUserData(NewtonJointGetBody0(contactJoint)));
|
||||
|
|
|
|||
|
|
@ -4,6 +4,7 @@
|
|||
|
||||
#include <Nazara/Physics3D/Physics3D.hpp>
|
||||
#include <Nazara/Core/Core.hpp>
|
||||
#include <Nazara/Core/ECS.hpp>
|
||||
#include <Nazara/Core/Error.hpp>
|
||||
#include <Nazara/Core/Log.hpp>
|
||||
#include <Nazara/Physics3D/Config.hpp>
|
||||
|
|
@ -16,6 +17,7 @@ namespace Nz
|
|||
Physics3D::Physics3D(Config /*config*/) :
|
||||
ModuleBase("Physics3D", this)
|
||||
{
|
||||
ECS::RegisterComponents();
|
||||
}
|
||||
|
||||
unsigned int Physics3D::GetMemoryUsed()
|
||||
|
|
|
|||
|
|
@ -61,17 +61,17 @@ namespace Nz
|
|||
SetRotation(object.GetRotation());
|
||||
}
|
||||
|
||||
RigidBody3D::RigidBody3D(RigidBody3D&& object) :
|
||||
RigidBody3D::RigidBody3D(RigidBody3D&& object) noexcept :
|
||||
m_geom(std::move(object.m_geom)),
|
||||
m_matrix(std::move(object.m_matrix)),
|
||||
m_forceAccumulator(std::move(object.m_forceAccumulator)),
|
||||
m_torqueAccumulator(std::move(object.m_torqueAccumulator)),
|
||||
m_body(object.m_body),
|
||||
m_body(std::move(object.m_body)),
|
||||
m_world(object.m_world),
|
||||
m_gravityFactor(object.m_gravityFactor),
|
||||
m_mass(object.m_mass)
|
||||
{
|
||||
object.m_body = nullptr;
|
||||
NewtonBodySetUserData(m_body, this);
|
||||
}
|
||||
|
||||
RigidBody3D::~RigidBody3D()
|
||||
|
|
@ -380,6 +380,24 @@ namespace Nz
|
|||
return operator=(std::move(physObj));
|
||||
}
|
||||
|
||||
RigidBody3D& RigidBody3D::operator=(RigidBody3D&& object) noexcept
|
||||
{
|
||||
if (m_body)
|
||||
NewtonDestroyBody(m_body);
|
||||
|
||||
m_body = std::move(object.m_body);
|
||||
m_forceAccumulator = std::move(object.m_forceAccumulator);
|
||||
m_geom = std::move(object.m_geom);
|
||||
m_gravityFactor = object.m_gravityFactor;
|
||||
m_mass = object.m_mass;
|
||||
m_matrix = std::move(object.m_matrix);
|
||||
m_torqueAccumulator = std::move(object.m_torqueAccumulator);
|
||||
m_world = object.m_world;
|
||||
|
||||
NewtonBodySetUserData(m_body, this);
|
||||
return *this;
|
||||
}
|
||||
|
||||
void RigidBody3D::UpdateBody()
|
||||
{
|
||||
NewtonBodySetMatrix(m_body, m_matrix);
|
||||
|
|
@ -401,25 +419,6 @@ namespace Nz
|
|||
}
|
||||
}
|
||||
|
||||
RigidBody3D& RigidBody3D::operator=(RigidBody3D&& object)
|
||||
{
|
||||
if (m_body)
|
||||
NewtonDestroyBody(m_body);
|
||||
|
||||
m_body = object.m_body;
|
||||
m_forceAccumulator = std::move(object.m_forceAccumulator);
|
||||
m_geom = std::move(object.m_geom);
|
||||
m_gravityFactor = object.m_gravityFactor;
|
||||
m_mass = object.m_mass;
|
||||
m_matrix = std::move(object.m_matrix);
|
||||
m_torqueAccumulator = std::move(object.m_torqueAccumulator);
|
||||
m_world = object.m_world;
|
||||
|
||||
object.m_body = nullptr;
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
void RigidBody3D::ForceAndTorqueCallback(const NewtonBody* body, float timeStep, int threadIndex)
|
||||
{
|
||||
NazaraUnused(timeStep);
|
||||
|
|
|
|||
|
|
@ -0,0 +1,45 @@
|
|||
// Copyright (C) 2021 Jérôme Leclercq
|
||||
// This file is part of the "Nazara Engine - Utility module"
|
||||
// For conditions of distribution and use, see copyright notice in Prerequisites.hpp
|
||||
|
||||
#include <Nazara/Physics3D/Systems/Physics3DSystem.hpp>
|
||||
#include <Nazara/Utility/Components/NodeComponent.hpp>
|
||||
#include <Nazara/Physics3D/Debug.hpp>
|
||||
|
||||
namespace Nz
|
||||
{
|
||||
Physics3DSystem::Physics3DSystem(entt::registry& registry)
|
||||
{
|
||||
m_constructConnection = registry.on_construct<RigidBody3DComponent>().connect<OnConstruct>();
|
||||
}
|
||||
|
||||
Physics3DSystem::~Physics3DSystem()
|
||||
{
|
||||
m_constructConnection.release();
|
||||
}
|
||||
|
||||
void Physics3DSystem::Update(entt::registry& registry, float elapsedTime)
|
||||
{
|
||||
m_physWorld.Step(elapsedTime);
|
||||
|
||||
// Replicate rigid body position to their node components
|
||||
auto velView = registry.view<Nz::NodeComponent, const RigidBody3DComponent>();
|
||||
for (auto [entity, nodeComponent, rigidBodyComponent] : velView.each())
|
||||
{
|
||||
nodeComponent.SetPosition(rigidBodyComponent.GetPosition(), CoordSys::Global);
|
||||
nodeComponent.SetRotation(rigidBodyComponent.GetRotation(), CoordSys::Global);
|
||||
}
|
||||
}
|
||||
|
||||
void Physics3DSystem::OnConstruct(entt::registry& registry, entt::entity entity)
|
||||
{
|
||||
// If our entity already has a node component when adding a rigid body, initialize it with
|
||||
Nz::NodeComponent* node = registry.try_get<NodeComponent>(entity);
|
||||
if (node)
|
||||
{
|
||||
RigidBody3DComponent& rigidBody = registry.get<RigidBody3DComponent>(entity);
|
||||
rigidBody.SetPosition(node->GetPosition());
|
||||
rigidBody.SetRotation(node->GetRotation());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,18 @@
|
|||
// Copyright (C) 2021 Jérôme Leclercq
|
||||
// This file is part of the "Nazara Engine - Utility module"
|
||||
// For conditions of distribution and use, see copyright notice in Prerequisites.hpp
|
||||
|
||||
#include <Nazara/Utility/Components/NodeComponent.hpp>
|
||||
#include <Nazara/Core/Error.hpp>
|
||||
#include <Nazara/Utility/Debug.hpp>
|
||||
|
||||
namespace Nz
|
||||
{
|
||||
void NodeComponent::SetParent(entt::registry& registry, entt::entity entity, bool keepDerived)
|
||||
{
|
||||
NodeComponent* nodeComponent = registry.try_get<NodeComponent>(entity);
|
||||
NazaraAssert(nodeComponent, "entity doesn't have a NodeComponent");
|
||||
|
||||
Node::SetParent(nodeComponent, keepDerived);
|
||||
}
|
||||
}
|
||||
|
|
@ -41,6 +41,35 @@ namespace Nz
|
|||
SetParent(node.m_parent, false);
|
||||
}
|
||||
|
||||
Node::Node(Node&& node) noexcept :
|
||||
m_childs(std::move(node.m_childs)),
|
||||
m_initialRotation(node.m_initialRotation),
|
||||
m_rotation(node.m_rotation),
|
||||
m_initialPosition(node.m_initialPosition),
|
||||
m_initialScale(node.m_initialScale),
|
||||
m_position(node.m_position),
|
||||
m_scale(node.m_scale),
|
||||
m_parent(node.m_parent),
|
||||
m_derivedUpdated(false),
|
||||
m_inheritPosition(node.m_inheritPosition),
|
||||
m_inheritRotation(node.m_inheritRotation),
|
||||
m_inheritScale(node.m_inheritScale),
|
||||
m_transformMatrixUpdated(false),
|
||||
OnNodeInvalidation(std::move(node.OnNodeInvalidation)),
|
||||
OnNodeNewParent(std::move(node.OnNodeNewParent)),
|
||||
OnNodeRelease(std::move(node.OnNodeRelease))
|
||||
{
|
||||
if (m_parent)
|
||||
{
|
||||
m_parent->RemoveChild(&node);
|
||||
m_parent->AddChild(this);
|
||||
node.m_parent = nullptr;
|
||||
}
|
||||
|
||||
for (Node* child : m_childs)
|
||||
child->m_parent = this;
|
||||
}
|
||||
|
||||
Node::~Node()
|
||||
{
|
||||
OnNodeRelease(this);
|
||||
|
|
@ -643,6 +672,42 @@ namespace Nz
|
|||
return *this;
|
||||
}
|
||||
|
||||
Node& Node::operator=(Node&& node) noexcept
|
||||
{
|
||||
if (m_parent)
|
||||
SetParent(nullptr);
|
||||
|
||||
m_inheritPosition = node.m_inheritPosition;
|
||||
m_inheritRotation = node.m_inheritRotation;
|
||||
m_inheritScale = node.m_inheritScale;
|
||||
m_initialPosition = node.m_initialPosition;
|
||||
m_initialRotation = node.m_initialRotation;
|
||||
m_initialScale = node.m_initialScale;
|
||||
m_position = node.m_position;
|
||||
m_rotation = node.m_rotation;
|
||||
m_scale = node.m_scale;
|
||||
|
||||
m_childs = std::move(node.m_childs);
|
||||
for (Node* child : m_childs)
|
||||
child->m_parent = this;
|
||||
|
||||
m_parent = node.m_parent;
|
||||
if (m_parent)
|
||||
{
|
||||
m_parent->RemoveChild(&node);
|
||||
m_parent->AddChild(this);
|
||||
node.m_parent = nullptr;
|
||||
}
|
||||
|
||||
OnNodeInvalidation = std::move(node.OnNodeInvalidation);
|
||||
OnNodeNewParent = std::move(node.OnNodeNewParent);
|
||||
OnNodeRelease = std::move(node.OnNodeRelease);
|
||||
|
||||
InvalidateNode();
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
void Node::AddChild(Node* node) const
|
||||
{
|
||||
#ifdef NAZARA_DEBUG
|
||||
|
|
|
|||
|
|
@ -5,6 +5,7 @@
|
|||
#include <Nazara/Utility/Utility.hpp>
|
||||
#include <Nazara/Core/CallOnExit.hpp>
|
||||
#include <Nazara/Core/Core.hpp>
|
||||
#include <Nazara/Core/ECS.hpp>
|
||||
#include <Nazara/Core/Error.hpp>
|
||||
#include <Nazara/Utility/Animation.hpp>
|
||||
#include <Nazara/Utility/Buffer.hpp>
|
||||
|
|
@ -39,6 +40,8 @@ namespace Nz
|
|||
Utility::Utility(Config /*config*/) :
|
||||
ModuleBase("Utility", this)
|
||||
{
|
||||
ECS::RegisterComponents();
|
||||
|
||||
if (!Buffer::Initialize())
|
||||
throw std::runtime_error("failed to initialize buffers");
|
||||
|
||||
|
|
|
|||
|
|
@ -54,6 +54,7 @@ namespace Nz
|
|||
deviceInfo.name = physDevice.properties.deviceName;
|
||||
|
||||
deviceInfo.features.anisotropicFiltering = physDevice.features.samplerAnisotropy;
|
||||
deviceInfo.features.nonSolidFaceFilling = physDevice.features.fillModeNonSolid;
|
||||
|
||||
deviceInfo.limits.minUniformBufferOffsetAlignment = physDevice.properties.limits.minUniformBufferOffsetAlignment;
|
||||
|
||||
|
|
@ -274,7 +275,7 @@ namespace Nz
|
|||
|
||||
VkValidationFeaturesEXT features = { VK_STRUCTURE_TYPE_VALIDATION_FEATURES_EXT };
|
||||
|
||||
std::vector<VkValidationFeatureEnableEXT> enabledFeatures = {
|
||||
std::array<VkValidationFeatureEnableEXT, 1> enabledFeatures = {
|
||||
//VK_VALIDATION_FEATURE_ENABLE_GPU_ASSISTED_EXT,
|
||||
//VK_VALIDATION_FEATURE_ENABLE_GPU_ASSISTED_RESERVE_BINDING_SLOT_EXT,
|
||||
VK_VALIDATION_FEATURE_ENABLE_SYNCHRONIZATION_VALIDATION_EXT
|
||||
|
|
|
|||
|
|
@ -14,7 +14,8 @@ local modules = {
|
|||
if is_plat("linux") then
|
||||
add_syslinks("dl", "pthread")
|
||||
end
|
||||
end
|
||||
end,
|
||||
Packages = {"entt"}
|
||||
},
|
||||
Graphics = {
|
||||
Deps = {"NazaraRenderer"},
|
||||
|
|
@ -54,7 +55,7 @@ local modules = {
|
|||
},
|
||||
Physics3D = {
|
||||
Deps = {"NazaraUtility"},
|
||||
Packages = {"newtondynamics"}
|
||||
Packages = {"entt", "newtondynamics"}
|
||||
},
|
||||
Platform = {
|
||||
Deps = {"NazaraUtility"},
|
||||
|
|
|
|||
|
|
@ -11,9 +11,11 @@ on_run(function ()
|
|||
local paths = {}
|
||||
|
||||
local excludedFiles = {
|
||||
["Components.hpp"] = true,
|
||||
["ConfigCheck.hpp"] = true,
|
||||
["Debug.hpp"] = true,
|
||||
["DebugOff.hpp"] = true,
|
||||
["Systems.hpp"] = true,
|
||||
["ThreadSafety.hpp"] = true,
|
||||
["ThreadSafetyOff.hpp"] = true
|
||||
}
|
||||
|
|
@ -37,42 +39,80 @@ on_run(function ()
|
|||
|
||||
config:close()
|
||||
|
||||
table.insert(paths, {
|
||||
Excludes = excludedFiles,
|
||||
paths[moduleName] = {
|
||||
Excludes = table.copy(excludedFiles),
|
||||
Header = head,
|
||||
HeaderGuard = "NAZARA_GLOBAL_" .. moduleName:upper() .. "_HPP",
|
||||
Name = "Nazara" .. moduleName,
|
||||
SearchDir = modulePath,
|
||||
Target = modulePath .. ".hpp"
|
||||
})
|
||||
}
|
||||
|
||||
-- Handle components and systems
|
||||
if (os.isdir(modulePath .. "/Components")) then
|
||||
paths[moduleName .. "_Components"] = {
|
||||
Excludes = table.copy(excludedFiles),
|
||||
Header = head,
|
||||
HeaderGuard = "NAZARA_GLOBAL_" .. moduleName:upper() .. "_COMPONENTS_HPP",
|
||||
Name = "Nazara" .. moduleName .. " components",
|
||||
SearchDir = modulePath .. "/Components",
|
||||
Target = modulePath .. "/Components.hpp"
|
||||
}
|
||||
end
|
||||
|
||||
if (os.isdir(modulePath .. "/Systems")) then
|
||||
paths[moduleName .. "_Systems"] = {
|
||||
Excludes = table.copy(excludedFiles),
|
||||
Header = head,
|
||||
HeaderGuard = "NAZARA_GLOBAL_" .. moduleName:upper() .. "_SYSTEMS_HPP",
|
||||
Name = "Nazara" .. moduleName .. " systems",
|
||||
SearchDir = modulePath .. "/Systems",
|
||||
Target = modulePath .. "/Systems.hpp"
|
||||
}
|
||||
end
|
||||
end
|
||||
|
||||
table.insert(paths, {
|
||||
paths["Core"].Excludes["ECS.hpp"] = true
|
||||
paths["OpenGLRenderer"].Excludes["Wrapper.hpp"] = true
|
||||
paths["Shader"].Excludes["ShaderLangTokenList.hpp"] = true
|
||||
paths["VulkanRenderer"].Excludes["Wrapper.hpp"] = true
|
||||
|
||||
-- OpenGL renderer wrapper
|
||||
paths["OpenGLWrapper"] = {
|
||||
Excludes = {
|
||||
["DeviceFunctions.hpp"] = true,
|
||||
["GlobalFunctions.hpp"] = true,
|
||||
["InstanceFunctions.hpp"] = true,
|
||||
},
|
||||
Header = paths["OpenGLRenderer"].Header,
|
||||
HeaderGuard = "NAZARA_GLOBAL_OPENGLRENDERER_WRAPPER_HPP",
|
||||
Name = "OpenGL wrapper",
|
||||
SearchDir = "include/Nazara/OpenGLRenderer/Wrapper",
|
||||
Target = "include/Nazara/OpenGLRenderer/Wrapper.hpp"
|
||||
})
|
||||
}
|
||||
|
||||
table.insert(paths, {
|
||||
-- Vulkan renderer wrapper
|
||||
paths["VulkanWrapper"] = {
|
||||
Excludes = {
|
||||
["DeviceFunctions.hpp"] = true,
|
||||
["GlobalFunctions.hpp"] = true,
|
||||
["InstanceFunctions.hpp"] = true,
|
||||
},
|
||||
Header = paths["VulkanRenderer"].Header,
|
||||
HeaderGuard = "NAZARA_GLOBAL_VULKANRENDERER_WRAPPER_HPP",
|
||||
Name = "Vulkan wrapper",
|
||||
SearchDir = "include/Nazara/VulkanRenderer/Wrapper",
|
||||
Target = "include/Nazara/VulkanRenderer/Wrapper.hpp"
|
||||
})
|
||||
}
|
||||
|
||||
for k,v in ipairs(paths) do
|
||||
for _,v in pairs(paths) do
|
||||
print(v.Name)
|
||||
local files = os.files(v.SearchDir .. "/*.hpp")
|
||||
if (#files == 0) then
|
||||
print("Skipped (no file matched)")
|
||||
goto continue
|
||||
end
|
||||
|
||||
local header, err = io.open(v.Target, "w+")
|
||||
if (not header) then
|
||||
error("Failed to create header file (" .. v.Target .. "): " .. err)
|
||||
|
|
@ -87,7 +127,6 @@ on_run(function ()
|
|||
header:write("#ifndef " .. v.HeaderGuard .. "\n")
|
||||
header:write("#define " .. v.HeaderGuard .. "\n\n")
|
||||
|
||||
local files = os.files(v.SearchDir .. "/*.hpp")
|
||||
local count = 0
|
||||
for _, filePath in pairs(files) do
|
||||
local pathParts = path.split(filePath)
|
||||
|
|
@ -96,7 +135,6 @@ on_run(function ()
|
|||
end
|
||||
|
||||
local include = table.concat(pathParts, "/")
|
||||
print(include)
|
||||
local fileName = path.filename(filePath)
|
||||
if (not v.Excludes[fileName]) then
|
||||
header:write("#include <" .. include .. ">\n")
|
||||
|
|
@ -108,5 +146,6 @@ on_run(function ()
|
|||
header:close()
|
||||
|
||||
print(string.format("-#include count: %d", count))
|
||||
::continue::
|
||||
end
|
||||
end)
|
||||
|
|
|
|||
Loading…
Reference in New Issue