Merge branch 'master' into console-widget
This commit is contained in:
@@ -11,6 +11,7 @@
|
||||
#include <NDK/Components/ConstraintComponent2D.hpp>
|
||||
#include <NDK/Components/DebugComponent.hpp>
|
||||
#include <NDK/Components/GraphicsComponent.hpp>
|
||||
#include <NDK/Components/LifetimeComponent.hpp>
|
||||
#include <NDK/Components/LightComponent.hpp>
|
||||
#include <NDK/Components/ListenerComponent.hpp>
|
||||
#include <NDK/Components/NodeComponent.hpp>
|
||||
|
||||
@@ -20,8 +20,9 @@ namespace Ndk
|
||||
|
||||
class NDK_API CollisionComponent2D : public Component<CollisionComponent2D>
|
||||
{
|
||||
friend class PhysicsSystem2D;
|
||||
friend class ConstraintComponent2D;
|
||||
friend class PhysicsComponent2D;
|
||||
friend class PhysicsSystem2D;
|
||||
|
||||
public:
|
||||
CollisionComponent2D(Nz::Collider2DRef geom = Nz::Collider2DRef());
|
||||
@@ -30,8 +31,12 @@ namespace Ndk
|
||||
|
||||
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;
|
||||
@@ -40,7 +45,10 @@ namespace Ndk
|
||||
|
||||
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;
|
||||
|
||||
@@ -28,16 +28,6 @@ namespace Ndk
|
||||
{
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Gets the collision box representing the entity
|
||||
* \return The physics collision box
|
||||
*/
|
||||
|
||||
inline Nz::Rectf CollisionComponent2D::GetAABB() const
|
||||
{
|
||||
return m_staticBody->GetAABB();
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Gets the geometry representing the entity
|
||||
* \return A constant reference to the physics geometry
|
||||
@@ -62,13 +52,13 @@ namespace Ndk
|
||||
return *this;
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Gets the static body used by the entity
|
||||
* \return A pointer to the entity
|
||||
*/
|
||||
|
||||
inline Nz::RigidBody2D* CollisionComponent2D::GetStaticBody()
|
||||
{
|
||||
return m_staticBody.get();
|
||||
}
|
||||
|
||||
inline const Nz::RigidBody2D* CollisionComponent2D::GetStaticBody() const
|
||||
{
|
||||
return m_staticBody.get();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -16,7 +16,7 @@ namespace Ndk
|
||||
{
|
||||
enum class DebugDraw
|
||||
{
|
||||
//TODO: Collider2D
|
||||
Collider2D,
|
||||
Collider3D,
|
||||
GraphicsAABB,
|
||||
GraphicsOBB,
|
||||
|
||||
40
SDK/include/NDK/Components/LifetimeComponent.hpp
Normal file
40
SDK/include/NDK/Components/LifetimeComponent.hpp
Normal 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 <NDK/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 <NDK/Components/LifetimeComponent.inl>
|
||||
|
||||
#endif // NDK_COMPONENTS_LIFETIMECOMPONENT_HPP
|
||||
24
SDK/include/NDK/Components/LifetimeComponent.inl
Normal file
24
SDK/include/NDK/Components/LifetimeComponent.inl
Normal 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 <NDK/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;
|
||||
}
|
||||
}
|
||||
@@ -24,6 +24,8 @@ namespace Ndk
|
||||
friend class ConstraintComponent2D;
|
||||
|
||||
public:
|
||||
using VelocityFunc = Nz::RigidBody2D::VelocityFunc;
|
||||
|
||||
PhysicsComponent2D();
|
||||
PhysicsComponent2D(const PhysicsComponent2D& physics);
|
||||
~PhysicsComponent2D() = default;
|
||||
@@ -38,6 +40,8 @@ namespace Ndk
|
||||
|
||||
inline void EnableNodeSynchronization(bool nodeSynchronization);
|
||||
|
||||
inline void ForEachArbiter(const std::function<void(Nz::Arbiter2D&)>& callback);
|
||||
|
||||
inline Nz::Rectf GetAABB() const;
|
||||
inline float GetAngularDamping() const;
|
||||
inline Nz::RadianAnglef GetAngularVelocity() const;
|
||||
@@ -53,9 +57,13 @@ namespace Ndk
|
||||
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);
|
||||
@@ -71,6 +79,9 @@ namespace Ndk
|
||||
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);
|
||||
|
||||
static ComponentIndex componentIndex;
|
||||
|
||||
|
||||
@@ -138,6 +138,15 @@ namespace Ndk
|
||||
m_entity->Invalidate();
|
||||
}
|
||||
|
||||
/*!
|
||||
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
|
||||
@@ -329,7 +338,6 @@ namespace Ndk
|
||||
*
|
||||
* \remark Produces a NazaraAssert if the physics object is invalid
|
||||
*/
|
||||
|
||||
inline Nz::Vector2f PhysicsComponent2D::GetVelocity() const
|
||||
{
|
||||
NazaraAssert(m_object, "Invalid physics object");
|
||||
@@ -337,6 +345,19 @@ namespace Ndk
|
||||
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
|
||||
@@ -361,6 +382,30 @@ namespace Ndk
|
||||
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
|
||||
*
|
||||
@@ -571,6 +616,39 @@ namespace Ndk
|
||||
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);
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Gets the underlying physics object
|
||||
* \return A reference to the physics object
|
||||
|
||||
@@ -19,10 +19,11 @@ namespace Ndk
|
||||
class NDK_API VelocityComponent : public Component<VelocityComponent>
|
||||
{
|
||||
public:
|
||||
VelocityComponent(const Nz::Vector3f& velocity = Nz::Vector3f::Zero());
|
||||
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);
|
||||
|
||||
|
||||
@@ -16,8 +16,9 @@ namespace Ndk
|
||||
* \param velocity Linear velocity
|
||||
*/
|
||||
|
||||
inline VelocityComponent::VelocityComponent(const Nz::Vector3f& velocity) :
|
||||
linearVelocity(velocity)
|
||||
inline VelocityComponent::VelocityComponent(const Nz::Vector3f& velocity, Nz::CoordSys coordSystem) :
|
||||
linearVelocity(velocity),
|
||||
coordSys(coordSystem)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
@@ -159,8 +159,13 @@ namespace Ndk
|
||||
*/
|
||||
inline bool StateMachine::Update(float elapsedTime)
|
||||
{
|
||||
for (StateTransition& transition : m_transitions)
|
||||
// Use a classic for instead of a range-for because some state may push/pop on enter/leave, adding new transitions as we iterate
|
||||
// (range-for is a problem here because it doesn't handle mutable containers)
|
||||
|
||||
for (std::size_t i = 0; i < m_transitions.size(); ++i)
|
||||
{
|
||||
StateTransition& transition = m_transitions[i];
|
||||
|
||||
switch (transition.type)
|
||||
{
|
||||
case TransitionType::Pop:
|
||||
|
||||
@@ -6,6 +6,7 @@
|
||||
#define NDK_SYSTEMS_GLOBAL_HPP
|
||||
|
||||
#include <NDK/Systems/DebugSystem.hpp>
|
||||
#include <NDK/Systems/LifetimeSystem.hpp>
|
||||
#include <NDK/Systems/ListenerSystem.hpp>
|
||||
#include <NDK/Systems/ParticleSystem.hpp>
|
||||
#include <NDK/Systems/PhysicsSystem2D.hpp>
|
||||
|
||||
@@ -26,6 +26,7 @@ namespace Ndk
|
||||
|
||||
private:
|
||||
Nz::InstancedRenderableRef GenerateBox(Nz::Boxf box);
|
||||
Nz::InstancedRenderableRef GenerateCollision2DMesh(Entity* entity, Nz::Vector3f* offset);
|
||||
Nz::InstancedRenderableRef GenerateCollision3DMesh(Entity* entity);
|
||||
|
||||
Nz::MaterialRef GetCollisionMaterial();
|
||||
|
||||
29
SDK/include/NDK/Systems/LifetimeSystem.hpp
Normal file
29
SDK/include/NDK/Systems/LifetimeSystem.hpp
Normal file
@@ -0,0 +1,29 @@
|
||||
// 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_SYSTEMS_LIFETIMESYSTEM_HPP
|
||||
#define NDK_SYSTEMS_LIFETIMESYSTEM_HPP
|
||||
|
||||
#include <NDK/System.hpp>
|
||||
|
||||
namespace Ndk
|
||||
{
|
||||
class NDK_API LifetimeSystem : public System<LifetimeSystem>
|
||||
{
|
||||
public:
|
||||
LifetimeSystem();
|
||||
~LifetimeSystem() = default;
|
||||
|
||||
static SystemIndex systemIndex;
|
||||
|
||||
private:
|
||||
void OnUpdate(float elapsedTime) override;
|
||||
};
|
||||
}
|
||||
|
||||
#include <NDK/Systems/LifetimeSystem.inl>
|
||||
|
||||
#endif // NDK_SYSTEMS_LIFETIMESYSTEM_HPP
|
||||
3
SDK/include/NDK/Systems/LifetimeSystem.inl
Normal file
3
SDK/include/NDK/Systems/LifetimeSystem.inl
Normal file
@@ -0,0 +1,3 @@
|
||||
// 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
|
||||
@@ -51,9 +51,11 @@ namespace Ndk
|
||||
bool NearestBodyQuery(const Nz::Vector2f& from, float maxDistance, Nz::UInt32 collisionGroup, Nz::UInt32 categoryMask, Nz::UInt32 collisionMask, EntityHandle* nearestBody = nullptr);
|
||||
bool NearestBodyQuery(const Nz::Vector2f& from, float maxDistance, Nz::UInt32 collisionGroup, Nz::UInt32 categoryMask, Nz::UInt32 collisionMask, NearestQueryResult* result);
|
||||
|
||||
void RaycastQuery(const Nz::Vector2f& from, const Nz::Vector2f& to, float radius, Nz::UInt32 collisionGroup, Nz::UInt32 categoryMask, Nz::UInt32 collisionMask, const std::function<void(const RaycastHit&)>& callback);
|
||||
bool RaycastQuery(const Nz::Vector2f& from, const Nz::Vector2f& to, float radius, Nz::UInt32 collisionGroup, Nz::UInt32 categoryMask, Nz::UInt32 collisionMask, std::vector<RaycastHit>* hitInfos);
|
||||
bool RaycastQueryFirst(const Nz::Vector2f& from, const Nz::Vector2f& to, float radius, Nz::UInt32 collisionGroup, Nz::UInt32 categoryMask, Nz::UInt32 collisionMask, RaycastHit* hitInfo = nullptr);
|
||||
|
||||
void RegionQuery(const Nz::Rectf& boundingBox, Nz::UInt32 collisionGroup, Nz::UInt32 categoryMask, Nz::UInt32 collisionMask, const std::function<void(const EntityHandle&)>& callback);
|
||||
void RegionQuery(const Nz::Rectf& boundingBox, Nz::UInt32 collisionGroup, Nz::UInt32 categoryMask, Nz::UInt32 collisionMask, std::vector<EntityHandle>* bodies);
|
||||
|
||||
void RegisterCallbacks(unsigned int collisionId, Callback callbacks);
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
#ifndef NDK_WIDGETS_GLOBAL_HPP
|
||||
#define NDK_WIDGETS_GLOBAL_HPP
|
||||
|
||||
#include <NDK/Widgets/BoxLayout.hpp>
|
||||
#include <NDK/Widgets/ButtonWidget.hpp>
|
||||
#include <NDK/Widgets/CheckboxWidget.hpp>
|
||||
#include <NDK/Widgets/Enums.hpp>
|
||||
|
||||
@@ -50,6 +50,8 @@ namespace Ndk
|
||||
inline std::size_t GetGlyphIndex(const Nz::Vector2ui& cursorPosition) const;
|
||||
inline const Nz::String& GetText() const;
|
||||
inline const Nz::Color& GetTextColor() const;
|
||||
inline const Nz::Color& GetTextOulineColor() const;
|
||||
inline float GetTextOulineThickness() const;
|
||||
|
||||
Nz::Vector2ui GetHoveredGlyph(float x, float y) const;
|
||||
|
||||
@@ -71,6 +73,8 @@ namespace Ndk
|
||||
inline void SetSelection(Nz::Vector2ui fromPosition, Nz::Vector2ui toPosition);
|
||||
inline void SetText(const Nz::String& text);
|
||||
inline void SetTextColor(const Nz::Color& text);
|
||||
inline void SetTextOutlineColor(const Nz::Color& color);
|
||||
inline void SetTextOutlineThickness(float thickness);
|
||||
|
||||
inline void Write(const Nz::String& text);
|
||||
inline void Write(const Nz::String& text, const Nz::Vector2ui& glyphPosition);
|
||||
|
||||
@@ -107,6 +107,16 @@ namespace Ndk
|
||||
return m_drawer.GetColor();
|
||||
}
|
||||
|
||||
inline const Nz::Color& TextAreaWidget::GetTextOulineColor() const
|
||||
{
|
||||
return m_drawer.GetOutlineColor();
|
||||
}
|
||||
|
||||
inline float TextAreaWidget::GetTextOulineThickness() const
|
||||
{
|
||||
return m_drawer.GetOutlineThickness();
|
||||
}
|
||||
|
||||
inline bool TextAreaWidget::HasSelection() const
|
||||
{
|
||||
return m_cursorPositionBegin != m_cursorPositionEnd;
|
||||
@@ -246,7 +256,21 @@ namespace Ndk
|
||||
{
|
||||
m_drawer.SetColor(text);
|
||||
|
||||
m_textSprite->Update(m_drawer);
|
||||
UpdateDisplayText();
|
||||
}
|
||||
|
||||
inline void TextAreaWidget::SetTextOutlineColor(const Nz::Color& color)
|
||||
{
|
||||
m_drawer.SetOutlineColor(color);
|
||||
|
||||
UpdateDisplayText();
|
||||
}
|
||||
|
||||
inline void TextAreaWidget::SetTextOutlineThickness(float thickness)
|
||||
{
|
||||
m_drawer.SetOutlineThickness(thickness);
|
||||
|
||||
UpdateDisplayText();
|
||||
}
|
||||
|
||||
inline void TextAreaWidget::Write(const Nz::String& text)
|
||||
|
||||
@@ -98,6 +98,12 @@ namespace Ndk
|
||||
inline void InvalidateSystemOrder();
|
||||
void ReorderSystems();
|
||||
|
||||
struct DoubleBitset
|
||||
{
|
||||
Nz::Bitset<Nz::UInt64> front;
|
||||
Nz::Bitset<Nz::UInt64> back;
|
||||
};
|
||||
|
||||
struct EntityBlock
|
||||
{
|
||||
EntityBlock(Entity&& e) :
|
||||
@@ -119,9 +125,9 @@ namespace Ndk
|
||||
std::vector<std::unique_ptr<EntityBlock>> m_waitingEntities;
|
||||
EntityList m_aliveEntities;
|
||||
ProfilerData m_profilerData;
|
||||
Nz::Bitset<Nz::UInt64> m_dirtyEntities;
|
||||
DoubleBitset m_dirtyEntities;
|
||||
Nz::Bitset<Nz::UInt64> m_freeEntityIds;
|
||||
Nz::Bitset<Nz::UInt64> m_killedEntities;
|
||||
DoubleBitset m_killedEntities;
|
||||
bool m_orderedSystemsUpdated;
|
||||
bool m_isProfilerEnabled;
|
||||
};
|
||||
|
||||
@@ -308,7 +308,7 @@ namespace Ndk
|
||||
inline void World::KillEntity(Entity* entity)
|
||||
{
|
||||
if (IsEntityValid(entity))
|
||||
m_killedEntities.UnboundedSet(entity->GetId(), true);
|
||||
m_killedEntities.front.UnboundedSet(entity->GetId(), true);
|
||||
}
|
||||
|
||||
/*!
|
||||
@@ -343,7 +343,7 @@ namespace Ndk
|
||||
*/
|
||||
inline bool World::IsEntityDying(EntityId id) const
|
||||
{
|
||||
return m_killedEntities.UnboundedTest(id);
|
||||
return m_killedEntities.front.UnboundedTest(id);
|
||||
}
|
||||
|
||||
/*!
|
||||
@@ -467,13 +467,13 @@ namespace Ndk
|
||||
|
||||
inline void World::Invalidate()
|
||||
{
|
||||
m_dirtyEntities.Resize(m_entityBlocks.size(), false);
|
||||
m_dirtyEntities.Set(true); // Activation of all bits
|
||||
m_dirtyEntities.front.Resize(m_entityBlocks.size(), false);
|
||||
m_dirtyEntities.front.Set(true); // Activation of all bits
|
||||
}
|
||||
|
||||
inline void World::Invalidate(EntityId id)
|
||||
{
|
||||
m_dirtyEntities.UnboundedSet(id, true);
|
||||
m_dirtyEntities.front.UnboundedSet(id, true);
|
||||
}
|
||||
|
||||
inline void World::InvalidateSystemOrder()
|
||||
|
||||
@@ -89,6 +89,7 @@ namespace Ndk
|
||||
}
|
||||
else
|
||||
{
|
||||
DestroyEntity(m_backgroundEntity);
|
||||
m_backgroundEntity.Reset();
|
||||
m_backgroundSprite.Reset();
|
||||
}
|
||||
@@ -185,7 +186,7 @@ namespace Ndk
|
||||
|
||||
void BaseWidget::Layout()
|
||||
{
|
||||
if (m_backgroundEntity)
|
||||
if (m_backgroundSprite)
|
||||
m_backgroundSprite->SetSize(m_size.x, m_size.y);
|
||||
|
||||
UpdatePositionAndSize();
|
||||
|
||||
@@ -17,28 +17,57 @@ namespace Ndk
|
||||
* \brief NDK class that represents a two-dimensional collision geometry
|
||||
*/
|
||||
|
||||
/*!
|
||||
* \brief Gets the collision box representing the entity
|
||||
* \return The physics collision box
|
||||
*/
|
||||
Nz::Rectf CollisionComponent2D::GetAABB() const
|
||||
{
|
||||
return GetRigidBody()->GetAABB();
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Gets the position offset between the actual rigid body center of mass position and the origin of the geometry
|
||||
* \return Position offset
|
||||
*/
|
||||
const Nz::Vector2f& CollisionComponent2D::GetGeomOffset() const
|
||||
{
|
||||
return GetRigidBody()->GetPositionOffset();
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Convenience function to align center of geometry to a specific point
|
||||
*
|
||||
* \param geomOffset Position offset
|
||||
*
|
||||
* \remark This does not change the center of mass
|
||||
*/
|
||||
void CollisionComponent2D::Recenter(const Nz::Vector2f& origin)
|
||||
{
|
||||
const Nz::RigidBody2D* rigidBody = GetRigidBody();
|
||||
SetGeomOffset(origin - rigidBody->GetAABB().GetCenter() + rigidBody->GetPositionOffset());
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Sets geometry for the entity
|
||||
*
|
||||
* \param geom Geometry used for collisions
|
||||
*
|
||||
* \remark Produces a NazaraAssert if the entity has no physics component and has no static body
|
||||
*/
|
||||
void CollisionComponent2D::SetGeom(Nz::Collider2DRef geom)
|
||||
{
|
||||
m_geom = std::move(geom);
|
||||
|
||||
if (m_entity->HasComponent<PhysicsComponent2D>())
|
||||
{
|
||||
// We update the geometry of the PhysiscsObject linked to the PhysicsComponent2D
|
||||
PhysicsComponent2D& physComponent = m_entity->GetComponent<PhysicsComponent2D>();
|
||||
physComponent.GetRigidBody()->SetGeom(m_geom);
|
||||
}
|
||||
else
|
||||
{
|
||||
NazaraAssert(m_staticBody, "An entity without physics component should have a static body");
|
||||
m_staticBody->SetGeom(m_geom);
|
||||
}
|
||||
GetRigidBody()->SetGeom(m_geom);
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Sets the position offset between the actual rigid body center of mass position and the origin of the geometry
|
||||
*
|
||||
* \param geomOffset Position offset
|
||||
*/
|
||||
void CollisionComponent2D::SetGeomOffset(const Nz::Vector2f& geomOffset)
|
||||
{
|
||||
GetRigidBody()->SetPositionOffset(geomOffset);
|
||||
}
|
||||
|
||||
/*!
|
||||
@@ -47,7 +76,6 @@ namespace Ndk
|
||||
* \remark Produces a NazaraAssert if entity is invalid
|
||||
* \remark Produces a NazaraAssert if entity is not linked to a world, or the world has no physics system
|
||||
*/
|
||||
|
||||
void CollisionComponent2D::InitializeStaticBody()
|
||||
{
|
||||
NazaraAssert(m_entity, "Invalid entity");
|
||||
@@ -67,7 +95,34 @@ namespace Ndk
|
||||
matrix.MakeIdentity();
|
||||
|
||||
m_staticBody->SetPosition(Nz::Vector2f(matrix.GetTranslation()));
|
||||
}
|
||||
|
||||
Nz::RigidBody2D* CollisionComponent2D::GetRigidBody()
|
||||
{
|
||||
if (m_entity->HasComponent<PhysicsComponent2D>())
|
||||
{
|
||||
PhysicsComponent2D& physComponent = m_entity->GetComponent<PhysicsComponent2D>();
|
||||
return physComponent.GetRigidBody();
|
||||
}
|
||||
else
|
||||
{
|
||||
NazaraAssert(m_staticBody, "An entity without physics component should have a static body");
|
||||
return m_staticBody.get();
|
||||
}
|
||||
}
|
||||
|
||||
const Nz::RigidBody2D* CollisionComponent2D::GetRigidBody() const
|
||||
{
|
||||
if (m_entity->HasComponent<PhysicsComponent2D>())
|
||||
{
|
||||
PhysicsComponent2D& physComponent = m_entity->GetComponent<PhysicsComponent2D>();
|
||||
return physComponent.GetRigidBody();
|
||||
}
|
||||
else
|
||||
{
|
||||
NazaraAssert(m_staticBody, "An entity without physics component should have a static body");
|
||||
return m_staticBody.get();
|
||||
}
|
||||
}
|
||||
|
||||
/*!
|
||||
|
||||
@@ -124,9 +124,11 @@ namespace Ndk
|
||||
|
||||
const Nz::MaterialRef& oldMat = renderable->GetMaterial(skinIndex, matIndex);
|
||||
UnregisterMaterial(oldMat);
|
||||
|
||||
ForceCullingInvalidation();
|
||||
}
|
||||
|
||||
void Ndk::GraphicsComponent::InvalidateReflectionMap()
|
||||
void GraphicsComponent::InvalidateReflectionMap()
|
||||
{
|
||||
m_entity->Invalidate();
|
||||
|
||||
@@ -230,6 +232,8 @@ namespace Ndk
|
||||
std::size_t materialCount = renderable->GetMaterialCount();
|
||||
for (std::size_t i = 0; i < materialCount; ++i)
|
||||
UnregisterMaterial(renderable->GetMaterial(i));
|
||||
|
||||
ForceCullingInvalidation();
|
||||
}
|
||||
|
||||
void GraphicsComponent::OnInstancedRenderableSkinChange(const Nz::InstancedRenderable* renderable, std::size_t newSkinIndex)
|
||||
@@ -240,6 +244,8 @@ namespace Ndk
|
||||
|
||||
for (std::size_t i = 0; i < materialCount; ++i)
|
||||
UnregisterMaterial(renderable->GetMaterial(i));
|
||||
|
||||
ForceCullingInvalidation();
|
||||
}
|
||||
|
||||
void GraphicsComponent::OnMaterialReflectionChange(const Nz::Material* material, Nz::ReflectionMode reflectionMode)
|
||||
@@ -297,6 +303,9 @@ namespace Ndk
|
||||
RenderSystem& renderSystem = m_entity->GetWorld()->GetSystem<RenderSystem>();
|
||||
|
||||
m_aabb.Set(-1.f, -1.f, -1.f);
|
||||
|
||||
bool isAabbSet = false;
|
||||
|
||||
for (const Renderable& r : m_renderables)
|
||||
{
|
||||
r.boundingVolume = r.renderable->GetBoundingVolume();
|
||||
@@ -305,10 +314,13 @@ namespace Ndk
|
||||
{
|
||||
r.boundingVolume.Update(r.data.transformMatrix);
|
||||
|
||||
if (m_aabb.IsValid())
|
||||
if (isAabbSet)
|
||||
m_aabb.ExtendTo(r.boundingVolume.aabb);
|
||||
else
|
||||
{
|
||||
m_aabb.Set(r.boundingVolume.aabb);
|
||||
isAabbSet = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
10
SDK/src/NDK/Components/LifetimeComponent.cpp
Normal file
10
SDK/src/NDK/Components/LifetimeComponent.cpp
Normal file
@@ -0,0 +1,10 @@
|
||||
// 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 <NDK/Components/LifetimeComponent.hpp>
|
||||
|
||||
namespace Ndk
|
||||
{
|
||||
ComponentIndex LifetimeComponent::componentIndex;
|
||||
}
|
||||
@@ -31,9 +31,17 @@ namespace Ndk
|
||||
|
||||
Nz::PhysWorld2D& world = entityWorld->GetSystem<PhysicsSystem2D>().GetPhysWorld();
|
||||
|
||||
Nz::Vector2f positionOffset;
|
||||
|
||||
Nz::Collider2DRef geom;
|
||||
if (m_entity->HasComponent<CollisionComponent2D>())
|
||||
geom = m_entity->GetComponent<CollisionComponent2D>().GetGeom();
|
||||
{
|
||||
const CollisionComponent2D& entityCollision = m_entity->GetComponent<CollisionComponent2D>();
|
||||
geom = entityCollision.GetGeom();
|
||||
positionOffset = entityCollision.GetStaticBody()->GetPositionOffset(); //< Calling GetGeomOffset would retrieve current component which is not yet initialized
|
||||
}
|
||||
else
|
||||
positionOffset = Nz::Vector2f::Zero();
|
||||
|
||||
Nz::Matrix4f matrix;
|
||||
if (m_entity->HasComponent<NodeComponent>())
|
||||
@@ -42,6 +50,7 @@ namespace Ndk
|
||||
matrix.MakeIdentity();
|
||||
|
||||
m_object = std::make_unique<Nz::RigidBody2D>(&world, 1.f, geom);
|
||||
m_object->SetPositionOffset(positionOffset);
|
||||
m_object->SetPosition(Nz::Vector2f(matrix.GetTranslation()));
|
||||
m_object->SetUserdata(reinterpret_cast<void*>(static_cast<std::ptrdiff_t>(m_entity->GetId())));
|
||||
}
|
||||
|
||||
@@ -123,12 +123,13 @@ namespace Ndk
|
||||
lua.Push(instance->GetCachedGlyphCount());
|
||||
return 1;
|
||||
|
||||
case 2:
|
||||
case 3:
|
||||
{
|
||||
unsigned int characterSize = lua.Check<unsigned int>(&argIndex);
|
||||
Nz::UInt32 style = lua.Check<Nz::UInt32>(&argIndex);
|
||||
Nz::TextStyleFlags style = lua.Check<Nz::TextStyleFlags>(&argIndex);
|
||||
float outlineThickness = lua.Check<float>(&argIndex);
|
||||
|
||||
lua.Push(instance->GetCachedGlyphCount(characterSize, style));
|
||||
lua.Push(instance->GetCachedGlyphCount(characterSize, style, outlineThickness));
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
@@ -146,7 +147,7 @@ namespace Ndk
|
||||
|
||||
font.BindMethod("IsValid", &Nz::Font::IsValid);
|
||||
|
||||
font.BindMethod("Precache", (bool(Nz::Font::*)(unsigned int, Nz::UInt32, const Nz::String&) const) &Nz::Font::Precache);
|
||||
font.BindMethod("Precache", (bool(Nz::Font::*)(unsigned int, Nz::TextStyleFlags, float, const Nz::String&) const) &Nz::Font::Precache);
|
||||
|
||||
font.BindMethod("SetGlyphBorder", &Nz::Font::SetGlyphBorder);
|
||||
font.BindMethod("SetMinimumStepSize", &Nz::Font::SetMinimumStepSize);
|
||||
|
||||
@@ -17,11 +17,13 @@
|
||||
#include <NDK/BaseSystem.hpp>
|
||||
#include <NDK/Components/CollisionComponent2D.hpp>
|
||||
#include <NDK/Components/CollisionComponent3D.hpp>
|
||||
#include <NDK/Components/LifetimeComponent.hpp>
|
||||
#include <NDK/Components/NodeComponent.hpp>
|
||||
#include <NDK/Components/PhysicsComponent2D.hpp>
|
||||
#include <NDK/Components/PhysicsComponent3D.hpp>
|
||||
#include <NDK/Components/VelocityComponent.hpp>
|
||||
#include <NDK/Components/ConstraintComponent2D.hpp>
|
||||
#include <NDK/Systems/LifetimeSystem.hpp>
|
||||
#include <NDK/Systems/PhysicsSystem2D.hpp>
|
||||
#include <NDK/Systems/PhysicsSystem3D.hpp>
|
||||
#include <NDK/Systems/VelocitySystem.hpp>
|
||||
@@ -88,6 +90,7 @@ namespace Ndk
|
||||
// Shared components
|
||||
InitializeComponent<CollisionComponent2D>("NdkColl2");
|
||||
InitializeComponent<CollisionComponent3D>("NdkColl3");
|
||||
InitializeComponent<LifetimeComponent>("NdkLiftm");
|
||||
InitializeComponent<NodeComponent>("NdkNode");
|
||||
InitializeComponent<PhysicsComponent2D>("NdkPhys2");
|
||||
InitializeComponent<PhysicsComponent3D>("NdkPhys3");
|
||||
@@ -110,6 +113,7 @@ namespace Ndk
|
||||
BaseSystem::Initialize();
|
||||
|
||||
// Shared systems
|
||||
InitializeSystem<LifetimeSystem>();
|
||||
InitializeSystem<PhysicsSystem2D>();
|
||||
InitializeSystem<PhysicsSystem3D>();
|
||||
InitializeSystem<VelocitySystem>();
|
||||
|
||||
@@ -8,10 +8,12 @@
|
||||
#include <Nazara/Utility/IndexIterator.hpp>
|
||||
#include <Nazara/Utility/Mesh.hpp>
|
||||
#include <Nazara/Utility/StaticMesh.hpp>
|
||||
#include <NDK/Components/CollisionComponent2D.hpp>
|
||||
#include <NDK/Components/CollisionComponent3D.hpp>
|
||||
#include <NDK/Components/DebugComponent.hpp>
|
||||
#include <NDK/Components/GraphicsComponent.hpp>
|
||||
#include <NDK/Components/NodeComponent.hpp>
|
||||
#include <NDK/Components/PhysicsComponent2D.hpp>
|
||||
|
||||
namespace Ndk
|
||||
{
|
||||
@@ -227,17 +229,24 @@ namespace Ndk
|
||||
{
|
||||
switch (option)
|
||||
{
|
||||
case DebugDraw::Collider2D:
|
||||
{
|
||||
Nz::Vector3f offset;
|
||||
Nz::InstancedRenderableRef renderable = GenerateCollision2DMesh(entity, &offset);
|
||||
if (renderable)
|
||||
entityGfx.Attach(renderable, Nz::Matrix4f::Translate(offset), DebugDrawOrder);
|
||||
|
||||
entityDebug.UpdateDebugRenderable(option, std::move(renderable));
|
||||
break;
|
||||
}
|
||||
|
||||
case DebugDraw::Collider3D:
|
||||
{
|
||||
const Nz::Boxf& obb = entityGfx.GetAABB();
|
||||
|
||||
Nz::InstancedRenderableRef renderable = GenerateCollision3DMesh(entity);
|
||||
if (renderable)
|
||||
{
|
||||
renderable->SetPersistent(false);
|
||||
|
||||
entityGfx.Attach(renderable, Nz::Matrix4f::Translate(obb.GetCenter() - entityNode.GetPosition()), DebugDrawOrder);
|
||||
}
|
||||
|
||||
entityDebug.UpdateDebugRenderable(option, std::move(renderable));
|
||||
break;
|
||||
@@ -305,6 +314,76 @@ namespace Ndk
|
||||
|
||||
return model;
|
||||
}
|
||||
|
||||
Nz::InstancedRenderableRef DebugSystem::GenerateCollision2DMesh(Entity* entity, Nz::Vector3f* offset)
|
||||
{
|
||||
if (entity->HasComponent<CollisionComponent2D>())
|
||||
{
|
||||
CollisionComponent2D& entityCollision = entity->GetComponent<CollisionComponent2D>();
|
||||
const Nz::Collider2DRef& geom = entityCollision.GetGeom();
|
||||
|
||||
std::vector<Nz::Vector3f> vertices;
|
||||
std::vector<std::size_t> indices;
|
||||
|
||||
geom->ForEachPolygon([&](const Nz::Vector2f* polygonVertices, std::size_t vertexCount)
|
||||
{
|
||||
std::size_t firstIndex = vertices.size();
|
||||
|
||||
// Don't reserve and let the vector handle its own capacity
|
||||
for (std::size_t i = 0; i < vertexCount; ++i)
|
||||
vertices.emplace_back(*polygonVertices++);
|
||||
|
||||
for (std::size_t i = 0; i < vertexCount - 1; ++i)
|
||||
{
|
||||
indices.push_back(firstIndex + i);
|
||||
indices.push_back(firstIndex + i + 1);
|
||||
}
|
||||
|
||||
indices.push_back(firstIndex + vertexCount - 1);
|
||||
indices.push_back(firstIndex);
|
||||
});
|
||||
|
||||
Nz::IndexBufferRef indexBuffer = Nz::IndexBuffer::New(vertices.size() > 0xFFFF, Nz::UInt32(indices.size()), Nz::DataStorage_Hardware, 0);
|
||||
Nz::IndexMapper indexMapper(indexBuffer, Nz::BufferAccess_WriteOnly);
|
||||
|
||||
Nz::IndexIterator indexPtr = indexMapper.begin();
|
||||
for (std::size_t index : indices)
|
||||
*indexPtr++ = static_cast<Nz::UInt32>(index);
|
||||
|
||||
indexMapper.Unmap();
|
||||
|
||||
Nz::VertexBufferRef vertexBuffer = Nz::VertexBuffer::New(Nz::VertexDeclaration::Get(Nz::VertexLayout_XYZ), Nz::UInt32(vertices.size()), Nz::DataStorage_Hardware, 0);
|
||||
vertexBuffer->Fill(vertices.data(), 0, Nz::UInt32(vertices.size()));
|
||||
|
||||
Nz::MeshRef mesh = Nz::Mesh::New();
|
||||
mesh->CreateStatic();
|
||||
|
||||
Nz::StaticMeshRef subMesh = Nz::StaticMesh::New(vertexBuffer, indexBuffer);
|
||||
subMesh->SetPrimitiveMode(Nz::PrimitiveMode_LineList);
|
||||
subMesh->SetMaterialIndex(0);
|
||||
subMesh->GenerateAABB();
|
||||
|
||||
mesh->SetMaterialCount(1);
|
||||
mesh->AddSubMesh(subMesh);
|
||||
|
||||
Nz::ModelRef model = Nz::Model::New();
|
||||
model->SetMesh(mesh);
|
||||
model->SetMaterial(0, GetCollisionMaterial());
|
||||
|
||||
// Find center of mass
|
||||
if (entity->HasComponent<PhysicsComponent2D>())
|
||||
{
|
||||
const PhysicsComponent2D& entityPhys = entity->GetComponent<PhysicsComponent2D>();
|
||||
*offset = entityPhys.GetMassCenter(Nz::CoordSys_Local) + entityCollision.GetGeomOffset();
|
||||
}
|
||||
else
|
||||
*offset = entityCollision.GetGeomOffset();
|
||||
|
||||
return model;
|
||||
}
|
||||
else
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
Nz::InstancedRenderableRef DebugSystem::GenerateCollision3DMesh(Entity* entity)
|
||||
{
|
||||
@@ -315,16 +394,12 @@ namespace Ndk
|
||||
|
||||
std::vector<Nz::Vector3f> vertices;
|
||||
std::vector<std::size_t> indices;
|
||||
|
||||
geom->ForEachPolygon([&](const float* polygonVertices, std::size_t vertexCount)
|
||||
|
||||
geom->ForEachPolygon([&](const Nz::Vector3f* polygonVertices, std::size_t vertexCount)
|
||||
{
|
||||
std::size_t firstIndex = vertices.size();
|
||||
|
||||
for (std::size_t i = 0; i < vertexCount; ++i)
|
||||
{
|
||||
const float* vertexData = &polygonVertices[i * 3];
|
||||
vertices.emplace_back(vertexData[0], vertexData[1], vertexData[2]);
|
||||
}
|
||||
vertices.resize(firstIndex + vertexCount);
|
||||
std::copy(polygonVertices, polygonVertices + vertexCount, &vertices[firstIndex]);
|
||||
|
||||
for (std::size_t i = 0; i < vertexCount - 1; ++i)
|
||||
{
|
||||
@@ -378,7 +453,7 @@ namespace Ndk
|
||||
m_globalAabbMaterial->EnableDepthBuffer(true);
|
||||
m_globalAabbMaterial->SetDiffuseColor(Nz::Color::Orange);
|
||||
m_globalAabbMaterial->SetFaceFilling(Nz::FaceFilling_Line);
|
||||
m_globalAabbMaterial->SetLineWidth(2.f);
|
||||
//m_globalAabbMaterial->SetLineWidth(2.f);
|
||||
}
|
||||
|
||||
return m_globalAabbMaterial;
|
||||
@@ -393,7 +468,7 @@ namespace Ndk
|
||||
m_localAabbMaterial->EnableDepthBuffer(true);
|
||||
m_localAabbMaterial->SetDiffuseColor(Nz::Color::Red);
|
||||
m_localAabbMaterial->SetFaceFilling(Nz::FaceFilling_Line);
|
||||
m_localAabbMaterial->SetLineWidth(2.f);
|
||||
//m_localAabbMaterial->SetLineWidth(2.f);
|
||||
}
|
||||
|
||||
return m_localAabbMaterial;
|
||||
@@ -408,7 +483,7 @@ namespace Ndk
|
||||
m_collisionMaterial->EnableDepthBuffer(true);
|
||||
m_collisionMaterial->SetDiffuseColor(Nz::Color::Blue);
|
||||
m_collisionMaterial->SetFaceFilling(Nz::FaceFilling_Line);
|
||||
m_collisionMaterial->SetLineWidth(2.f);
|
||||
//m_collisionMaterial->SetLineWidth(2.f);
|
||||
}
|
||||
|
||||
return m_collisionMaterial;
|
||||
@@ -423,7 +498,7 @@ namespace Ndk
|
||||
m_obbMaterial->EnableDepthBuffer(true);
|
||||
m_obbMaterial->SetDiffuseColor(Nz::Color::Green);
|
||||
m_obbMaterial->SetFaceFilling(Nz::FaceFilling_Line);
|
||||
m_obbMaterial->SetLineWidth(2.f);
|
||||
//m_obbMaterial->SetLineWidth(2.f);
|
||||
}
|
||||
|
||||
return m_obbMaterial;
|
||||
|
||||
27
SDK/src/NDK/Systems/LifetimeSystem.cpp
Normal file
27
SDK/src/NDK/Systems/LifetimeSystem.cpp
Normal file
@@ -0,0 +1,27 @@
|
||||
// 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 <NDK/Systems/LifetimeSystem.hpp>
|
||||
#include <NDK/Components/LifetimeComponent.hpp>
|
||||
|
||||
namespace Ndk
|
||||
{
|
||||
LifetimeSystem::LifetimeSystem()
|
||||
{
|
||||
Requires<LifetimeComponent>();
|
||||
}
|
||||
|
||||
void LifetimeSystem::OnUpdate(float elapsedTime)
|
||||
{
|
||||
for (const Ndk::EntityHandle& entity : GetEntities())
|
||||
{
|
||||
auto& lifetime = entity->GetComponent<LifetimeComponent>();
|
||||
|
||||
if (lifetime.UpdateLifetime(elapsedTime))
|
||||
entity->Kill();
|
||||
}
|
||||
}
|
||||
|
||||
SystemIndex LifetimeSystem::systemIndex;
|
||||
}
|
||||
@@ -86,14 +86,30 @@ namespace Ndk
|
||||
bool PhysicsSystem2D::NearestBodyQuery(const Nz::Vector2f& from, float maxDistance, Nz::UInt32 collisionGroup, Nz::UInt32 categoryMask, Nz::UInt32 collisionMask, NearestQueryResult* result)
|
||||
{
|
||||
Nz::PhysWorld2D::NearestQueryResult queryResult;
|
||||
bool res = GetPhysWorld().NearestBodyQuery(from, maxDistance, collisionGroup, categoryMask, collisionMask, &queryResult);
|
||||
if (GetPhysWorld().NearestBodyQuery(from, maxDistance, collisionGroup, categoryMask, collisionMask, &queryResult))
|
||||
{
|
||||
result->nearestBody = GetEntityFromBody(*queryResult.nearestBody);
|
||||
result->closestPoint = std::move(queryResult.closestPoint);
|
||||
result->fraction = std::move(queryResult.fraction);
|
||||
result->distance = queryResult.distance;
|
||||
|
||||
result->nearestBody = GetEntityFromBody(*queryResult.nearestBody);
|
||||
result->closestPoint = std::move(queryResult.closestPoint);
|
||||
result->fraction = std::move(queryResult.fraction);
|
||||
result->distance = queryResult.distance;
|
||||
return true;
|
||||
}
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
return res;
|
||||
void PhysicsSystem2D::RaycastQuery(const Nz::Vector2f & from, const Nz::Vector2f & to, float radius, Nz::UInt32 collisionGroup, Nz::UInt32 categoryMask, Nz::UInt32 collisionMask, const std::function<void(const RaycastHit&)>& callback)
|
||||
{
|
||||
return GetPhysWorld().RaycastQuery(from, to, radius, collisionGroup, categoryMask, collisionMask, [this, &callback](const Nz::PhysWorld2D::RaycastHit& hitInfo)
|
||||
{
|
||||
callback({
|
||||
GetEntityFromBody(*hitInfo.nearestBody),
|
||||
hitInfo.hitPos,
|
||||
hitInfo.hitNormal,
|
||||
hitInfo.fraction
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
bool PhysicsSystem2D::RaycastQuery(const Nz::Vector2f& from, const Nz::Vector2f& to, float radius, Nz::UInt32 collisionGroup, Nz::UInt32 categoryMask, Nz::UInt32 collisionMask, std::vector<RaycastHit>* hitInfos)
|
||||
@@ -108,7 +124,7 @@ namespace Ndk
|
||||
std::move(hitResult.hitPos),
|
||||
std::move(hitResult.hitNormal),
|
||||
hitResult.fraction
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
return res;
|
||||
@@ -117,14 +133,25 @@ namespace Ndk
|
||||
bool PhysicsSystem2D::RaycastQueryFirst(const Nz::Vector2f& from, const Nz::Vector2f& to, float radius, Nz::UInt32 collisionGroup, Nz::UInt32 categoryMask, Nz::UInt32 collisionMask, RaycastHit* hitInfo)
|
||||
{
|
||||
Nz::PhysWorld2D::RaycastHit queryResult;
|
||||
bool res = GetPhysWorld().RaycastQueryFirst(from, to, radius, collisionGroup, categoryMask, collisionMask, &queryResult);
|
||||
if (GetPhysWorld().RaycastQueryFirst(from, to, radius, collisionGroup, categoryMask, collisionMask, &queryResult))
|
||||
{
|
||||
hitInfo->body = GetEntityFromBody(*queryResult.nearestBody);
|
||||
hitInfo->hitPos = std::move(queryResult.hitPos);
|
||||
hitInfo->hitNormal = std::move(queryResult.hitNormal);
|
||||
hitInfo->fraction = queryResult.fraction;
|
||||
|
||||
hitInfo->body = GetEntityFromBody(*queryResult.nearestBody);
|
||||
hitInfo->hitPos = std::move(queryResult.hitPos);
|
||||
hitInfo->hitNormal = std::move(queryResult.hitNormal);
|
||||
hitInfo->fraction = queryResult.fraction;
|
||||
return true;
|
||||
}
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
return res;
|
||||
void PhysicsSystem2D::RegionQuery(const Nz::Rectf& boundingBox, Nz::UInt32 collisionGroup, Nz::UInt32 categoryMask, Nz::UInt32 collisionMask, const std::function<void(const EntityHandle&)>& callback)
|
||||
{
|
||||
return GetPhysWorld().RegionQuery(boundingBox, collisionGroup, categoryMask, collisionMask, [this, &callback](Nz::RigidBody2D* body)
|
||||
{
|
||||
callback(GetEntityFromBody(*body));
|
||||
});
|
||||
}
|
||||
|
||||
void PhysicsSystem2D::RegionQuery(const Nz::Rectf& boundingBox, Nz::UInt32 collisionGroup, Nz::UInt32 categoryMask, Nz::UInt32 collisionMask, std::vector<EntityHandle>* bodies)
|
||||
@@ -213,7 +240,7 @@ namespace Ndk
|
||||
Nz::Vector2f newPosition = Nz::Vector2f(node.GetPosition(Nz::CoordSys_Global));
|
||||
|
||||
// To move static objects and ensure their collisions, we have to specify them a velocity
|
||||
// (/!\: the physical motor does not apply the speed on static objects)
|
||||
// (/!\: the physical engine does not apply the speed on static objects)
|
||||
if (newPosition != oldPosition)
|
||||
{
|
||||
body->SetPosition(newPosition);
|
||||
@@ -222,8 +249,7 @@ namespace Ndk
|
||||
else
|
||||
body->SetVelocity(Nz::Vector2f::Zero());
|
||||
|
||||
/*
|
||||
if (newRotation != oldRotation)
|
||||
/*if (newRotation != oldRotation)
|
||||
{
|
||||
Nz::Quaternionf transition = newRotation * oldRotation.GetConjugate();
|
||||
Nz::EulerAnglesf angles = transition.ToEulerAngles();
|
||||
@@ -235,8 +261,7 @@ namespace Ndk
|
||||
physObj->SetAngularVelocity(angularVelocity);
|
||||
}
|
||||
else
|
||||
physObj->SetAngularVelocity(Nz::Vector3f::Zero());
|
||||
*/
|
||||
physObj->SetAngularVelocity(Nz::Vector3f::Zero());*/
|
||||
}
|
||||
}
|
||||
|
||||
@@ -283,7 +308,7 @@ namespace Ndk
|
||||
|
||||
void PhysicsSystem2D::RegisterCallbacks(unsigned int collisionIdA, unsigned int collisionIdB, Callback callbacks)
|
||||
{
|
||||
Nz::PhysWorld2D::Callback worldCallbacks{};
|
||||
Nz::PhysWorld2D::Callback worldCallbacks;
|
||||
|
||||
if (callbacks.endCallback)
|
||||
{
|
||||
|
||||
@@ -43,7 +43,7 @@ namespace Ndk
|
||||
NodeComponent& node = entity->GetComponent<NodeComponent>();
|
||||
const VelocityComponent& velocity = entity->GetComponent<VelocityComponent>();
|
||||
|
||||
node.Move(velocity.linearVelocity * elapsedTime, Nz::CoordSys_Global);
|
||||
node.Move(velocity.linearVelocity * elapsedTime, velocity.coordSys);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -12,7 +12,7 @@ namespace Ndk
|
||||
BaseWidget(parent)
|
||||
{
|
||||
m_entity = CreateEntity();
|
||||
m_entity->AddComponent<NodeComponent>();
|
||||
m_entity->AddComponent<NodeComponent>().SetParent(this);
|
||||
auto& gfx = m_entity->AddComponent<GraphicsComponent>();
|
||||
|
||||
m_sprite = Nz::Sprite::New();
|
||||
|
||||
@@ -6,6 +6,7 @@
|
||||
#include <Nazara/Core/Clock.hpp>
|
||||
#include <Nazara/Core/Error.hpp>
|
||||
#include <NDK/BaseComponent.hpp>
|
||||
#include <NDK/Systems/LifetimeSystem.hpp>
|
||||
#include <NDK/Systems/PhysicsSystem2D.hpp>
|
||||
#include <NDK/Systems/PhysicsSystem3D.hpp>
|
||||
#include <NDK/Systems/VelocitySystem.hpp>
|
||||
@@ -43,6 +44,7 @@ namespace Ndk
|
||||
|
||||
void World::AddDefaultSystems()
|
||||
{
|
||||
AddSystem<LifetimeSystem>();
|
||||
AddSystem<PhysicsSystem2D>();
|
||||
AddSystem<PhysicsSystem3D>();
|
||||
AddSystem<VelocitySystem>();
|
||||
@@ -133,9 +135,9 @@ namespace Ndk
|
||||
m_waitingEntities.clear();
|
||||
|
||||
m_aliveEntities.Clear();
|
||||
m_dirtyEntities.Clear();
|
||||
m_dirtyEntities.front.Clear();
|
||||
m_freeEntityIds.Clear();
|
||||
m_killedEntities.Clear();
|
||||
m_killedEntities.front.Clear();
|
||||
}
|
||||
|
||||
/*!
|
||||
@@ -208,7 +210,8 @@ namespace Ndk
|
||||
}
|
||||
|
||||
// Handle killed entities before last call
|
||||
for (std::size_t i = m_killedEntities.FindFirst(); i != m_killedEntities.npos; i = m_killedEntities.FindNext(i))
|
||||
std::swap(m_killedEntities.front, m_killedEntities.back);
|
||||
for (std::size_t i = m_killedEntities.back.FindFirst(); i != m_killedEntities.back.npos; i = m_killedEntities.back.FindNext(i))
|
||||
{
|
||||
NazaraAssert(i < m_entityBlocks.size(), "Entity index out of range");
|
||||
|
||||
@@ -218,12 +221,13 @@ namespace Ndk
|
||||
entity->Destroy();
|
||||
|
||||
// Send back the identifier of the entity to the free queue
|
||||
m_freeEntityIds.UnboundedSet(entity->GetId());
|
||||
m_freeEntityIds.UnboundedSet(i);
|
||||
}
|
||||
m_killedEntities.Reset();
|
||||
m_killedEntities.back.Clear();
|
||||
|
||||
// Handle of entities which need an update from the systems
|
||||
for (std::size_t i = m_dirtyEntities.FindFirst(); i != m_dirtyEntities.npos; i = m_dirtyEntities.FindNext(i))
|
||||
std::swap(m_dirtyEntities.front, m_dirtyEntities.back);
|
||||
for (std::size_t i = m_dirtyEntities.back.FindFirst(); i != m_dirtyEntities.back.npos; i = m_dirtyEntities.back.FindNext(i))
|
||||
{
|
||||
NazaraAssert(i < m_entityBlocks.size(), "Entity index out of range");
|
||||
|
||||
@@ -234,7 +238,7 @@ namespace Ndk
|
||||
continue;
|
||||
|
||||
Nz::Bitset<>& removedComponents = entity->GetRemovedComponentBits();
|
||||
for (std::size_t j = removedComponents.FindFirst(); j != m_dirtyEntities.npos; j = removedComponents.FindNext(j))
|
||||
for (std::size_t j = removedComponents.FindFirst(); j != m_dirtyEntities.back.npos; j = removedComponents.FindNext(j))
|
||||
entity->DestroyComponent(static_cast<Ndk::ComponentIndex>(j));
|
||||
removedComponents.Reset();
|
||||
|
||||
@@ -260,7 +264,7 @@ namespace Ndk
|
||||
}
|
||||
}
|
||||
}
|
||||
m_dirtyEntities.Reset();
|
||||
m_dirtyEntities.back.Clear();
|
||||
}
|
||||
|
||||
/*!
|
||||
|
||||
Reference in New Issue
Block a user