Merge branch 'nazara-next' of https://github.com/DigitalPulseSoftware/NazaraEngine into nazara-next

This commit is contained in:
Jérôme Leclercq
2021-06-20 14:13:21 +02:00
57 changed files with 1382 additions and 51 deletions

11
src/Nazara/Core/ECS.cpp Normal file
View File

@@ -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;
}

View File

@@ -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
{
}

View File

@@ -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)

View File

@@ -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());

View File

@@ -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);

View File

@@ -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;
}

View File

@@ -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);

View File

@@ -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
{
}

View File

@@ -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)));

View File

@@ -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()

View File

@@ -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);

View File

@@ -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());
}
}
}

View File

@@ -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);
}
}

View File

@@ -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

View File

@@ -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");

View File

@@ -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