Move SDK include and source to base

This commit is contained in:
Lynix
2020-02-24 18:23:30 +01:00
parent f0d11aea72
commit b6b3ac9f31
149 changed files with 34 additions and 33 deletions

View File

@@ -0,0 +1,120 @@
// Copyright (C) 2017 Jérôme Leclercq
// This file is part of the "Nazara Development Kit"
// For conditions of distribution and use, see copyright notice in Prerequisites.hpp
#pragma once
#ifndef NDK_SERVER
#ifndef NDK_COMPONENTS_CAMERACOMPONENT_HPP
#define NDK_COMPONENTS_CAMERACOMPONENT_HPP
#include <Nazara/Math/Frustum.hpp>
#include <Nazara/Math/Matrix4.hpp>
#include <Nazara/Math/Vector3.hpp>
#include <Nazara/Graphics/AbstractViewer.hpp>
#include <Nazara/Renderer/RenderTarget.hpp>
#include <Nazara/Utility/Node.hpp>
#include <NazaraSDK/Component.hpp>
namespace Ndk
{
class CameraComponent;
using CameraComponentHandle = Nz::ObjectHandle<CameraComponent>;
class NDK_API CameraComponent : public Component<CameraComponent>, public Nz::AbstractViewer
{
public:
inline CameraComponent();
inline CameraComponent(const CameraComponent& camera);
~CameraComponent() = default;
void ApplyView() const override;
inline void EnsureFrustumUpdate() const;
inline void EnsureProjectionMatrixUpdate() const;
inline void EnsureViewMatrixUpdate() const;
inline void EnsureViewportUpdate() const;
float GetAspectRatio() const override;
Nz::Vector3f GetEyePosition() const override;
Nz::Vector3f GetForward() const override;
inline float GetFOV() const;
const Nz::Frustumf& GetFrustum() const override;
inline unsigned int GetLayer() const;
const Nz::Matrix4f& GetProjectionMatrix() const override;
inline const Nz::Vector3f& GetProjectionScale() const;
Nz::ProjectionType GetProjectionType() const override;
inline const Nz::Vector2f& GetSize() const;
const Nz::RenderTarget* GetTarget() const override;
inline const Nz::Rectf& GetTargetRegion() const;
const Nz::Matrix4f& GetViewMatrix() const override;
const Nz::Recti& GetViewport() const override;
float GetZFar() const override;
float GetZNear() const override;
inline void SetFOV(float fov);
void SetLayer(unsigned int layer);
inline void SetProjectionScale(const Nz::Vector3f& scale);
inline void SetProjectionType(Nz::ProjectionType projection);
inline void SetSize(const Nz::Vector2f& size);
inline void SetSize(float width, float height);
inline void SetTarget(const Nz::RenderTarget* renderTarget);
inline void SetTargetRegion(const Nz::Rectf& region);
inline void SetViewport(const Nz::Recti& viewport);
inline void SetZFar(float zFar);
inline void SetZNear(float zNear);
inline bool UpdateVisibility(std::size_t visibilityHash);
static ComponentIndex componentIndex;
private:
inline void InvalidateFrustum() const;
inline void InvalidateProjectionMatrix() const;
inline void InvalidateViewMatrix() const;
inline void InvalidateViewport() const;
void OnAttached() override;
void OnComponentAttached(BaseComponent& component) override;
void OnComponentDetached(BaseComponent& component) override;
void OnDetached() override;
void OnNodeInvalidated(const Nz::Node* node);
void OnRenderTargetRelease(const Nz::RenderTarget* renderTarget);
void OnRenderTargetSizeChange(const Nz::RenderTarget* renderTarget);
void UpdateFrustum() const;
void UpdateProjectionMatrix() const;
void UpdateViewMatrix() const;
void UpdateViewport() const;
NazaraSlot(Nz::Node, OnNodeInvalidation, m_nodeInvalidationSlot);
NazaraSlot(Nz::RenderTarget, OnRenderTargetRelease, m_targetReleaseSlot);
NazaraSlot(Nz::RenderTarget, OnRenderTargetSizeChange, m_targetResizeSlot);
std::size_t m_visibilityHash;
Nz::ProjectionType m_projectionType;
mutable Nz::Frustumf m_frustum;
mutable Nz::Matrix4f m_projectionMatrix;
mutable Nz::Matrix4f m_viewMatrix;
Nz::Rectf m_targetRegion;
mutable Nz::Recti m_viewport;
const Nz::RenderTarget* m_target;
Nz::Vector2f m_size;
Nz::Vector3f m_projectionScale;
mutable bool m_frustumUpdated;
mutable bool m_projectionMatrixUpdated;
mutable bool m_viewMatrixUpdated;
mutable bool m_viewportUpdated;
mutable float m_aspectRatio;
float m_fov;
float m_zFar;
float m_zNear;
unsigned int m_layer;
};
}
#include <NazaraSDK/Components/CameraComponent.inl>
#endif // NDK_COMPONENTS_CAMERACOMPONENT_HPP
#endif // NDK_SERVER

View File

@@ -0,0 +1,353 @@
// Copyright (C) 2017 Jérôme Leclercq
// This file is part of the "Nazara Development Kit"
// For conditions of distribution and use, see copyright notice in Prerequisites.hpp
#include <Nazara/Core/Error.hpp>
#include <Nazara/Math/Algorithm.hpp>
namespace Ndk
{
/*!
* \brief Constructs an CameraComponent object by default
*/
inline CameraComponent::CameraComponent() :
m_visibilityHash(0U),
m_projectionType(Nz::ProjectionType_Perspective),
m_targetRegion(0.f, 0.f, 1.f, 1.f),
m_target(nullptr),
m_size(0.f),
m_projectionScale(1.f, 1.f, 1.f),
m_frustumUpdated(false),
m_projectionMatrixUpdated(false),
m_viewMatrixUpdated(false),
m_viewportUpdated(false),
m_aspectRatio(0.f),
m_fov(70.f),
m_zFar(100.f),
m_zNear(1.f),
m_layer(0)
{
}
/*!
* \brief Constructs a CameraComponent object by copy semantic
*
* \param camera CameraComponent to copy
*/
inline CameraComponent::CameraComponent(const CameraComponent& camera) :
Component(camera),
AbstractViewer(camera),
m_visibilityHash(camera.m_visibilityHash),
m_projectionType(camera.m_projectionType),
m_targetRegion(camera.m_targetRegion),
m_target(nullptr),
m_size(camera.m_size),
m_projectionScale(camera.m_projectionScale),
m_frustumUpdated(false),
m_projectionMatrixUpdated(false),
m_viewMatrixUpdated(false),
m_viewportUpdated(false),
m_aspectRatio(camera.m_aspectRatio),
m_fov(camera.m_fov),
m_zFar(camera.m_zFar),
m_zNear(camera.m_zNear),
m_layer(camera.m_layer)
{
SetTarget(camera.m_target);
}
/*!
* \brief Ensures the frustum is up to date
*/
inline void CameraComponent::EnsureFrustumUpdate() const
{
if (!m_frustumUpdated)
UpdateFrustum();
}
/*!
* \brief Ensures the projection matrix is up to date
*/
inline void CameraComponent::EnsureProjectionMatrixUpdate() const
{
if (!m_projectionMatrixUpdated)
UpdateProjectionMatrix();
}
/*!
* \brief Ensures the view matrix is up to date
*/
inline void CameraComponent::EnsureViewMatrixUpdate() const
{
if (!m_viewMatrixUpdated)
UpdateViewMatrix();
}
/*!
* \brief Ensures the view port is up to date
*/
inline void CameraComponent::EnsureViewportUpdate() const
{
if (!m_viewportUpdated)
UpdateViewport();
}
/*!
* \brief Gets the field of view of the camera
* \return Field of view of the camera
*/
inline float CameraComponent::GetFOV() const
{
return m_fov;
}
/*!
* \brief Gets the layer of the camera
* \return Layer of the camera
*/
inline unsigned int CameraComponent::GetLayer() const
{
return m_layer;
}
/*!
* \brief Gets the projection scale of the camera
* \return Projection scale
*/
const Nz::Vector3f& CameraComponent::GetProjectionScale() const
{
return m_projectionScale;
}
/*!
* \brief Gets the size of the camera
* \return Size of the camera
*/
inline const Nz::Vector2f & CameraComponent::GetSize() const
{
return m_size;
}
/*!
* \brief Gets the target region of the camera
* \return A constant reference to the target region of the camera
*/
inline const Nz::Rectf& CameraComponent::GetTargetRegion() const
{
return m_targetRegion;
}
/*!
* \brief Sets the field of view of the camera
*
* \param fov Field of view of the camera
*
* \remark Produces a NazaraAssert if angle is zero
*/
inline void CameraComponent::SetFOV(float fov)
{
NazaraAssert(!Nz::NumberEquals(fov, 0.f), "FOV must be different from zero");
m_fov = fov;
InvalidateProjectionMatrix();
}
/*!
* \brief Sets the camera projection scale
*
* \param scale New projection scale
*/
inline void CameraComponent::SetProjectionScale(const Nz::Vector3f& scale)
{
m_projectionScale = scale;
InvalidateProjectionMatrix();
}
/*!
* \brief Sets the projection type of the camera
*
* \param projectionType Projection type of the camera
*/
inline void CameraComponent::SetProjectionType(Nz::ProjectionType projectionType)
{
m_projectionType = projectionType;
InvalidateProjectionMatrix();
}
/*!
* \brief Sets the size of the camera
*
* \param size Size of the camera
*/
inline void CameraComponent::SetSize(const Nz::Vector2f& size)
{
m_size = size;
InvalidateProjectionMatrix();
}
/*!
* \brief Sets the size of the camera
*
* \param width Size in X of the camera
* \param height Size in Y of the camera
*/
inline void CameraComponent::SetSize(float width, float height)
{
SetSize({width, height});
}
/*!
* \brief Sets the target of the camera
*
* \param renderTarget A constant reference to the render target of the camera
*/
inline void CameraComponent::SetTarget(const Nz::RenderTarget* renderTarget)
{
m_target = renderTarget;
if (m_target)
{
m_targetResizeSlot.Connect(m_target->OnRenderTargetSizeChange, this, &CameraComponent::OnRenderTargetSizeChange);
m_targetReleaseSlot.Connect(m_target->OnRenderTargetRelease, this, &CameraComponent::OnRenderTargetRelease);
}
else
{
m_targetResizeSlot.Disconnect();
m_targetReleaseSlot.Disconnect();
}
}
/*!
* \brief Sets the target region of the camera
*
* \param region A constant reference to the target region of the camera
*/
inline void CameraComponent::SetTargetRegion(const Nz::Rectf& region)
{
m_targetRegion = region;
InvalidateViewport();
}
/*!
* \brief Sets the view port of the camera
*
* \param viewport A constant reference to the view port of the camera
*
* \remark Produces a NazaraAssert if the camera has no target
*/
inline void CameraComponent::SetViewport(const Nz::Recti& viewport)
{
NazaraAssert(m_target, "Component has no render target");
// We compute the region necessary to make this view port with the actual size of the target
Nz::Vector2f invSize = 1.f / Nz::Vector2f(m_target->GetSize());
SetTargetRegion(Nz::Rectf(invSize.x * viewport.x, invSize.y * viewport.y, invSize.x * viewport.width, invSize.y * viewport.height));
}
/*!
* \brief Sets the Z far distance of the camera
*
* \param zFar Z far distance of the camera
*/
inline void CameraComponent::SetZFar(float zFar)
{
m_zFar = zFar;
InvalidateProjectionMatrix();
}
/*!
* \brief Sets the Z near distance of the camera
*
* \param zNear Z near distance of the camera
*
* \remark Produces a NazaraAssert if zNear is zero
*/
inline void CameraComponent::SetZNear(float zNear)
{
NazaraAssert(!Nz::NumberEquals(zNear, 0.f), "zNear cannot be zero");
m_zNear = zNear;
InvalidateProjectionMatrix();
}
/*!
* \brief Update the camera component visibility hash
*
* This is used with CullingList (which produce a visibility hash)
*
* \param visibilityHash New visibility hash
*
* \return True if the visibility hash is not the same as before
*/
inline bool CameraComponent::UpdateVisibility(std::size_t visibilityHash)
{
if (m_visibilityHash != visibilityHash)
{
m_visibilityHash = visibilityHash;
return true;
}
return false;
}
/*!
* \brief Invalidates the frustum
*/
inline void CameraComponent::InvalidateFrustum() const
{
m_frustumUpdated = false;
}
/*!
* \brief Invalidates the projection matrix
*/
inline void CameraComponent::InvalidateProjectionMatrix() const
{
m_frustumUpdated = false;
m_projectionMatrixUpdated = false;
}
/*!
* \brief Invalidates the view matrix
*/
inline void CameraComponent::InvalidateViewMatrix() const
{
m_frustumUpdated = false;
m_viewMatrixUpdated = false;
}
/*!
* \brief Invalidates the view port
*/
inline void CameraComponent::InvalidateViewport() const
{
m_frustumUpdated = false;
m_projectionMatrixUpdated = false;
m_viewportUpdated = false;
}
}

View File

@@ -0,0 +1,66 @@
// Copyright (C) 2017 Jérôme Leclercq
// This file is part of the "Nazara Development Kit"
// For conditions of distribution and use, see copyright notice in Prerequisites.hpp
#pragma once
#ifndef NDK_COMPONENTS_COLLISIONCOMPONENT2D_HPP
#define NDK_COMPONENTS_COLLISIONCOMPONENT2D_HPP
#include <Nazara/Physics2D/Collider2D.hpp>
#include <Nazara/Physics2D/RigidBody2D.hpp>
#include <NazaraSDK/Component.hpp>
#include <memory>
namespace Ndk
{
class CollisionComponent2D;
using CollisionComponent2DHandle = Nz::ObjectHandle<CollisionComponent2D>;
class NDK_API CollisionComponent2D : public Component<CollisionComponent2D>
{
friend class ConstraintComponent2D;
friend class PhysicsComponent2D;
friend class PhysicsSystem2D;
public:
CollisionComponent2D(Nz::Collider2DRef geom = Nz::Collider2DRef());
CollisionComponent2D(const CollisionComponent2D& collision);
~CollisionComponent2D() = default;
Nz::Rectf GetAABB() const;
const Nz::Collider2DRef& GetGeom() const;
const Nz::Vector2f& GetGeomOffset() const;
void Recenter(const Nz::Vector2f& origin);
void SetGeom(Nz::Collider2DRef geom);
void SetGeomOffset(const Nz::Vector2f& geomOffset);
CollisionComponent2D& operator=(Nz::Collider2DRef geom);
CollisionComponent2D& operator=(CollisionComponent2D&& collision) = default;
static ComponentIndex componentIndex;
private:
void InitializeStaticBody();
Nz::RigidBody2D* GetRigidBody();
const Nz::RigidBody2D* GetRigidBody() const;
Nz::RigidBody2D* GetStaticBody();
const Nz::RigidBody2D* GetStaticBody() const;
void OnAttached() override;
void OnComponentAttached(BaseComponent& component) override;
void OnComponentDetached(BaseComponent& component) override;
void OnDetached() override;
std::unique_ptr<Nz::RigidBody2D> m_staticBody;
Nz::Collider2DRef m_geom;
bool m_bodyUpdated;
};
}
#include <NazaraSDK/Components/CollisionComponent2D.inl>
#endif // NDK_COMPONENTS_COLLISIONCOMPONENT2D_HPP

View File

@@ -0,0 +1,64 @@
// Copyright (C) 2017 Jérôme Leclercq
// This file is part of the "Nazara Development Kit"
// For conditions of distribution and use, see copyright notice in Prerequisites.hpp
namespace Ndk
{
/*!
* \brief Constructs a CollisionComponent2D object with a geometry
*
* \param geom Reference to a geometry symbolizing the entity
*/
inline CollisionComponent2D::CollisionComponent2D(Nz::Collider2DRef geom) :
m_geom(std::move(geom)),
m_bodyUpdated(false)
{
}
/*!
* \brief Constructs a CollisionComponent2D object by copy semantic
*
* \param collision CollisionComponent2D to copy
*/
inline CollisionComponent2D::CollisionComponent2D(const CollisionComponent2D& collision) :
m_geom(collision.m_geom),
m_bodyUpdated(false)
{
}
/*!
* \brief Gets the geometry representing the entity
* \return A constant reference to the physics geometry
*/
inline const Nz::Collider2DRef& CollisionComponent2D::GetGeom() const
{
return m_geom;
}
/*!
* \brief Assigns the geometry to this component
* \return A reference to this
*
* \param geom Reference to a geometry symbolizing the entity
*/
inline CollisionComponent2D& CollisionComponent2D::operator=(Nz::Collider2DRef geom)
{
SetGeom(geom);
return *this;
}
inline Nz::RigidBody2D* CollisionComponent2D::GetStaticBody()
{
return m_staticBody.get();
}
inline const Nz::RigidBody2D* CollisionComponent2D::GetStaticBody() const
{
return m_staticBody.get();
}
}

View File

@@ -0,0 +1,58 @@
// Copyright (C) 2017 Jérôme Leclercq
// This file is part of the "Nazara Development Kit"
// For conditions of distribution and use, see copyright notice in Prerequisites.hpp
#pragma once
#ifndef NDK_COMPONENTS_COLLISIONCOMPONENT3D_HPP
#define NDK_COMPONENTS_COLLISIONCOMPONENT3D_HPP
#include <Nazara/Physics3D/Collider3D.hpp>
#include <Nazara/Physics3D/RigidBody3D.hpp>
#include <NazaraSDK/Component.hpp>
#include <memory>
namespace Ndk
{
class CollisionComponent3D;
using CollisionComponent3DHandle = Nz::ObjectHandle<CollisionComponent3D>;
class NDK_API CollisionComponent3D : public Component<CollisionComponent3D>
{
friend class PhysicsSystem3D;
public:
CollisionComponent3D(Nz::Collider3DRef geom = Nz::Collider3DRef());
CollisionComponent3D(const CollisionComponent3D& collision);
~CollisionComponent3D() = default;
const Nz::Collider3DRef& GetGeom() const;
void SetGeom(Nz::Collider3DRef geom);
CollisionComponent3D& operator=(Nz::Collider3DRef geom);
CollisionComponent3D& operator=(CollisionComponent3D&& collision) = default;
static ComponentIndex componentIndex;
private:
void InitializeStaticBody();
Nz::RigidBody3D* GetStaticBody();
void OnAttached() override;
void OnComponentAttached(BaseComponent& component) override;
void OnComponentDetached(BaseComponent& component) override;
void OnDetached() override;
void OnEntityDisabled() override;
void OnEntityEnabled() override;
std::unique_ptr<Nz::RigidBody3D> m_staticBody;
Nz::Collider3DRef m_geom;
bool m_bodyUpdated;
};
}
#include <NazaraSDK/Components/CollisionComponent3D.inl>
#endif // NDK_COMPONENTS_COLLISIONCOMPONENT3D_HPP

View File

@@ -0,0 +1,64 @@
// Copyright (C) 2017 Jérôme Leclercq
// This file is part of the "Nazara Development Kit"
// For conditions of distribution and use, see copyright notice in Prerequisites.hpp
namespace Ndk
{
/*!
* \brief Constructs a CollisionComponent3D object with a geometry
*
* \param geom Reference to a geometry symbolizing the entity
*/
inline CollisionComponent3D::CollisionComponent3D(Nz::Collider3DRef geom) :
m_geom(std::move(geom)),
m_bodyUpdated(false)
{
}
/*!
* \brief Constructs a CollisionComponent3D object by copy semantic
*
* \param collision CollisionComponent3D to copy
*/
inline CollisionComponent3D::CollisionComponent3D(const CollisionComponent3D& collision) :
m_geom(collision.m_geom),
m_bodyUpdated(false)
{
}
/*!
* \brief Gets the geometry representing the entity
* \return A constant reference to the physics geometry
*/
inline const Nz::Collider3DRef& CollisionComponent3D::GetGeom() const
{
return m_geom;
}
/*!
* \brief Assigns the geometry to this component
* \return A reference to this
*
* \param geom Reference to a geometry symbolizing the entity
*/
inline CollisionComponent3D& CollisionComponent3D::operator=(Nz::Collider3DRef geom)
{
SetGeom(geom);
return *this;
}
/*!
* \brief Gets the static body used by the entity
* \return A pointer to the entity
*/
inline Nz::RigidBody3D* CollisionComponent3D::GetStaticBody()
{
return m_staticBody.get();
}
}

View File

@@ -0,0 +1,51 @@
// Copyright (C) 2019 Jérôme Leclercq
// This file is part of the "Nazara Development Kit"
// For conditions of distribution and use, see copyright notice in Prerequisites.hpp
#pragma once
#ifndef NDK_COMPONENTS_CONSTRAINTCOMPONENT2D_HPP
#define NDK_COMPONENTS_CONSTRAINTCOMPONENT2D_HPP
#include <Nazara/Physics2D/Constraint2D.hpp>
#include <Nazara/Math/Vector3.hpp>
#include <NazaraSDK/Component.hpp>
#include <NazaraSDK/Entity.hpp>
#include <memory>
#include <vector>
namespace Ndk
{
class ConstraintComponent2D;
using ConstraintComponent2DHandle = Nz::ObjectHandle<ConstraintComponent2D>;
class NDK_API ConstraintComponent2D : public Component<ConstraintComponent2D>
{
public:
ConstraintComponent2D() = default;
ConstraintComponent2D(const ConstraintComponent2D& joint);
ConstraintComponent2D(ConstraintComponent2D&& joint) = default;
template<typename T, typename... Args> T* CreateConstraint(const Ndk::EntityHandle& first, const Ndk::EntityHandle& second, Args&&... args);
bool RemoveConstraint(Nz::Constraint2D* constraint);
static ComponentIndex componentIndex;
private:
struct ConstraintData
{
std::unique_ptr<Nz::Constraint2D> constraint;
NazaraSlot(Ndk::Entity, OnEntityDestruction, onBodyADestruction);
NazaraSlot(Ndk::Entity, OnEntityDestruction, onBodyBDestruction);
};
std::vector<ConstraintData> m_constraints;
};
}
#include <NazaraSDK/Components/ConstraintComponent2D.inl>
#endif// NDK_COMPONENTS_CONSTRAINTCOMPONENT2D_HPP

View File

@@ -0,0 +1,46 @@
// Copyright (C) 2019 Jérôme Leclercq
// This file is part of the "Nazara Development Kit"
// For conditions of distribution and use, see copyright notice in Prerequisites.hpp
#include <NazaraSDK/Components/ConstraintComponent2D.hpp>
#include <NazaraSDK/Components/PhysicsComponent2D.hpp>
#include <NazaraSDK/Components/CollisionComponent2D.hpp>
namespace Ndk
{
template<typename T, typename ...Args>
T* ConstraintComponent2D::CreateConstraint(const Ndk::EntityHandle& first, const Ndk::EntityHandle& second, Args&& ...args)
{
auto FetchBody = [](const Ndk::EntityHandle& entity) -> Nz::RigidBody2D*
{
if (entity->HasComponent<Ndk::PhysicsComponent2D>())
return entity->GetComponent<Ndk::PhysicsComponent2D>().GetRigidBody();
else if (entity->HasComponent<Ndk::CollisionComponent2D>())
return entity->GetComponent<Ndk::CollisionComponent2D>().GetStaticBody();
return nullptr;
};
Nz::RigidBody2D* firstBody = FetchBody(first);
NazaraAssert(firstBody, "First entity has no CollisionComponent2D nor PhysicsComponent2D component");
Nz::RigidBody2D* secondBody = FetchBody(second);
NazaraAssert(secondBody, "Second entity has no CollisionComponent2D nor PhysicsComponent2D component");
m_constraints.emplace_back();
auto& constraintData = m_constraints.back();
constraintData.constraint = std::make_unique<T>(*firstBody, *secondBody, std::forward<Args>(args)...);
constraintData.onBodyADestruction.Connect(first->OnEntityDestruction, [this, constraint = constraintData.constraint.get()](const Ndk::Entity* /*entity*/)
{
RemoveConstraint(constraint);
});
constraintData.onBodyBDestruction.Connect(second->OnEntityDestruction, [this, constraint = constraintData.constraint.get()](const Ndk::Entity* /*entity*/)
{
RemoveConstraint(constraint);
});
return static_cast<T*>(constraintData.constraint.get());
}
}

View File

@@ -0,0 +1,91 @@
// Copyright (C) 2017 Jérôme Leclercq
// This file is part of the "Nazara Development Kit"
// For conditions of distribution and use, see copyright notice in Prerequisites.hpp
#pragma once
#ifndef NDK_SERVER
#ifndef NDK_COMPONENTS_DEBUGCOMPONENT_HPP
#define NDK_COMPONENTS_DEBUGCOMPONENT_HPP
#include <Nazara/Core/Flags.hpp>
#include <Nazara/Graphics/InstancedRenderable.hpp>
#include <NazaraSDK/Component.hpp>
namespace Ndk
{
enum class DebugDraw
{
Collider2D,
Collider3D,
GraphicsAABB,
GraphicsOBB,
Max = GraphicsOBB
};
}
namespace Nz
{
template<>
struct EnumAsFlags<Ndk::DebugDraw>
{
static constexpr Ndk::DebugDraw max = Ndk::DebugDraw::GraphicsOBB;
};
}
namespace Ndk
{
using DebugDrawFlags = Nz::Flags<DebugDraw>;
constexpr DebugDrawFlags DebugDraw_None = 0;
class DebugComponent;
class GraphicsComponent;
using DebugComponentHandle = Nz::ObjectHandle<DebugComponent>;
class NDK_API DebugComponent : public Component<DebugComponent>
{
friend class DebugSystem;
public:
inline DebugComponent(DebugDrawFlags flags = DebugDraw_None);
inline DebugComponent(const DebugComponent& debug);
~DebugComponent() = default;
inline void Disable(DebugDrawFlags flags);
inline void Enable(DebugDrawFlags flags);
inline DebugDrawFlags GetFlags() const;
inline bool IsEnabled(DebugDrawFlags flags) const;
inline DebugComponent& operator=(const DebugComponent& debug);
static ComponentIndex componentIndex;
private:
void DetachDebugRenderables(GraphicsComponent& gfxComponent);
inline const Nz::InstancedRenderableRef& GetDebugRenderable(DebugDraw option) const;
inline DebugDrawFlags GetEnabledFlags() const;
void OnComponentDetached(BaseComponent& component) override;
void OnDetached() override;
inline void UpdateDebugRenderable(DebugDraw option, Nz::InstancedRenderableRef renderable);
inline void UpdateEnabledFlags(DebugDrawFlags flags);
static constexpr std::size_t DebugModeCount = static_cast<std::size_t>(DebugDraw::Max) + 1;
std::array<Nz::InstancedRenderableRef, DebugModeCount> m_debugRenderables;
DebugDrawFlags m_enabledFlags;
DebugDrawFlags m_flags;
};
}
#include <NazaraSDK/Components/DebugComponent.inl>
#endif // NDK_COMPONENTS_DEBUGCOMPONENT_HPP
#endif // NDK_SERVER

View File

@@ -0,0 +1,74 @@
// Copyright (C) 2017 Jérôme Leclercq
// This file is part of the "Nazara Development Kit"
// For conditions of distribution and use, see copyright notice in Prerequisites.hpp
#include <NazaraSDK/Components/DebugComponent.hpp>
namespace Ndk
{
inline DebugComponent::DebugComponent(DebugDrawFlags flags) :
m_flags(flags)
{
}
inline DebugComponent::DebugComponent(const DebugComponent& debug) :
m_flags(debug.m_flags)
{
}
inline void DebugComponent::Disable(DebugDrawFlags flags)
{
m_flags &= ~flags;
if (m_entity)
m_entity->Invalidate();
}
inline void DebugComponent::Enable(DebugDrawFlags flags)
{
m_flags |= flags;
if (m_entity)
m_entity->Invalidate();
}
inline DebugDrawFlags DebugComponent::GetFlags() const
{
return m_flags;
}
inline bool DebugComponent::IsEnabled(DebugDrawFlags flags) const
{
return (m_flags & flags) == flags;
}
inline DebugComponent& DebugComponent::operator=(const DebugComponent& debug)
{
m_flags = debug.m_flags;
if (m_entity)
m_entity->Invalidate();
return *this;
}
inline const Nz::InstancedRenderableRef& DebugComponent::GetDebugRenderable(DebugDraw option) const
{
return m_debugRenderables[static_cast<std::size_t>(option)];
}
inline DebugDrawFlags DebugComponent::GetEnabledFlags() const
{
return m_enabledFlags;
}
inline void DebugComponent::UpdateDebugRenderable(DebugDraw option, Nz::InstancedRenderableRef renderable)
{
m_debugRenderables[static_cast<std::size_t>(option)] = std::move(renderable);
}
inline void DebugComponent::UpdateEnabledFlags(DebugDrawFlags flags)
{
m_enabledFlags = flags;
}
}

View File

@@ -0,0 +1,170 @@
// Copyright (C) 2017 Jérôme Leclercq
// This file is part of the "Nazara Development Kit"
// For conditions of distribution and use, see copyright notice in Prerequisites.hpp
#pragma once
#ifndef NDK_SERVER
#ifndef NDK_COMPONENTS_GRAPHICSCOMPONENT_HPP
#define NDK_COMPONENTS_GRAPHICSCOMPONENT_HPP
#include <Nazara/Graphics/CullingList.hpp>
#include <Nazara/Graphics/InstancedRenderable.hpp>
#include <Nazara/Math/Frustum.hpp>
#include <Nazara/Utility/Node.hpp>
#include <NazaraSDK/Component.hpp>
#include <unordered_map>
namespace Ndk
{
class GraphicsComponent;
using GraphicsComponentCullingList = Nz::CullingList<GraphicsComponent>;
using GraphicsComponentHandle = Nz::ObjectHandle<GraphicsComponent>;
class NDK_API GraphicsComponent : public Component<GraphicsComponent>
{
friend class RenderSystem;
public:
using RenderableList = std::vector<Nz::InstancedRenderableRef>;
inline GraphicsComponent();
inline GraphicsComponent(const GraphicsComponent& graphicsComponent);
~GraphicsComponent() = default;
inline void AddToCullingList(GraphicsComponentCullingList* cullingList) const;
void AddToRenderQueue(Nz::AbstractRenderQueue* renderQueue) const;
void AddToRenderQueueByCulling(const Nz::Frustumf& frustum, Nz::AbstractRenderQueue* renderQueue) const;
inline void Attach(Nz::InstancedRenderableRef renderable, int renderOrder = 0);
void Attach(Nz::InstancedRenderableRef renderable, const Nz::Matrix4f& localMatrix, int renderOrder = 0);
inline void Clear();
inline void Detach(const Nz::InstancedRenderable* renderable);
inline bool DoesRequireRealTimeReflections() const;
inline void EnsureBoundingVolumesUpdate() const;
inline void EnsureTransformMatrixUpdate() const;
template<typename Func> void ForEachRenderable(const Func& func) const;
inline const Nz::Boxf& GetAABB() const;
inline void GetAttachedRenderables(RenderableList* renderables) const;
inline std::size_t GetAttachedRenderableCount() const;
inline const Nz::BoundingVolumef& GetBoundingVolume(std::size_t renderableIndex) const;
inline const Nz::Matrix4f& GetLocalMatrix(std::size_t renderableIndex) const;
inline const Nz::Matrix4f& GetTransformMatrix(std::size_t renderableIndex) const;
inline void RemoveFromCullingList(GraphicsComponentCullingList* cullingList) const;
inline void SetScissorRect(const Nz::Recti& scissorRect);
inline void UpdateLocalMatrix(const Nz::InstancedRenderable* instancedRenderable, const Nz::Matrix4f& localMatrix);
inline void UpdateRenderOrder(const Nz::InstancedRenderable* instancedRenderable, int renderOrder);
static ComponentIndex componentIndex;
private:
struct Renderable;
void ConnectInstancedRenderableSignals(Renderable& renderable);
inline void ForceCullingInvalidation();
inline void InvalidateAABB() const;
void InvalidateRenderableData(const Nz::InstancedRenderable* renderable, Nz::UInt32 flags, std::size_t index);
void InvalidateRenderableMaterial(const Nz::InstancedRenderable* renderable, std::size_t skinIndex, std::size_t matIndex, const Nz::MaterialRef& newMat);
inline void InvalidateRenderables();
void InvalidateReflectionMap();
inline void InvalidateTransformMatrix();
void RegisterMaterial(Nz::Material* material, std::size_t count = 1);
void OnAttached() override;
void OnComponentAttached(BaseComponent& component) override;
void OnComponentDetached(BaseComponent& component) override;
void OnDetached() override;
void OnInstancedRenderableResetMaterials(const Nz::InstancedRenderable* renderable, std::size_t newMaterialCount);
void OnInstancedRenderableSkinChange(const Nz::InstancedRenderable* renderable, std::size_t newSkinIndex);
void OnMaterialReflectionChange(const Nz::Material* material, Nz::ReflectionMode reflectionMode);
void OnNodeInvalidated(const Nz::Node* node);
void UnregisterMaterial(Nz::Material* material);
void UpdateBoundingVolumes() const;
void UpdateTransformMatrix() const;
NazaraSlot(Nz::Node, OnNodeInvalidation, m_nodeInvalidationSlot);
using CullingListBoxEntry = GraphicsComponentCullingList::BoxEntry;
struct CullingBoxEntry
{
CullingListBoxEntry listEntry;
NazaraSlot(GraphicsComponentCullingList, OnCullingListRelease, cullingListReleaseSlot);
};
struct MaterialEntry
{
NazaraSlot(Nz::Material, OnMaterialReflectionModeChange, reflectionModelChangeSlot);
std::size_t renderableCounter;
};
struct Renderable
{
Renderable(const Nz::Matrix4f& transformMatrix) :
data(transformMatrix),
dataUpdated(false)
{
}
Renderable(const Renderable&) = delete;
Renderable(Renderable&& rhs) noexcept = default;
~Renderable()
{
// Disconnect release slot before releasing instanced renderable reference
renderableReleaseSlot.Disconnect();
}
Renderable& operator=(const Renderable&) = delete;
Renderable& operator=(Renderable&& r) noexcept = default;
NazaraSlot(Nz::InstancedRenderable, OnInstancedRenderableInvalidateBoundingVolume, renderableBoundingVolumeInvalidationSlot);
NazaraSlot(Nz::InstancedRenderable, OnInstancedRenderableInvalidateData, renderableDataInvalidationSlot);
NazaraSlot(Nz::InstancedRenderable, OnInstancedRenderableInvalidateMaterial, renderableMaterialInvalidationSlot);
NazaraSlot(Nz::InstancedRenderable, OnInstancedRenderableRelease, renderableReleaseSlot);
NazaraSlot(Nz::InstancedRenderable, OnInstancedRenderableResetMaterials, renderableResetMaterialsSlot);
NazaraSlot(Nz::InstancedRenderable, OnInstancedRenderableSkinChange, renderableSkinChangeSlot);
mutable Nz::BoundingVolumef boundingVolume;
mutable Nz::InstancedRenderable::InstanceData data;
Nz::InstancedRenderableRef renderable;
mutable bool dataUpdated;
};
std::size_t m_reflectiveMaterialCount;
mutable std::vector<CullingBoxEntry> m_cullingBoxEntries;
std::vector<Renderable> m_renderables;
std::unordered_map<const Nz::Material*, MaterialEntry> m_materialEntries;
mutable Nz::Boxf m_aabb;
mutable Nz::Matrix4f m_transformMatrix;
Nz::Recti m_scissorRect;
Nz::TextureRef m_reflectionMap;
mutable bool m_boundingVolumesUpdated;
mutable bool m_transformMatrixUpdated;
unsigned int m_reflectionMapSize;
};
}
#include <NazaraSDK/Components/GraphicsComponent.inl>
#endif // NDK_COMPONENTS_GRAPHICSCOMPONENT_HPP
#endif // NDK_SERVER

View File

@@ -0,0 +1,291 @@
// Copyright (C) 2017 Jérôme Leclercq
// This file is part of the "Nazara Development Kit"
// For conditions of distribution and use, see copyright notice in Prerequisites.hpp
#include <NazaraSDK/Components/GraphicsComponent.hpp>
#include <NazaraSDK/World.hpp>
#include <NazaraSDK/Systems/RenderSystem.hpp>
#include <algorithm>
namespace Ndk
{
inline GraphicsComponent::GraphicsComponent() :
m_reflectiveMaterialCount(0),
m_scissorRect(-1, -1)
{
}
/*!
* \brief Constructs a GraphicsComponent object by copy semantic
*
* \param graphicsComponent GraphicsComponent to copy
*/
inline GraphicsComponent::GraphicsComponent(const GraphicsComponent& graphicsComponent) :
Component(graphicsComponent),
m_reflectiveMaterialCount(0),
m_aabb(graphicsComponent.m_aabb),
m_transformMatrix(graphicsComponent.m_transformMatrix),
m_scissorRect(graphicsComponent.m_scissorRect),
m_boundingVolumesUpdated(graphicsComponent.m_boundingVolumesUpdated),
m_transformMatrixUpdated(graphicsComponent.m_transformMatrixUpdated)
{
m_renderables.reserve(graphicsComponent.m_renderables.size());
for (const Renderable& r : graphicsComponent.m_renderables)
Attach(r.renderable, r.data.localMatrix, r.data.renderOrder);
}
inline void GraphicsComponent::AddToCullingList(GraphicsComponentCullingList* cullingList) const
{
m_cullingBoxEntries.emplace_back();
CullingBoxEntry& entry = m_cullingBoxEntries.back();
entry.cullingListReleaseSlot.Connect(cullingList->OnCullingListRelease, this, &GraphicsComponent::RemoveFromCullingList);
entry.listEntry = cullingList->RegisterBoxTest(this);
InvalidateAABB();
}
/*!
* \brief Attaches a renderable to the entity
*
* \param renderable Reference to a renderable element
* \param renderOrder Render order of the element
*/
inline void GraphicsComponent::Attach(Nz::InstancedRenderableRef renderable, int renderOrder)
{
return Attach(std::move(renderable), Nz::Matrix4f::Identity(), renderOrder);
}
/*!
* \brief Clears every renderable elements
*/
inline void GraphicsComponent::Clear()
{
m_materialEntries.clear();
m_renderables.clear();
if (m_reflectiveMaterialCount > 0)
{
m_reflectiveMaterialCount = 0;
InvalidateReflectionMap();
}
InvalidateAABB();
}
/*!
* \brief Detaches a renderable to the entity
*
* \param renderable Reference to a renderable element
*/
inline void GraphicsComponent::Detach(const Nz::InstancedRenderable* renderable)
{
for (auto it = m_renderables.begin(); it != m_renderables.end(); ++it)
{
if (it->renderable == renderable)
{
InvalidateAABB();
std::size_t materialCount = renderable->GetMaterialCount();
for (std::size_t i = 0; i < materialCount; ++i)
UnregisterMaterial(renderable->GetMaterial(i));
m_renderables.erase(it);
ForceCullingInvalidation();
break;
}
}
}
/*!
* \brief Checks if this graphics component requires real-time reflections to be generated
*
* If any of the materials attached to a GraphicsComponent (via the attached instanced renderable) needs real-time reflections, this function will return true.
*
* \return True if real-time reflections needs to be generated or false
*/
inline bool GraphicsComponent::DoesRequireRealTimeReflections() const
{
return m_reflectiveMaterialCount != 0 && m_reflectionMap;
}
/*!
* \brief Ensures the bounding volume is up to date
*/
inline void GraphicsComponent::EnsureBoundingVolumesUpdate() const
{
if (!m_boundingVolumesUpdated)
UpdateBoundingVolumes();
}
/*!
* \brief Ensures the transformation matrix is up to date
*/
inline void GraphicsComponent::EnsureTransformMatrixUpdate() const
{
if (!m_transformMatrixUpdated)
UpdateTransformMatrix();
}
/*!
* \brief Gets the axis-aligned bounding box of the entity
* \return A constant reference to the AABB
*/
inline const Nz::Boxf& GraphicsComponent::GetAABB() const
{
EnsureBoundingVolumesUpdate();
return m_aabb;
}
/*!
* \brief Gets the set of renderable elements
*
* \param renderables Pointer to the list of renderables
*
* \remark Produces a NazaraAssert if renderables is invalid
*/
inline void GraphicsComponent::GetAttachedRenderables(RenderableList* renderables) const
{
NazaraAssert(renderables, "Invalid renderable list");
renderables->reserve(renderables->size() + m_renderables.size());
for (const Renderable& r : m_renderables)
renderables->push_back(r.renderable);
}
/*!
* \brief Gets the number of renderable elements attached to the entity
* \return Number of renderable elements
*/
inline std::size_t GraphicsComponent::GetAttachedRenderableCount() const
{
return m_renderables.size();
}
inline const Nz::BoundingVolumef& GraphicsComponent::GetBoundingVolume(std::size_t renderableIndex) const
{
EnsureBoundingVolumesUpdate();
assert(renderableIndex < m_renderables.size());
return m_renderables[renderableIndex].boundingVolume;
}
inline const Nz::Matrix4f& GraphicsComponent::GetLocalMatrix(std::size_t renderableIndex) const
{
assert(renderableIndex < m_renderables.size());
return m_renderables[renderableIndex].data.localMatrix;
}
inline const Nz::Matrix4f& GraphicsComponent::GetTransformMatrix(std::size_t renderableIndex) const
{
EnsureBoundingVolumesUpdate();
assert(renderableIndex < m_renderables.size());
return m_renderables[renderableIndex].data.transformMatrix;
}
/*!
* \brief Calls a function for every renderable attached to this component
*
* \param func Callback function which will be called with renderable data
*/
template<typename Func>
void GraphicsComponent::ForEachRenderable(const Func& func) const
{
for (const auto& renderableData : m_renderables)
func(renderableData.renderable, renderableData.data.localMatrix, renderableData.data.renderOrder);
}
inline void GraphicsComponent::RemoveFromCullingList(GraphicsComponentCullingList* cullingList) const
{
for (auto it = m_cullingBoxEntries.begin(); it != m_cullingBoxEntries.end(); ++it)
{
if (it->listEntry.GetParent() == cullingList)
{
if (m_cullingBoxEntries.size() > 1)
*it = std::move(m_cullingBoxEntries.back());
m_cullingBoxEntries.pop_back();
break;
}
}
}
inline void GraphicsComponent::SetScissorRect(const Nz::Recti& scissorRect)
{
m_scissorRect = scissorRect;
for (CullingBoxEntry& entry : m_cullingBoxEntries)
entry.listEntry.ForceInvalidation(); //< Invalidate render queues
}
inline void GraphicsComponent::UpdateLocalMatrix(const Nz::InstancedRenderable* instancedRenderable, const Nz::Matrix4f& localMatrix)
{
for (auto& renderable : m_renderables)
{
if (renderable.renderable == instancedRenderable)
{
renderable.data.localMatrix = localMatrix;
InvalidateAABB();
break;
}
}
}
inline void GraphicsComponent::UpdateRenderOrder(const Nz::InstancedRenderable* instancedRenderable, int renderOrder)
{
for (auto& renderable : m_renderables)
{
if (renderable.renderable == instancedRenderable)
{
renderable.data.renderOrder = renderOrder;
break;
}
}
}
/*!
* \brief Invalidates the bounding volume
*/
inline void GraphicsComponent::ForceCullingInvalidation()
{
for (CullingBoxEntry& entry : m_cullingBoxEntries)
entry.listEntry.ForceInvalidation(); //< Invalidate render queues
}
inline void GraphicsComponent::InvalidateAABB() const
{
m_boundingVolumesUpdated = false;
}
/*!
* \brief Invalidates every renderable elements
*/
inline void GraphicsComponent::InvalidateRenderables()
{
for (Renderable& r : m_renderables)
r.dataUpdated = false;
}
/*!
* \brief Invalidates the transformation matrix
*/
inline void GraphicsComponent::InvalidateTransformMatrix()
{
m_transformMatrixUpdated = false;
InvalidateAABB();
InvalidateRenderables();
}
}

View File

@@ -0,0 +1,40 @@
// Copyright (C) 2017 Jérôme Leclercq
// This file is part of the "Nazara Development Kit"
// For conditions of distribution and use, see copyright notice in Prerequisites.hpp
#pragma once
#ifndef NDK_COMPONENTS_LIFETIMECOMPONENT_HPP
#define NDK_COMPONENTS_LIFETIMECOMPONENT_HPP
#include <NazaraSDK/Component.hpp>
namespace Ndk
{
class LifetimeComponent;
using LifetimeComponentHandle = Nz::ObjectHandle<LifetimeComponent>;
class NDK_API LifetimeComponent : public Component<LifetimeComponent>
{
friend class LifetimeSystem;
public:
inline LifetimeComponent(float lifetime);
LifetimeComponent(const LifetimeComponent&) = default;
~LifetimeComponent() = default;
inline float GetRemainingTime() const;
static ComponentIndex componentIndex;
private:
inline bool UpdateLifetime(float elapsedTime);
float m_lifetime;
};
}
#include <NazaraSDK/Components/LifetimeComponent.inl>
#endif // NDK_COMPONENTS_LIFETIMECOMPONENT_HPP

View File

@@ -0,0 +1,24 @@
// Copyright (C) 2017 Jérôme Leclercq
// This file is part of the "Nazara Development Kit"
// For conditions of distribution and use, see copyright notice in Prerequisites.hpp
#include <NazaraSDK/Components/LifetimeComponent.hpp>
namespace Ndk
{
inline LifetimeComponent::LifetimeComponent(float lifetime) :
m_lifetime(lifetime)
{
}
inline float Ndk::LifetimeComponent::GetRemainingTime() const
{
return m_lifetime;
}
inline bool LifetimeComponent::UpdateLifetime(float elapsedTime)
{
m_lifetime -= elapsedTime;
return m_lifetime < 0.f;
}
}

View File

@@ -0,0 +1,36 @@
// Copyright (C) 2017 Jérôme Leclercq
// This file is part of the "Nazara Development Kit"
// For conditions of distribution and use, see copyright notice in Prerequisites.hpp
#pragma once
#ifndef NDK_SERVER
#ifndef NDK_COMPONENTS_LIGHTCOMPONENT_HPP
#define NDK_COMPONENTS_LIGHTCOMPONENT_HPP
#include <Nazara/Graphics/Light.hpp>
#include <NazaraSDK/Component.hpp>
namespace Ndk
{
class LightComponent;
using LightComponentHandle = Nz::ObjectHandle<LightComponent>;
class NDK_API LightComponent : public Component<LightComponent>, public Nz::Light
{
public:
inline LightComponent(Nz::LightType lightType = Nz::LightType_Point);
LightComponent(const LightComponent& light) = default;
~LightComponent() = default;
LightComponent& operator=(const LightComponent& light) = default;
static ComponentIndex componentIndex;
};
}
#include <NazaraSDK/Components/LightComponent.inl>
#endif // NDK_COMPONENTS_LIGHTCOMPONENT_HPP
#endif // NDK_SERVER

View File

@@ -0,0 +1,15 @@
// Copyright (C) 2017 Jérôme Leclercq
// This file is part of the "Nazara Development Kit"
// For conditions of distribution and use, see copyright notice in Prerequisites.hpp
namespace Ndk
{
/*!
* \brief Constructs an LightComponent object with a light type
*/
inline LightComponent::LightComponent(Nz::LightType lightType) :
Nz::Light(lightType)
{
}
}

View File

@@ -0,0 +1,38 @@
// Copyright (C) 2017 Jérôme Leclercq
// This file is part of the "Nazara Development Kit"
// For conditions of distribution and use, see copyright notice in Prerequisites.hpp
#pragma once
#ifndef NDK_SERVER
#ifndef NDK_COMPONENTS_LISTENERCOMPONENT_HPP
#define NDK_COMPONENTS_LISTENERCOMPONENT_HPP
#include <NazaraSDK/Component.hpp>
namespace Ndk
{
class ListenerComponent;
using ListenerComponentHandle = Nz::ObjectHandle<ListenerComponent>;
class NDK_API ListenerComponent : public Component<ListenerComponent>
{
public:
inline ListenerComponent();
~ListenerComponent() = default;
inline bool IsActive() const;
inline void SetActive(bool active = true);
static ComponentIndex componentIndex;
private:
bool m_isActive;
};
}
#include <NazaraSDK/Components/ListenerComponent.inl>
#endif // NDK_COMPONENTS_LISTENERCOMPONENT_HPP
#endif // NDK_SERVER

View File

@@ -0,0 +1,36 @@
// Copyright (C) 2017 Jérôme Leclercq
// This file is part of the "Nazara Development Kit"
// For conditions of distribution and use, see copyright notice in Prerequisites.hpp
namespace Ndk
{
/*!
* \brief Constructs an ListenerComponent object by default
*/
inline ListenerComponent::ListenerComponent() :
m_isActive(true)
{
}
/*!
* \brief Checks whether the listener is activated
* \param true If it is the case
*/
inline bool ListenerComponent::IsActive() const
{
return m_isActive;
}
/*!
* \brief Enables the listener
*
* \param active Should the listener be active
*/
inline void ListenerComponent::SetActive(bool active)
{
m_isActive = active;
}
}

View File

@@ -0,0 +1,35 @@
// Copyright (C) 2017 Jérôme Leclercq
// This file is part of the "Nazara Development Kit"
// For conditions of distribution and use, see copyright notice in Prerequisites.hpp
#pragma once
#ifndef NDK_COMPONENTS_NODECOMPONENT_HPP
#define NDK_COMPONENTS_NODECOMPONENT_HPP
#include <Nazara/Utility/Node.hpp>
#include <NazaraSDK/Component.hpp>
namespace Ndk
{
class Entity;
class NodeComponent;
using NodeComponentHandle = Nz::ObjectHandle<NodeComponent>;
class NDK_API NodeComponent : public Component<NodeComponent>, public Nz::Node
{
public:
NodeComponent() = default;
~NodeComponent() = default;
void SetParent(Entity* entity, bool keepDerived = false);
using Nz::Node::SetParent;
static ComponentIndex componentIndex;
};
}
#include <NazaraSDK/Components/NodeComponent.inl>
#endif // NDK_COMPONENTS_NODECOMPONENT_HPP

View File

@@ -0,0 +1,30 @@
// Copyright (C) 2017 Jérôme Leclercq
// This file is part of the "Nazara Development Kit"
// For conditions of distribution and use, see copyright notice in Prerequisites.hpp
#include <Nazara/Core/Error.hpp>
#include <NazaraSDK/Entity.hpp>
namespace Ndk
{
/*!
* \brief Sets the parent node of the entity
*
* \param entity Pointer to the entity considered as parent
* \param keepDerived Should this component considered as a derived
*
* \remark Produces a NazaraAssert if entity has no component NodeComponent
*/
inline void NodeComponent::SetParent(Entity* entity, bool keepDerived)
{
if (entity)
{
NazaraAssert(entity->HasComponent<NodeComponent>(), "Entity must have a NodeComponent");
Nz::Node::SetParent(entity->GetComponent<NodeComponent>(), keepDerived);
}
else
Nz::Node::SetParent(nullptr, keepDerived);
}
}

View File

@@ -0,0 +1,49 @@
// Copyright (C) 2017 Jérôme Leclercq
// This file is part of the "Nazara Development Kit"
// For conditions of distribution and use, see copyright notice in Prerequisites.hpp
#pragma once
#ifndef NDK_SERVER
#ifndef NDK_COMPONENTS_PARTICLEEMITTERCOMPONENT_HPP
#define NDK_COMPONENTS_PARTICLEEMITTERCOMPONENT_HPP
#include <Nazara/Graphics/ParticleEmitter.hpp>
#include <NazaraSDK/Component.hpp>
namespace Ndk
{
class ParticleEmitterComponent;
using ParticleEmitterComponentHandle = Nz::ObjectHandle<ParticleEmitterComponent>;
class NDK_API ParticleEmitterComponent : public Component<ParticleEmitterComponent>, public Nz::ParticleEmitter
{
public:
using SetupFunc = std::function<void(const EntityHandle& /*entity*/, Nz::ParticleMapper& /*mapper*/, unsigned int /*count*/)>;
inline ParticleEmitterComponent();
ParticleEmitterComponent(const ParticleEmitterComponent& emitter) = default;
ParticleEmitterComponent(ParticleEmitterComponent&& emitter) = default;
~ParticleEmitterComponent() = default;
inline void Enable(bool active = true);
inline bool IsActive() const;
inline void SetSetupFunc(SetupFunc func);
static ComponentIndex componentIndex;
private:
void SetupParticles(Nz::ParticleMapper& mapper, unsigned int count) const override;
SetupFunc m_setupFunc;
bool m_isActive;
};
}
#include <NazaraSDK/Components/ParticleEmitterComponent.inl>
#endif // NDK_COMPONENTS_PARTICLEEMITTERCOMPONENT_HPP
#endif // NDK_SERVER

View File

@@ -0,0 +1,47 @@
// Copyright (C) 2017 Jérôme Leclercq
// This file is part of the "Nazara Development Kit"
// For conditions of distribution and use, see copyright notice in Prerequisites.hpp
namespace Ndk
{
/*!
* \brief Constructs an ParticleEmitterComponent object by default
*/
inline ParticleEmitterComponent::ParticleEmitterComponent() :
m_isActive(true)
{
}
/*!
* \brief Enables the emission of particles
*
* \param active Should the emitter be active
*/
inline void Ndk::ParticleEmitterComponent::Enable(bool active)
{
m_isActive = active;
}
/*!
* \brief Checks whether the emission of particles is activated
* \param true If it is the case
*/
inline bool ParticleEmitterComponent::IsActive() const
{
return m_isActive;
}
/*!
* \brief Sets the function use for setting up particles
*
* \param func Function to set up particles
*/
inline void Ndk::ParticleEmitterComponent::SetSetupFunc(SetupFunc func)
{
m_setupFunc = std::move(func);
}
}

View File

@@ -0,0 +1,41 @@
// Copyright (C) 2017 Jérôme Leclercq
// This file is part of the "Nazara Development Kit"
// For conditions of distribution and use, see copyright notice in Prerequisites.hpp
#pragma once
#ifndef NDK_SERVER
#ifndef NDK_COMPONENTS_PARTICLEGROUPCOMPONENT_HPP
#define NDK_COMPONENTS_PARTICLEGROUPCOMPONENT_HPP
#include <Nazara/Graphics/ParticleGroup.hpp>
#include <NazaraSDK/Component.hpp>
namespace Ndk
{
class ParticleGroupComponent;
using ParticleGroupComponentHandle = Nz::ObjectHandle<ParticleGroupComponent>;
class NDK_API ParticleGroupComponent : public Component<ParticleGroupComponent>, public Nz::ParticleGroup
{
public:
inline ParticleGroupComponent(unsigned int maxParticleCount, Nz::ParticleLayout layout);
inline ParticleGroupComponent(unsigned int maxParticleCount, Nz::ParticleDeclarationConstRef declaration);
ParticleGroupComponent(const ParticleGroupComponent&) = default;
~ParticleGroupComponent() = default;
void AddEmitter(Entity* emitter);
using ParticleGroup::AddEmitter;
void RemoveEmitter(Entity* emitter);
using ParticleGroup::RemoveEmitter;
static ComponentIndex componentIndex;
};
}
#include <NazaraSDK/Components/ParticleGroupComponent.inl>
#endif // NDK_COMPONENTS_PARTICLEGROUPCOMPONENT_HPP
#endif // NDK_SERVER

View File

@@ -0,0 +1,76 @@
// Copyright (C) 2017 Jérôme Leclercq
// This file is part of the "Nazara Development Kit"
// For conditions of distribution and use, see copyright notice in Prerequisites.hpp
#include <NazaraSDK/Components/ParticleEmitterComponent.hpp>
#include <Nazara/Core/Error.hpp>
namespace Ndk
{
/*!
* \ingroup NDK
* \class Ndk::ParticleGroupComponent
* \brief NDK class that represents the component for a group of particles
*/
/*!
* \brief Constructs a ParticleGroupComponent object with a maximal number of particles and a layout
*
* \param maxParticleCount Maximum number of particles to generate
* \param layout Enumeration for the layout of data information for the particles
*/
inline ParticleGroupComponent::ParticleGroupComponent(unsigned int maxParticleCount, Nz::ParticleLayout layout) :
ParticleGroup(maxParticleCount, layout)
{
}
/*!
* \brief Constructs a ParticleGroupComponent object with a maximal number of particles and a particle declaration
*
* \param maxParticleCount Maximum number of particles to generate
* \param declaration Data information for the particles
*/
inline ParticleGroupComponent::ParticleGroupComponent(unsigned int maxParticleCount, Nz::ParticleDeclarationConstRef declaration) :
ParticleGroup(maxParticleCount, std::move(declaration))
{
}
/*!
* \brief Adds an emitter to the particles
*
* \param emitter Emitter for the particles
*
* \remark Produces a NazaraAssert if emitter is invalid
* \remark Produces a NazaraAssert if entity has no component of type ParticleEmitterComponent
*/
inline void ParticleGroupComponent::AddEmitter(Entity* emitter)
{
NazaraAssert(emitter && emitter->IsValid(), "Invalid entity");
NazaraAssert(emitter->HasComponent<ParticleEmitterComponent>(), "Entity must have a ParticleEmitterComponent");
auto& emitterComponent = emitter->GetComponent<ParticleEmitterComponent>();
ParticleGroup::AddEmitter(&emitterComponent);
}
/*!
* \brief Removes an emitter to the particles
*
* \param emitter Emitter for the particles to remove
*
* \remark Produces a NazaraAssert if emitter is invalid
* \remark Produces a NazaraAssert if entity has no component of type ParticleEmitterComponent
*/
inline void ParticleGroupComponent::RemoveEmitter(Entity* emitter)
{
NazaraAssert(emitter && emitter->IsValid(), "Invalid entity");
NazaraAssert(emitter->HasComponent<ParticleEmitterComponent>(), "Entity must have a ParticleEmitterComponent");
auto& emitterComponent = emitter->GetComponent<ParticleEmitterComponent>();
ParticleGroup::RemoveEmitter(&emitterComponent);
}
}

View File

@@ -0,0 +1,130 @@
// Copyright (C) 2017 Jérôme Leclercq
// This file is part of the "Nazara Development Kit"
// For conditions of distribution and use, see copyright notice in Prerequisites.hpp
#pragma once
#ifndef NDK_COMPONENTS_PHYSICSCOMPONENT2D_HPP
#define NDK_COMPONENTS_PHYSICSCOMPONENT2D_HPP
#include <Nazara/Physics2D/RigidBody2D.hpp>
#include <NazaraSDK/Component.hpp>
#include <memory>
namespace Ndk
{
class PhysicsComponent2D;
using PhysicsComponent2DHandle = Nz::ObjectHandle<PhysicsComponent2D>;
class NDK_API PhysicsComponent2D : public Component<PhysicsComponent2D>
{
friend class CollisionComponent2D;
friend class PhysicsSystem2D;
friend class ConstraintComponent2D;
public:
using VelocityFunc = Nz::RigidBody2D::VelocityFunc;
PhysicsComponent2D();
PhysicsComponent2D(const PhysicsComponent2D& physics);
~PhysicsComponent2D() = default;
inline void AddForce(const Nz::Vector2f& force, Nz::CoordSys coordSys = Nz::CoordSys_Global);
inline void AddForce(const Nz::Vector2f& force, const Nz::Vector2f& point, Nz::CoordSys coordSys = Nz::CoordSys_Global);
inline void AddImpulse(const Nz::Vector2f& impulse, Nz::CoordSys coordSys = Nz::CoordSys_Global);
inline void AddImpulse(const Nz::Vector2f& impulse, const Nz::Vector2f& point, Nz::CoordSys coordSys = Nz::CoordSys_Global);
inline void AddTorque(const Nz::RadianAnglef& torque);
inline bool ClosestPointQuery(const Nz::Vector2f& position, Nz::Vector2f* closestPoint, float* closestDistance) const;
inline void EnableNodeSynchronization(bool nodeSynchronization);
inline void ForceSleep();
inline void ForEachArbiter(const std::function<void(Nz::Arbiter2D&)>& callback);
inline Nz::Rectf GetAABB() const;
inline float GetAngularDamping() const;
inline Nz::RadianAnglef GetAngularVelocity() const;
NAZARA_DEPRECATED("Name error, please use GetMassCenter")
inline Nz::Vector2f GetCenterOfGravity(Nz::CoordSys coordSys = Nz::CoordSys_Local) const;
inline float GetElasticity(std::size_t shapeIndex = 0) const;
inline float GetFriction(std::size_t shapeIndex = 0) const;
inline float GetMass() const;
inline Nz::Vector2f GetMassCenter(Nz::CoordSys coordSys = Nz::CoordSys_Local) const;
inline float GetMomentOfInertia() const;
inline Nz::Vector2f GetPosition() const;
inline Nz::RadianAnglef GetRotation() const;
inline Nz::Vector2f GetSurfaceVelocity(std::size_t shapeIndex = 0) const;
inline std::size_t GetShapeCount() const;
inline Nz::Vector2f GetVelocity() const;
const VelocityFunc& GetVelocityFunction() const;
inline bool IsNodeSynchronizationEnabled() const;
inline bool IsSleeping() const;
inline bool IsValid() const;
inline void ResetVelocityFunction();
inline void SetAngularDamping(float angularDamping);
inline void SetAngularVelocity(const Nz::RadianAnglef& angularVelocity);
inline void SetElasticity(float elasticity);
inline void SetElasticity(std::size_t shapeIndex, float friction);
inline void SetFriction(float friction);
inline void SetFriction(std::size_t shapeIndex, float friction);
inline void SetMass(float mass, bool recomputeMoment = true);
inline void SetMassCenter(const Nz::Vector2f& center, Nz::CoordSys coordSys = Nz::CoordSys_Local);
inline void SetMomentOfInertia(float moment);
inline void SetPosition(const Nz::Vector2f& position);
inline void SetRotation(const Nz::RadianAnglef& rotation);
inline void SetSurfaceVelocity(const Nz::Vector2f& velocity);
inline void SetSurfaceVelocity(std::size_t shapeIndex, const Nz::Vector2f& velocity);
inline void SetVelocity(const Nz::Vector2f& velocity);
inline void SetVelocityFunction(VelocityFunc velocityFunc);
inline void UpdateVelocity(const Nz::Vector2f& gravity, float damping, float deltaTime);
inline void Wakeup();
static ComponentIndex componentIndex;
private:
inline void ApplyPhysicsState(Nz::RigidBody2D& rigidBody) const;
inline void CopyPhysicsState(const Nz::RigidBody2D& rigidBody);
Nz::RigidBody2D* GetRigidBody();
const Nz::RigidBody2D* GetRigidBody() const;
void OnAttached() override;
void OnComponentAttached(BaseComponent& component) override;
void OnComponentDetached(BaseComponent& component) override;
void OnDetached() override;
void OnEntityDestruction() override;
struct PendingPhysObjectStates
{
struct ShapeStates
{
Nz::Vector2f surfaceVelocity;
float elasticity;
float friction;
};
VelocityFunc velocityFunc;
std::vector<ShapeStates> shapes;
Nz::RadianAnglef angularVelocity;
Nz::Vector2f massCenter;
Nz::Vector2f velocity;
bool valid = false;
float mass;
float momentOfInertia;
};
std::unique_ptr<Nz::RigidBody2D> m_object;
PendingPhysObjectStates m_pendingStates;
bool m_nodeSynchronizationEnabled;
};
}
#include <NazaraSDK/Components/PhysicsComponent2D.inl>
#endif // NDK_COMPONENTS_PHYSICSCOMPONENT2D_HPP

View File

@@ -0,0 +1,725 @@
// Copyright (C) 2017 Jérôme Leclercq
// This file is part of the "Nazara Development Kit"
// For conditions of distribution and use, see copyright notice in Prerequisites.hpp
#include <NazaraSDK/Components/PhysicsComponent2D.hpp>
#include <Nazara/Core/Error.hpp>
namespace Ndk
{
/*!
* \brief Constructs a PhysicsComponent2D object by default
*/
inline PhysicsComponent2D::PhysicsComponent2D() :
m_nodeSynchronizationEnabled(true)
{
}
/*!
* \brief Constructs a PhysicsComponent2D object by copy semantic
*
* \param physics PhysicsComponent2D to copy
*/
inline PhysicsComponent2D::PhysicsComponent2D(const PhysicsComponent2D& physics)
{
CopyPhysicsState(*physics.GetRigidBody());
}
/*!
* \brief Applies a physics force to the entity
*
* \param force Force to apply on the entity
* \param coordSys System coordinates to consider
*
* \remark Produces a NazaraAssert if the physics object is invalid
*/
inline void PhysicsComponent2D::AddForce(const Nz::Vector2f& force, Nz::CoordSys coordSys)
{
NazaraAssert(m_object, "Invalid physics object");
m_object->AddForce(force, coordSys);
}
/*!
* \brief Applies a physics force to the entity
*
* \param force Force to apply on the entity
* \param point Point where to apply the force
* \param coordSys System coordinates to consider
*
* \remark Produces a NazaraAssert if the physics object is invalid
*/
inline void PhysicsComponent2D::AddForce(const Nz::Vector2f& force, const Nz::Vector2f& point, Nz::CoordSys coordSys)
{
NazaraAssert(m_object, "Invalid physics object");
m_object->AddForce(force, point, coordSys);
}
/*!
* \brief Applies a impulse to the entity
*
* \param impulse Impulse to apply on the entity
*
* \remark Produces a NazaraAssert if the physics object is invalid
*/
inline void PhysicsComponent2D::AddImpulse(const Nz::Vector2f& impulse, Nz::CoordSys coordSys)
{
NazaraAssert(m_object, "Invalid physics object");
m_object->AddImpulse(impulse, coordSys);
}
/*!
* \brief Applies a impulse to the entity
*
* \param impulse Impulse to apply on the entity
* \param point Point where the impulse is applied
*
* \remark Produces a NazaraAssert if the physics object is invalid
*/
inline void PhysicsComponent2D::AddImpulse(const Nz::Vector2f& impulse, const Nz::Vector2f& point, Nz::CoordSys coordSys)
{
NazaraAssert(m_object, "Invalid physics object");
m_object->AddImpulse(impulse, point, coordSys);
}
/*!
* \brief Applies a torque to the entity
*
* \param torque Torque to apply on the entity
*
* \remark Produces a NazaraAssert if the physics object is invalid
*/
inline void PhysicsComponent2D::AddTorque(const Nz::RadianAnglef& torque)
{
NazaraAssert(m_object, "Invalid physics object");
m_object->AddTorque(torque);
}
/*!
* \brief Finds the closest point on the entity relative to a position
* \return True if such a point exists (will return false if no collider exists)
*
* \param position The starting point which will be used for the query
* \param closestPoint The closest point on entity surface
* \param closestDistance The distance between the closest point and the starting point, may be negative if starting point is inside the entity
*
* \remark Produces a NazaraAssert if the physics object is invalid
*/
inline bool PhysicsComponent2D::ClosestPointQuery(const Nz::Vector2f& position, Nz::Vector2f* closestPoint, float* closestDistance) const
{
NazaraAssert(m_object, "Invalid physics object");
return m_object->ClosestPointQuery(position, closestPoint, closestDistance);
}
/*!
* \brief Enables position/rotation synchronization with the NodeComponent
*
* By default, at every update of the PhysicsSystem2D, the NodeComponent's position and rotation (if any) will be synchronized with
* the values of the PhysicsComponent2D. This function allows to enable/disable this behavior on a per-entity basis.
*
* \param nodeSynchronization Should synchronization occur between NodeComponent and PhysicsComponent2D
*/
inline void PhysicsComponent2D::EnableNodeSynchronization(bool nodeSynchronization)
{
m_nodeSynchronizationEnabled = nodeSynchronization;
if (m_entity)
m_entity->Invalidate();
}
/*!
TODO
*/
inline void PhysicsComponent2D::ForceSleep()
{
NazaraAssert(m_object, "Invalid physics object");
return m_object->ForceSleep();
}
/*!
TODO
*/
inline void PhysicsComponent2D::ForEachArbiter(const std::function<void(Nz::Arbiter2D&)>& callback)
{
NazaraAssert(m_object, "Invalid physics object");
return m_object->ForEachArbiter(callback);
}
/*!
* \brief Gets the AABB of the physics object
* \return AABB of the object
*
* \remark Produces a NazaraAssert if the physics object is invalid
*/
inline Nz::Rectf PhysicsComponent2D::GetAABB() const
{
NazaraAssert(m_object, "Invalid physics object");
return m_object->GetAABB();
}
/*!
* \brief Gets the angular damping or moment of inertia of the physics object
* \return Angular damping of the object
*
* \remark Produces a NazaraAssert if the physics object is invalid
*
* \see GetMomentOfInertia
*/
inline float PhysicsComponent2D::GetAngularDamping() const
{
NazaraAssert(m_object, "Invalid physics object");
return m_object->GetAngularDamping();
}
/*!
* \brief Gets the angular velocity of the physics object
* \return Angular velocity of the object
*
* \remark Produces a NazaraAssert if the physics object is invalid
*/
inline Nz::RadianAnglef PhysicsComponent2D::GetAngularVelocity() const
{
NazaraAssert(m_object, "Invalid physics object");
return m_object->GetAngularVelocity();
}
/*!
* \brief Gets the gravity center of the physics object
* \return Gravity center of the object
*
* \param coordSys System coordinates to consider
*
* \remark Produces a NazaraAssert if the physics object is invalid
*/
inline Nz::Vector2f PhysicsComponent2D::GetCenterOfGravity(Nz::CoordSys coordSys) const
{
NazaraAssert(m_object, "Invalid physics object");
return m_object->GetMassCenter(coordSys);
}
/*!
* \brief Gets the elasticity of a shape belonging to this physics object
* \return Elasticity of the shape
*
* \param shapeIndex Shape index of the collider we're interested
*
* \remark Produces a NazaraAssert if the physics object is invalid
*/
inline float PhysicsComponent2D::GetElasticity(std::size_t shapeIndex) const
{
NazaraAssert(m_object, "Invalid physics object");
return m_object->GetElasticity(shapeIndex);
}
/*!
* \brief Gets the friction of a shape belonging to this physics object
* \return Friction of the shape
*
* \param shapeIndex Shape index of the collider we're interested
*
* \remark Produces a NazaraAssert if the physics object is invalid
*/
inline float PhysicsComponent2D::GetFriction(std::size_t shapeIndex) const
{
NazaraAssert(m_object, "Invalid physics object");
return m_object->GetFriction(shapeIndex);
}
/*!
* \brief Gets the mass of the physics object
* \return Mass of the object
*
* \remark Produces a NazaraAssert if the physics object is invalid
*/
inline float PhysicsComponent2D::GetMass() const
{
NazaraAssert(m_object, "Invalid physics object");
return m_object->GetMass();
}
/*!
* \brief Gets the gravity center of the physics object
* \return Gravity center of the object
*
* \param coordSys System coordinates to consider
*
* \remark Produces a NazaraAssert if the physics object is invalid
*/
inline Nz::Vector2f PhysicsComponent2D::GetMassCenter(Nz::CoordSys coordSys) const
{
NazaraAssert(m_object, "Invalid physics object");
return m_object->GetMassCenter(coordSys);
}
/*!
* \brief Gets the angular damping or moment of inertia of the physics object
* \return Moment of inertia of the object
*
* \remark Produces a NazaraAssert if the physics object is invalid
*
* \see GetAngularDamping
*/
inline float PhysicsComponent2D::GetMomentOfInertia() const
{
NazaraAssert(m_object, "Invalid physics object");
return m_object->GetMomentOfInertia();
}
/*!
* \brief Gets the position of the physics object
* \return Position of the object
*
* \remark Produces a NazaraAssert if the physics object is invalid
*/
inline Nz::Vector2f PhysicsComponent2D::GetPosition() const
{
NazaraAssert(m_object, "Invalid physics object");
return m_object->GetPosition();
}
/*!
* \brief Gets the rotation of the physics object
* \return Rotation of the object
*
* \remark Produces a NazaraAssert if the physics object is invalid
*/
inline Nz::RadianAnglef PhysicsComponent2D::GetRotation() const
{
NazaraAssert(m_object, "Invalid physics object");
return m_object->GetRotation();
}
/*!
* \brief Gets the surface velocity of a shape belonging to this physics object
* \return Surface velocity of the shape
*
* \param shapeIndex Shape index of the collider we're interested
*
* \remark Produces a NazaraAssert if the physics object is invalid
*/
inline Nz::Vector2f PhysicsComponent2D::GetSurfaceVelocity(std::size_t shapeIndex) const
{
return m_object->GetSurfaceVelocity(shapeIndex);
}
/*!
* \brief Gets the rotation of the physics object
* \return Shape count of the object
*
* \remark Produces a NazaraAssert if the physics object is invalid
*/
inline std::size_t PhysicsComponent2D::GetShapeCount() const
{
return m_object->GetShapeCount();
}
/*!
* \brief Gets the velocity of the physics object
* \return Velocity of the object
*
* \remark Produces a NazaraAssert if the physics object is invalid
*/
inline Nz::Vector2f PhysicsComponent2D::GetVelocity() const
{
NazaraAssert(m_object, "Invalid physics object");
return m_object->GetVelocity();
}
/*!
* \brief Gets the custom velocity function of the physics object
* \return Velocity function of the object (may be empty if default function is used)
*
* \remark Produces a NazaraAssert if the physics object is invalid
*/
inline auto PhysicsComponent2D::GetVelocityFunction() const -> const VelocityFunc&
{
NazaraAssert(m_object, "Invalid physics object");
return m_object->GetVelocityFunction();
}
/*!
* \brief Checks if position & rotation are synchronized with NodeComponent
* \return true If synchronization is enabled
*
* \see EnableNodeSynchronization
*/
inline bool PhysicsComponent2D::IsNodeSynchronizationEnabled() const
{
return m_nodeSynchronizationEnabled;
}
/*!
* \brief Checks whether the entity is currently sleeping
* \return true If it is the case
*
* \remark Produces a NazaraAssert if the physics object is invalid
*/
inline bool PhysicsComponent2D::IsSleeping() const
{
NazaraAssert(m_object, "Invalid physics object");
return m_object->IsSleeping();
}
/*!
* \brief Checks if this component is bound to a valid rigid body
*
* A component may not be bound to a rigid body if the component is not bound to an entity or if this entity is being destroyed
*
* \return true If bound, false otherwise
*/
inline bool PhysicsComponent2D::IsValid() const
{
return bool(m_object);
}
/*!
* \brief Reset velocity function to default one
*
* \remark Produces a NazaraAssert if the physics object is invalid
*/
inline void PhysicsComponent2D::ResetVelocityFunction()
{
NazaraAssert(m_object, "Invalid physics object");
return m_object->ResetVelocityFunction();
}
/*!
* \brief Sets the angular damping or moment of inertia of the physics object
*
* \param angularDamping Angular damping of the object
*
* \remark Produces a NazaraAssert if the physics object is invalid
*
* \see SetMomentOfInertia
*/
inline void PhysicsComponent2D::SetAngularDamping(float angularDamping)
{
NazaraAssert(m_object, "Invalid physics object");
m_object->SetAngularDamping(angularDamping);
}
/*!
* \brief Sets the angular velocity of the physics object
*
* \param angularVelocity Angular velocity of the object
*
* \remark Produces a NazaraAssert if the physics object is invalid
*/
inline void PhysicsComponent2D::SetAngularVelocity(const Nz::RadianAnglef& angularVelocity)
{
NazaraAssert(m_object, "Invalid physics object");
m_object->SetAngularVelocity(angularVelocity);
}
/*!
* \brief Sets the elasticity of the whole physics object
*
* Overrides all shapes elasticity with a single value
*
* \param elasticity Elasticity to be applied
*
* \remark Elasticity must be positive or zero
*/
inline void PhysicsComponent2D::SetElasticity(float elasticity)
{
NazaraAssert(m_object, "Invalid physics object");
NazaraAssert(elasticity >= 0.f, "Friction must be positive");
m_object->SetElasticity(elasticity);
}
/*!
* \brief Sets the elasticity of a single shape of the physics object
*
* \param shapeIndex Target shape index
* \param elasticity Elasticity to be applied
*
* \remark Elasticity must be positive or zero
*/
inline void PhysicsComponent2D::SetElasticity(std::size_t shapeIndex, float elasticity)
{
NazaraAssert(m_object, "Invalid physics object");
NazaraAssert(elasticity >= 0.f, "Friction must be positive");
m_object->SetElasticity(shapeIndex, elasticity);
}
/*!
* \brief Sets the friction of the whole physics object
*
* Overrides all shapes friction with a single value
*
* \param friction Friction to be applied
*
* \remark Friction must be positive or zero
*/
inline void PhysicsComponent2D::SetFriction(float friction)
{
NazaraAssert(m_object, "Invalid physics object");
NazaraAssert(friction >= 0.f, "Friction must be positive");
m_object->SetFriction(friction);
}
/*!
* \brief Sets the friction of a single shape of the physics object
*
* \param shapeIndex Target shape index
* \param friction Friction to be applied
*
* \remark Friction must be positive or zero
*/
inline void PhysicsComponent2D::SetFriction(std::size_t shapeIndex, float friction)
{
NazaraAssert(m_object, "Invalid physics object");
NazaraAssert(friction >= 0.f, "Friction must be positive");
m_object->SetFriction(shapeIndex, friction);
}
/*!
* \brief Sets the mass of the physics object
*
* \param mass Mass of the object
* \param recomputeMoment Should the moment of inertia be recomputed according to the new mass
*
* \remark Mass must be positive or zero
*/
inline void PhysicsComponent2D::SetMass(float mass, bool recomputeMoment)
{
NazaraAssert(m_object, "Invalid physics object");
NazaraAssert(mass >= 0.f, "Mass should be positive");
m_object->SetMass(mass, recomputeMoment);
}
/*!
* \brief Sets the gravity center of the physics object
*
* \param center Gravity center of the object
*
* \remark Produces a NazaraAssert if the physics object is invalid
*/
inline void PhysicsComponent2D::SetMassCenter(const Nz::Vector2f& center, Nz::CoordSys coordSys)
{
NazaraAssert(m_object, "Invalid physics object");
m_object->SetMassCenter(center, coordSys);
}
/*!
* \brief Sets the angular damping or moment of inertia of the physics object
*
* \param moment Moment of inertia of the object
*
* \remark Produces a NazaraAssert if the physics object is invalid
*
* \see SetAngularDamping
*/
inline void PhysicsComponent2D::SetMomentOfInertia(float moment)
{
NazaraAssert(m_object, "Invalid physics object");
m_object->SetMomentOfInertia(moment);
}
/*!
* \brief Sets the position of the physics object
*
* \param position Position of the object
*
* \remark Produces a NazaraAssert if the physics object is invalid
*/
inline void PhysicsComponent2D::SetPosition(const Nz::Vector2f& position)
{
NazaraAssert(m_object, "Invalid physics object");
m_object->SetPosition(position);
}
/*!
* \brief Sets the rotation of the physics object
*
* \param rotation Rotation of the object
*
* \remark Produces a NazaraAssert if the physics object is invalid
*/
inline void PhysicsComponent2D::SetRotation(const Nz::RadianAnglef& rotation)
{
NazaraAssert(m_object, "Invalid physics object");
m_object->SetRotation(rotation);
}
/*!
* \brief Sets the surface velocity of the whole physics object
*
* Overrides all shapes surface velocity with a single value
*
* \param velocity Surface velocity to be applied
*/
inline void PhysicsComponent2D::SetSurfaceVelocity(const Nz::Vector2f& velocity)
{
NazaraAssert(m_object, "Invalid physics object");
m_object->SetSurfaceVelocity(velocity);
}
/*!
* \brief Sets the surface velocity of a single shape of the physics object
*
* \param shapeIndex Target shape index
* \param velocity Surface velocity to be applied
*/
inline void PhysicsComponent2D::SetSurfaceVelocity(std::size_t shapeIndex, const Nz::Vector2f& velocity)
{
NazaraAssert(m_object, "Invalid physics object");
m_object->SetSurfaceVelocity(shapeIndex, velocity);
}
/*!
* \brief Sets the velocity of the physics object
*
* \param velocity Velocity of the object
*/
inline void PhysicsComponent2D::SetVelocity(const Nz::Vector2f& velocity)
{
NazaraAssert(m_object, "Invalid physics object");
m_object->SetVelocity(velocity);
}
/*!
* \brief Sets a custom velocity function for the physics object
*
* A velocity function is called (for non-kinematic and non-static objects) at every physics update to compute the new velocity of the object.
* You may call UpdateVelocity (the default velocity function) to let the physics engine compute that itself and then adjust it using GetVelocity/SetVelocity as you need.
*
* \param velocityFunc New custom velocity function
*
* \remark Passing an empty VelocityFunc has the same effect as calling ResetVelocityFunction
* \see ResetVelocityFunction
* \see UpdateVelocity
*/
inline void PhysicsComponent2D::SetVelocityFunction(VelocityFunc velocityFunc)
{
NazaraAssert(m_object, "Invalid physics object");
m_object->SetVelocityFunction(std::move(velocityFunc));
}
/*!
* \brief Calls the physics engine default velocity function
*
* \param gravity Physics system gravity
* \param damping Physics system damping (adjusted to deltaTime)
* \param deltaTime Elapsed time since last physics update
*/
inline void PhysicsComponent2D::UpdateVelocity(const Nz::Vector2f& gravity, float damping, float deltaTime)
{
NazaraAssert(m_object, "Invalid physics object");
m_object->UpdateVelocity(gravity, damping, deltaTime);
}
/*!
TODO
*/
inline void PhysicsComponent2D::Wakeup()
{
NazaraAssert(m_object, "Invalid physics object");
return m_object->Wakeup();
}
inline void PhysicsComponent2D::ApplyPhysicsState(Nz::RigidBody2D& rigidBody) const
{
assert(m_pendingStates.valid);
rigidBody.SetAngularVelocity(m_pendingStates.angularVelocity);
rigidBody.SetMass(m_pendingStates.mass);
rigidBody.SetMassCenter(m_pendingStates.massCenter);
rigidBody.SetMomentOfInertia(m_pendingStates.momentOfInertia);
rigidBody.SetVelocity(m_pendingStates.velocity);
rigidBody.SetVelocityFunction(m_pendingStates.velocityFunc);
for (std::size_t i = 0; i < m_pendingStates.shapes.size(); ++i)
{
auto& shapeData = m_pendingStates.shapes[i];
rigidBody.SetElasticity(i, shapeData.elasticity);
rigidBody.SetFriction(i, shapeData.friction);
rigidBody.SetSurfaceVelocity(i, shapeData.surfaceVelocity);
}
}
inline void PhysicsComponent2D::CopyPhysicsState(const Nz::RigidBody2D& rigidBody)
{
m_pendingStates.valid = true;
m_pendingStates.angularVelocity = rigidBody.GetAngularVelocity();
m_pendingStates.mass = rigidBody.GetMass();
m_pendingStates.massCenter = rigidBody.GetMassCenter();
m_pendingStates.momentOfInertia = rigidBody.GetMomentOfInertia();
m_pendingStates.velocity = rigidBody.GetVelocity();
m_pendingStates.velocityFunc = rigidBody.GetVelocityFunction();
m_pendingStates.shapes.resize(rigidBody.GetShapeCount());
for (std::size_t i = 0; i < m_pendingStates.shapes.size(); ++i)
{
auto& shapeData = m_pendingStates.shapes[i];
shapeData.elasticity = rigidBody.GetElasticity(i);
shapeData.friction = rigidBody.GetFriction(i);
shapeData.surfaceVelocity = rigidBody.GetSurfaceVelocity(i);
}
}
/*!
* \brief Gets the underlying physics object
* \return A reference to the physics object
*/
inline Nz::RigidBody2D* PhysicsComponent2D::GetRigidBody()
{
return m_object.get();
}
inline const Nz::RigidBody2D* PhysicsComponent2D::GetRigidBody() const
{
return m_object.get();
}
}

View File

@@ -0,0 +1,101 @@
// Copyright (C) 2017 Jérôme Leclercq
// This file is part of the "Nazara Development Kit"
// For conditions of distribution and use, see copyright notice in Prerequisites.hpp
#pragma once
#ifndef NDK_COMPONENTS_PHYSICSCOMPONENT3D_HPP
#define NDK_COMPONENTS_PHYSICSCOMPONENT3D_HPP
#include <Nazara/Physics3D/RigidBody3D.hpp>
#include <NazaraSDK/Component.hpp>
#include <memory>
namespace Ndk
{
class PhysicsComponent3D;
using PhysicsComponent3DHandle = Nz::ObjectHandle<PhysicsComponent3D>;
class NDK_API PhysicsComponent3D : public Component<PhysicsComponent3D>
{
friend class CollisionComponent3D;
friend class PhysicsSystem3D;
public:
inline PhysicsComponent3D();
PhysicsComponent3D(const PhysicsComponent3D& physics);
~PhysicsComponent3D() = default;
inline void AddForce(const Nz::Vector3f& force, Nz::CoordSys coordSys = Nz::CoordSys_Global);
inline void AddForce(const Nz::Vector3f& force, const Nz::Vector3f& point, Nz::CoordSys coordSys = Nz::CoordSys_Global);
inline void AddTorque(const Nz::Vector3f& torque, Nz::CoordSys coordSys = Nz::CoordSys_Global);
inline void EnableAutoSleep(bool autoSleep);
inline void EnableNodeSynchronization(bool nodeSynchronization);
inline Nz::Boxf GetAABB() const;
inline Nz::Vector3f GetAngularDamping() const;
inline Nz::Vector3f GetAngularVelocity() const;
inline float GetGravityFactor() const;
inline float GetLinearDamping() const;
inline Nz::Vector3f GetLinearVelocity() const;
inline float GetMass() const;
inline Nz::Vector3f GetMassCenter(Nz::CoordSys coordSys = Nz::CoordSys_Local) const;
inline const Nz::Matrix4f& GetMatrix() const;
inline Nz::Vector3f GetPosition() const;
inline Nz::Quaternionf GetRotation() const;
inline bool IsAutoSleepEnabled() const;
inline bool IsMoveable() const;
inline bool IsNodeSynchronizationEnabled() const;
inline bool IsSleeping() const;
inline void SetAngularDamping(const Nz::Vector3f& angularDamping);
inline void SetAngularVelocity(const Nz::Vector3f& angularVelocity);
inline void SetGravityFactor(float gravityFactor);
inline void SetLinearDamping(float damping);
inline void SetLinearVelocity(const Nz::Vector3f& velocity);
inline void SetMass(float mass);
inline void SetMassCenter(const Nz::Vector3f& center);
inline void SetMaterial(const Nz::String& materialName);
inline void SetMaterial(int materialIndex);
inline void SetPosition(const Nz::Vector3f& position);
inline void SetRotation(const Nz::Quaternionf& rotation);
static ComponentIndex componentIndex;
private:
inline void ApplyPhysicsState(Nz::RigidBody3D& rigidBody) const;
inline void CopyPhysicsState(const Nz::RigidBody3D& rigidBody);
inline Nz::RigidBody3D* GetRigidBody();
inline const Nz::RigidBody3D& GetRigidBody() const;
void OnAttached() override;
void OnComponentAttached(BaseComponent& component) override;
void OnComponentDetached(BaseComponent& component) override;
void OnDetached() override;
void OnEntityDestruction() override;
void OnEntityDisabled() override;
void OnEntityEnabled() override;
struct PendingPhysObjectStates
{
Nz::Vector3f angularDamping;
Nz::Vector3f massCenter;
bool autoSleep;
bool valid = false;
float gravityFactor;
float linearDamping;
float mass;
};
std::unique_ptr<Nz::RigidBody3D> m_object;
PendingPhysObjectStates m_pendingStates;
bool m_nodeSynchronizationEnabled;
};
}
#include <NazaraSDK/Components/PhysicsComponent3D.inl>
#endif // NDK_COMPONENTS_PHYSICSCOMPONENT3D_HPP

View File

@@ -0,0 +1,504 @@
// Copyright (C) 2017 Jérôme Leclercq
// This file is part of the "Nazara Development Kit"
// For conditions of distribution and use, see copyright notice in Prerequisites.hpp
#include <Nazara/Core/Error.hpp>
#include "PhysicsComponent3D.hpp"
namespace Ndk
{
inline PhysicsComponent3D::PhysicsComponent3D() :
m_nodeSynchronizationEnabled(true)
{
}
/*!
* \brief Constructs a PhysicsComponent3D object by copy semantic
*
* \param physics PhysicsComponent3D to copy
*/
inline PhysicsComponent3D::PhysicsComponent3D(const PhysicsComponent3D& physics) :
m_nodeSynchronizationEnabled(physics.m_nodeSynchronizationEnabled)
{
// We can't make a copy of the RigidBody3D, as we are not attached yet (and will possibly be attached to another world)
CopyPhysicsState(physics.GetRigidBody());
}
/*!
* \brief Applies a force to the entity
*
* \param force Force to apply on the entity
* \param coordSys System coordinates to consider
*
* \remark Produces a NazaraAssert if the physics object is invalid
*/
inline void PhysicsComponent3D::AddForce(const Nz::Vector3f& force, Nz::CoordSys coordSys)
{
NazaraAssert(m_object, "Invalid physics object");
m_object->AddForce(force, coordSys);
}
/*!
* \brief Applies a force to the entity
*
* \param force Force to apply on the entity
* \param point Point where to apply the force
* \param coordSys System coordinates to consider
*
* \remark Produces a NazaraAssert if the physics object is invalid
*/
inline void PhysicsComponent3D::AddForce(const Nz::Vector3f& force, const Nz::Vector3f& point, Nz::CoordSys coordSys)
{
NazaraAssert(m_object, "Invalid physics object");
m_object->AddForce(force, point, coordSys);
}
/*!
* \brief Applies a torque to the entity
*
* \param torque Torque to apply on the entity
* \param coordSys System coordinates to consider
*
* \remark Produces a NazaraAssert if the physics object is invalid
*/
inline void PhysicsComponent3D::AddTorque(const Nz::Vector3f& torque, Nz::CoordSys coordSys)
{
NazaraAssert(m_object, "Invalid physics object");
m_object->AddTorque(torque, coordSys);
}
/*!
* \brief Enables auto sleep of physics object
*
* \param autoSleep Should the physics of the object be disabled when too far from others
*
* \remark Produces a NazaraAssert if the physics object is invalid
*/
inline void PhysicsComponent3D::EnableAutoSleep(bool autoSleep)
{
NazaraAssert(m_object, "Invalid physics object");
m_object->EnableAutoSleep(autoSleep);
}
/*!
* \brief Enables position/rotation synchronization with the NodeComponent
*
* By default, at every update of the PhysicsSystem3D, the NodeComponent's position and rotation (if any) will be synchronized with
* the values of the PhysicsComponent3D. This function allows to enable/disable this behavior on a per-entity basis.
*
* \param nodeSynchronization Should synchronization occur between NodeComponent and PhysicsComponent3D
*/
inline void PhysicsComponent3D::EnableNodeSynchronization(bool nodeSynchronization)
{
m_nodeSynchronizationEnabled = nodeSynchronization;
if (m_entity)
m_entity->Invalidate();
}
/*!
* \brief Gets the AABB of the physics object
* \return AABB of the object
*
* \remark Produces a NazaraAssert if the physics object is invalid
*/
inline Nz::Boxf PhysicsComponent3D::GetAABB() const
{
NazaraAssert(m_object, "Invalid physics object");
return m_object->GetAABB();
}
/*!
* \brief Gets the angular damping of the physics object
* \return Angular damping of the object
*
* \remark Produces a NazaraAssert if the physics object is invalid
*/
inline Nz::Vector3f PhysicsComponent3D::GetAngularDamping() const
{
return m_object->GetAngularDamping();
}
/*!
* \brief Gets the angular velocity of the physics object
* \return Angular velocity of the object
*
* \remark Produces a NazaraAssert if the physics object is invalid
*/
inline Nz::Vector3f PhysicsComponent3D::GetAngularVelocity() const
{
NazaraAssert(m_object, "Invalid physics object");
return m_object->GetAngularVelocity();
}
/*!
* \brief Gets the gravity factor of the physics object
* \return Gravity factor of the object
*
* \remark Produces a NazaraAssert if the physics object is invalid
*/
inline float PhysicsComponent3D::GetGravityFactor() const
{
NazaraAssert(m_object, "Invalid physics object");
return m_object->GetGravityFactor();
}
/*!
* \brief Gets the linear damping of the physics object
* \return Linear damping of the object
*
* \remark Produces a NazaraAssert if the physics object is invalid
*/
inline float PhysicsComponent3D::GetLinearDamping() const
{
NazaraAssert(m_object, "Invalid physics object");
return m_object->GetLinearDamping();
}
/*!
* \brief Gets the linear velocity of the physics object
* \return Linear velocity of the object
*
* \remark Produces a NazaraAssert if the physics object is invalid
*/
inline Nz::Vector3f PhysicsComponent3D::GetLinearVelocity() const
{
NazaraAssert(m_object, "Invalid physics object");
return m_object->GetLinearVelocity();
}
/*!
* \brief Gets the mass of the physics object
* \return Mass of the object
*
* \remark Produces a NazaraAssert if the physics object is invalid
*/
inline float PhysicsComponent3D::GetMass() const
{
NazaraAssert(m_object, "Invalid physics object");
return m_object->GetMass();
}
/*!
* \brief Gets the gravity center of the physics object
* \return Gravity center of the object
*
* \param coordSys System coordinates to consider
*
* \remark Produces a NazaraAssert if the physics object is invalid
*/
inline Nz::Vector3f PhysicsComponent3D::GetMassCenter(Nz::CoordSys coordSys) const
{
NazaraAssert(m_object, "Invalid physics object");
return m_object->GetMassCenter(coordSys);
}
/*!
* \brief Gets the matrix of the physics object
* \return Matrix of the object
*
* \remark Produces a NazaraAssert if the physics object is invalid
*/
inline const Nz::Matrix4f& PhysicsComponent3D::GetMatrix() const
{
NazaraAssert(m_object, "Invalid physics object");
return m_object->GetMatrix();
}
/*!
* \brief Gets the position of the physics object
* \return Position of the object
*
* \remark Produces a NazaraAssert if the physics object is invalid
*/
inline Nz::Vector3f PhysicsComponent3D::GetPosition() const
{
NazaraAssert(m_object, "Invalid physics object");
return m_object->GetPosition();
}
/*!
* \brief Gets the rotation of the physics object
* \return Rotation of the object
*
* \remark Produces a NazaraAssert if the physics object is invalid
*/
inline Nz::Quaternionf PhysicsComponent3D::GetRotation() const
{
NazaraAssert(m_object, "Invalid physics object");
return m_object->GetRotation();
}
/*!
* \brief Checks whether the auto sleep is enabled
* \return true If it is the case
*
* \remark Produces a NazaraAssert if the physics object is invalid
*/
inline bool PhysicsComponent3D::IsAutoSleepEnabled() const
{
NazaraAssert(m_object, "Invalid physics object");
return m_object->IsAutoSleepEnabled();
}
/*!
* \brief Checks whether the object is moveable
* \return true If it is the case
*
* \remark Produces a NazaraAssert if the physics object is invalid
*/
inline bool PhysicsComponent3D::IsMoveable() const
{
NazaraAssert(m_object, "Invalid physics object");
return m_object->IsMoveable();
}
/*!
* \brief Checks if position & rotation are synchronized with NodeComponent
* \return true If synchronization is enabled
*
* \see EnableNodeSynchronization
*/
inline bool PhysicsComponent3D::IsNodeSynchronizationEnabled() const
{
return m_nodeSynchronizationEnabled;
}
/*!
* \brief Checks whether the entity is currently sleeping
* \return true If it is the case
*
* \remark Produces a NazaraAssert if the physics object is invalid
*/
inline bool PhysicsComponent3D::IsSleeping() const
{
NazaraAssert(m_object, "Invalid physics object");
return m_object->IsSleeping();
}
/*!
* \brief Sets the angular damping of the physics object
*
* \param angularDamping Angular damping of the object
*
* \remark Produces a NazaraAssert if the physics object is invalid
*/
inline void PhysicsComponent3D::SetAngularDamping(const Nz::Vector3f& angularDamping)
{
NazaraAssert(m_object, "Invalid physics object");
m_object->SetAngularDamping(angularDamping);
}
/*!
* \brief Sets the angular velocity of the physics object
*
* \param angularVelocity Angular velocity of the object
*
* \remark Produces a NazaraAssert if the physics object is invalid
*/
inline void PhysicsComponent3D::SetAngularVelocity(const Nz::Vector3f& angularVelocity)
{
NazaraAssert(m_object, "Invalid physics object");
m_object->SetAngularVelocity(angularVelocity);
}
/*!
* \brief Sets the gravity factor of the physics object
*
* \param gravityFactor Gravity factor of the object
*
* \remark Produces a NazaraAssert if the physics object is invalid
*/
inline void PhysicsComponent3D::SetGravityFactor(float gravityFactor)
{
NazaraAssert(m_object, "Invalid physics object");
m_object->SetGravityFactor(gravityFactor);
}
/*!
* \brief Sets the linear damping of the physics object
*
* \param damping Linear damping of the object
*
* \remark Produces a NazaraAssert if the physics object is invalid
*/
inline void PhysicsComponent3D::SetLinearDamping(float damping)
{
NazaraAssert(m_object, "Invalid physics object");
m_object->SetLinearDamping(damping);
}
/*!
* \brief Sets the linear velocity of the physics object
*
* \param velocity New linear velocity of the object
*
* \remark Produces a NazaraAssert if the physics object is invalid
*/
inline void PhysicsComponent3D::SetLinearVelocity(const Nz::Vector3f& velocity)
{
NazaraAssert(m_object, "Invalid physics object");
m_object->SetLinearVelocity(velocity);
}
/*!
* \brief Sets the mass of the physics object
*
* \param mass Mass of the object
*
* \remark Produces a NazaraAssert if the physics object is invalid
* \remark Produces a NazaraAssert if the mass is negative
*/
inline void PhysicsComponent3D::SetMass(float mass)
{
NazaraAssert(m_object, "Invalid physics object");
NazaraAssert(mass >= 0.f, "Mass must be positive and finite");
NazaraAssert(std::isfinite(mass), "Mass must be positive and finite");
m_object->SetMass(mass);
}
/*!
* \brief Sets the gravity center of the physics object
*
* \param center Gravity center of the object
*
* \remark Produces a NazaraAssert if the physics object is invalid
*/
inline void PhysicsComponent3D::SetMassCenter(const Nz::Vector3f& center)
{
NazaraAssert(m_object, "Invalid physics object");
m_object->SetMassCenter(center);
}
/*!
* \brief Sets the material of the object, affecting how object does respond to collisions
*
* \param materialName Name of the material, previously registered to physics world
*
* \remark materialName must exists in PhysWorld before this call
*/
inline void PhysicsComponent3D::SetMaterial(const Nz::String& materialName)
{
NazaraAssert(m_object, "Invalid physics object");
m_object->SetMaterial(materialName);
}
/*!
* \brief Sets the material of the object, affecting how object does respond to collisions
*
* \param materialIndex Id of the material, previously retrieved from a physics world
*
* \remark materialIndex must come from a call to in PhysWorld::CreateMaterial
*/
inline void PhysicsComponent3D::SetMaterial(int materialIndex)
{
NazaraAssert(m_object, "Invalid physics object");
m_object->SetMaterial(materialIndex);
}
/*!
* \brief Sets the position of the physics object
*
* \param position Position of the object
*
* \remark Produces a NazaraAssert if the physics object is invalid
*/
inline void PhysicsComponent3D::SetPosition(const Nz::Vector3f& position)
{
NazaraAssert(m_object, "Invalid physics object");
m_object->SetPosition(position);
}
/*!
* \brief Sets the rotation of the physics object
*
* \param rotation Rotation of the object
*
* \remark Produces a NazaraAssert if the physics object is invalid
*/
inline void PhysicsComponent3D::SetRotation(const Nz::Quaternionf& rotation)
{
NazaraAssert(m_object, "Invalid physics object");
m_object->SetRotation(rotation);
}
inline void PhysicsComponent3D::ApplyPhysicsState(Nz::RigidBody3D& rigidBody) const
{
assert(m_pendingStates.valid);
rigidBody.EnableAutoSleep(m_pendingStates.autoSleep);
rigidBody.SetAngularDamping(m_pendingStates.angularDamping);
rigidBody.SetGravityFactor(m_pendingStates.gravityFactor);
rigidBody.SetLinearDamping(m_pendingStates.linearDamping);
rigidBody.SetMass(m_pendingStates.mass);
rigidBody.SetMassCenter(m_pendingStates.massCenter);
}
inline void PhysicsComponent3D::CopyPhysicsState(const Nz::RigidBody3D& rigidBody)
{
m_pendingStates.autoSleep = rigidBody.IsAutoSleepEnabled();
m_pendingStates.angularDamping = rigidBody.GetAngularDamping();
m_pendingStates.gravityFactor = rigidBody.GetGravityFactor();
m_pendingStates.linearDamping = rigidBody.GetLinearDamping();
m_pendingStates.mass = rigidBody.GetMass();
m_pendingStates.massCenter = rigidBody.GetMassCenter(Nz::CoordSys_Local);
m_pendingStates.valid = true;
}
/*!
* \brief Gets the underlying physics object
* \return A reference to the physics object
*/
inline Nz::RigidBody3D* PhysicsComponent3D::GetRigidBody()
{
return m_object.get();
}
/*!
* \brief Gets the underlying physics object
* \return A reference to the physics object
*/
inline const Nz::RigidBody3D& PhysicsComponent3D::GetRigidBody() const
{
return *m_object.get();
}
}

View File

@@ -0,0 +1,36 @@
// Copyright (C) 2017 Jérôme Leclercq
// This file is part of the "Nazara Development Kit"
// For conditions of distribution and use, see copyright notice in Prerequisites.hpp
#pragma once
#ifndef NDK_COMPONENTS_VELOCITYCOMPONENT_HPP
#define NDK_COMPONENTS_VELOCITYCOMPONENT_HPP
#include <Nazara/Math/Vector3.hpp>
#include <NazaraSDK/Component.hpp>
namespace Ndk
{
class VelocityComponent;
using VelocityComponentHandle = Nz::ObjectHandle<VelocityComponent>;
class NDK_API VelocityComponent : public Component<VelocityComponent>
{
public:
VelocityComponent(const Nz::Vector3f& velocity = Nz::Vector3f::Zero(), Nz::CoordSys coordSystem = Nz::CoordSys_Global);
~VelocityComponent() = default;
Nz::Vector3f linearVelocity;
Nz::CoordSys coordSys;
VelocityComponent& operator=(const Nz::Vector3f& vel);
static ComponentIndex componentIndex;
};
}
#include <NazaraSDK/Components/VelocityComponent.inl>
#endif // NDK_COMPONENTS_VELOCITYCOMPONENT_HPP

View File

@@ -0,0 +1,37 @@
// Copyright (C) 2017 Jérôme Leclercq
// This file is part of the "Nazara Development Kit"
// For conditions of distribution and use, see copyright notice in Prerequisites.hpp
namespace Ndk
{
/*!
* \ingroup NDK
* \class Ndk::VelocityComponent
* \brief NDK class that represents the component for velocity
*/
/*!
* \brief Constructs a VelocityComponent object with a velocity
*
* \param velocity Linear velocity
*/
inline VelocityComponent::VelocityComponent(const Nz::Vector3f& velocity, Nz::CoordSys coordSystem) :
linearVelocity(velocity),
coordSys(coordSystem)
{
}
/*!
* \brief Assigns the velocity to this component
* \return A reference to this
*
* \param vel Linear velocity
*/
inline VelocityComponent& VelocityComponent::operator=(const Nz::Vector3f& vel)
{
linearVelocity = vel;
return *this;
}
}