Panagiotis Christopoulos Charitos 11 سال پیش
والد
کامیت
25cd517e53

+ 2 - 2
include/anki/physics/PhysicsCollisionShape.h

@@ -18,7 +18,7 @@ class PhysicsCollisionShape: public PhysicsObject
 {
 {
 public:
 public:
 	/// Type of supported physics collision shapes.
 	/// Type of supported physics collision shapes.
-	enum class Type: U8
+	enum class ShapeType: U8
 	{
 	{
 		NONE,
 		NONE,
 		SPHERE,
 		SPHERE,
@@ -32,7 +32,7 @@ public:
 	};
 	};
 
 
 	PhysicsCollisionShape(PhysicsWorld* world)
 	PhysicsCollisionShape(PhysicsWorld* world)
-	:	PhysicsObject(world)
+	:	PhysicsObject(Type::COLLISION_SHAPE, world)
 	{}
 	{}
 
 
 	~PhysicsCollisionShape();
 	~PhysicsCollisionShape();

+ 18 - 2
include/anki/physics/PhysicsObject.h

@@ -17,8 +17,18 @@ namespace anki {
 class PhysicsObject
 class PhysicsObject
 {
 {
 public:
 public:
-	PhysicsObject(PhysicsWorld* world)
-	:	m_world(world)
+	/// Type of the physics object.
+	enum class Type: U8
+	{
+		COLLISION_SHAPE,
+		BODY,
+		JOINT,
+		COUNT
+	};
+
+	PhysicsObject(Type type, PhysicsWorld* world)
+	:	m_world(world),
+		m_type(type)
 	{
 	{
 		ANKI_ASSERT(m_world);
 		ANKI_ASSERT(m_world);
 	}
 	}
@@ -28,6 +38,11 @@ public:
 		ANKI_ASSERT(m_markedForDeletion == true);
 		ANKI_ASSERT(m_markedForDeletion == true);
 	}
 	}
 
 
+	Type getType() const
+	{
+		return m_type;
+	}
+
 	void setMarkedForDeletion();
 	void setMarkedForDeletion();
 
 
 	Bool getMarkedForDeletion() const
 	Bool getMarkedForDeletion() const
@@ -39,6 +54,7 @@ protected:
 	PhysicsWorld* m_world = nullptr;
 	PhysicsWorld* m_world = nullptr;
 
 
 private:
 private:
+	Type m_type;
 	Bool8 m_markedForDeletion = false;
 	Bool8 m_markedForDeletion = false;
 };
 };
 /// @}
 /// @}

+ 13 - 5
include/anki/physics/PhysicsWorld.h

@@ -38,6 +38,12 @@ public:
 		return newObjectInternal(m_bodies, std::forward<TArgs>(args)...);
 		return newObjectInternal(m_bodies, std::forward<TArgs>(args)...);
 	}
 	}
 
 
+	/// Start asynchronous update.
+	Error updateAsync(F32 timestep);
+
+	/// End asynchronous update.
+	void waitUpdate();
+
 	/// @privatesection
 	/// @privatesection
 	/// @{
 	/// @{
 	NewtonWorld* _getNewtonWorld()
 	NewtonWorld* _getNewtonWorld()
@@ -46,21 +52,23 @@ public:
 		return m_world;
 		return m_world;
 	}
 	}
 
 
-	void _increaseObjectsMarkedForDeletion()
-	{
-		++m_markedForDeletionCount;
-	}
+	void _increaseObjectsMarkedForDeletion(PhysicsObject::Type type);
 	/// @}
 	/// @}
 
 
 private:
 private:
 	ChainAllocator<U8> m_alloc;
 	ChainAllocator<U8> m_alloc;
 	List<PhysicsCollisionShape*> m_collisions;
 	List<PhysicsCollisionShape*> m_collisions;
 	List<PhysicsBody*> m_bodies;
 	List<PhysicsBody*> m_bodies;
-	AtomicU32 m_markedForDeletionCount = {0};
+	Array<AtomicU32, static_cast<U>(PhysicsObject::Type::COUNT)> 
+		m_forDeletionCount = {{{0}, {0}, {0}}};
 	NewtonWorld* m_world = nullptr;
 	NewtonWorld* m_world = nullptr;
 
 
 	template<typename T, typename TContainer, typename... TArgs>
 	template<typename T, typename TContainer, typename... TArgs>
 	T* newObjectInternal(TContainer& cont, TArgs&&... args);
 	T* newObjectInternal(TContainer& cont, TArgs&&... args);
+
+	template<typename T>
+	void cleanupMarkedForDeletion(
+		List<T*>& container, AtomicU32& count);
 };
 };
 
 
 //==============================================================================
 //==============================================================================

+ 0 - 3
include/anki/resource/Common.h

@@ -18,7 +18,6 @@ class ResourceManager;
 
 
 /// @addtogroup resource
 /// @addtogroup resource
 /// @{
 /// @{
-
 template<typename T>
 template<typename T>
 using ResourceAllocator = HeapAllocator<T>;
 using ResourceAllocator = HeapAllocator<T>;
 
 
@@ -52,7 +51,6 @@ public:
 		m_resources(resourceManager)
 		m_resources(resourceManager)
 	{}
 	{}
 };
 };
-
 /// @}
 /// @}
 
 
 /// @privatesection
 /// @privatesection
@@ -72,7 +70,6 @@ public:
 	{ \
 	{ \
 		goto cleanup; \
 		goto cleanup; \
 	}
 	}
-
 /// @}
 /// @}
 
 
 } // end namespace anki
 } // end namespace anki

+ 6 - 11
include/anki/resource/Model.h

@@ -14,10 +14,12 @@
 #include "anki/resource/Material.h"
 #include "anki/resource/Material.h"
 #include "anki/resource/Skeleton.h"
 #include "anki/resource/Skeleton.h"
 #include "anki/resource/Animation.h"
 #include "anki/resource/Animation.h"
-#include "anki/physics/PhysicsCollisionShape.h"
 
 
 namespace anki {
 namespace anki {
 
 
+// Forward
+class PhysicsCollisionShape;
+
 /// Model patch interface class. Its very important class and it binds the
 /// Model patch interface class. Its very important class and it binds the
 /// material with the mesh
 /// material with the mesh
 class ModelPatchBase
 class ModelPatchBase
@@ -167,13 +169,6 @@ private:
 class Model
 class Model
 {
 {
 public:
 public:
-	/// Physics information the Model holds.
-	struct PhysicsInformation
-	{
-		PhysicsCollisionShape::Type m_type = PhysicsCollisionShape::Type::NONE;
-		F32 m_radius = 0.0;
-	};
-
 	Model(ResourceAllocator<U8>& alloc);
 	Model(ResourceAllocator<U8>& alloc);
 
 
 	~Model();
 	~Model();
@@ -188,9 +183,9 @@ public:
 		return m_visibilityShape;
 		return m_visibilityShape;
 	}
 	}
 
 
-	const PhysicsInformation& getPhysicsInformation() const
+	const PhysicsCollisionShape* getPhysicsCollisionShape() const
 	{
 	{
-		return m_physicsInfo;
+		return m_physicsShape;
 	}
 	}
 
 
 	ANKI_USE_RESULT Error load(
 	ANKI_USE_RESULT Error load(
@@ -202,7 +197,7 @@ private:
 	Obb m_visibilityShape;
 	Obb m_visibilityShape;
 	SkeletonResourcePointer m_skeleton;
 	SkeletonResourcePointer m_skeleton;
 	ResourceDArray<AnimationResourcePointer> m_animations;
 	ResourceDArray<AnimationResourcePointer> m_animations;
-	PhysicsInformation m_physicsInfo;
+	PhysicsCollisionShape* m_physicsShape = nullptr;
 };
 };
 
 
 } // end namespace anki
 } // end namespace anki

+ 10 - 0
include/anki/resource/ResourceManager.h

@@ -17,6 +17,7 @@ namespace anki {
 // Forward
 // Forward
 class ConfigSet;
 class ConfigSet;
 class GlDevice;
 class GlDevice;
+class PhysicsWorld;
 class ResourceManager;
 class ResourceManager;
 class AsyncLoader;
 class AsyncLoader;
 
 
@@ -143,6 +144,7 @@ public:
 	{
 	{
 	public:
 	public:
 		GlDevice* m_gl = nullptr;
 		GlDevice* m_gl = nullptr;
+		PhysicsWorld* m_physics = nullptr;
 		const ConfigSet* m_config = nullptr;
 		const ConfigSet* m_config = nullptr;
 		CString m_cacheDir;
 		CString m_cacheDir;
 		AllocAlignedCallback m_allocCallback = 0;
 		AllocAlignedCallback m_allocCallback = 0;
@@ -189,9 +191,16 @@ public:
 
 
 	GlDevice& _getGlDevice()
 	GlDevice& _getGlDevice()
 	{
 	{
+		ANKI_ASSERT(m_gl);
 		return *m_gl;
 		return *m_gl;
 	}
 	}
 
 
+	PhysicsWorld& _getPhysicsWorld()
+	{
+		ANKI_ASSERT(m_physics);
+		return *m_physics;
+	}
+
 	const ResourceString& _getCacheDirectory() const
 	const ResourceString& _getCacheDirectory() const
 	{
 	{
 		return m_cacheDir;
 		return m_cacheDir;
@@ -237,6 +246,7 @@ public:
 
 
 private:
 private:
 	GlDevice* m_gl = nullptr;
 	GlDevice* m_gl = nullptr;
+	PhysicsWorld* m_physics = nullptr;
 	ResourceAllocator<U8> m_alloc;
 	ResourceAllocator<U8> m_alloc;
 	TempResourceAllocator<U8> m_tmpAlloc;
 	TempResourceAllocator<U8> m_tmpAlloc;
 	ResourceString m_cacheDir;
 	ResourceString m_cacheDir;

+ 1 - 1
src/physics/PhysicsBody.cpp

@@ -11,7 +11,7 @@ namespace anki {
 
 
 //==============================================================================
 //==============================================================================
 PhysicsBody::PhysicsBody(PhysicsWorld* world)
 PhysicsBody::PhysicsBody(PhysicsWorld* world)
-:	PhysicsObject(world)
+:	PhysicsObject(Type::BODY, world)
 {}
 {}
 
 
 //==============================================================================
 //==============================================================================

+ 1 - 1
src/physics/PhysicsObject.cpp

@@ -14,7 +14,7 @@ void PhysicsObject::setMarkedForDeletion()
 	if(!m_markedForDeletion)
 	if(!m_markedForDeletion)
 	{
 	{
 		m_markedForDeletion = true;
 		m_markedForDeletion = true;
-		m_world->_increaseObjectsMarkedForDeletion();
+		m_world->_increaseObjectsMarkedForDeletion(m_type);
 	}
 	}
 }
 }
 
 

+ 54 - 0
src/physics/PhysicsWorld.cpp

@@ -63,4 +63,58 @@ Error PhysicsWorld::create(AllocAlignedCallback allocCb, void* allocCbData)
 	return err;
 	return err;
 }
 }
 
 
+//==============================================================================
+void PhysicsWorld::_increaseObjectsMarkedForDeletion(PhysicsObject::Type type)
+{
+	++m_forDeletionCount[static_cast<U>(type)];
+}
+
+//==============================================================================
+Error PhysicsWorld::updateAsync(F32 timestep)
+{
+	// Do cleanup of marked for deletion
+	cleanupMarkedForDeletion(m_bodies, 
+		m_forDeletionCount[static_cast<U>(PhysicsObject::Type::BODY)]);
+	cleanupMarkedForDeletion(m_collisions, m_forDeletionCount[
+		static_cast<U>(PhysicsObject::Type::COLLISION_SHAPE)]);
+
+	// Update
+	NewtonUpdateAsync(m_world, timestep);
+
+	return ErrorCode::NONE;
+}
+
+//==============================================================================
+void PhysicsWorld::waitUpdate()
+{
+	NewtonWaitForUpdateToFinish(m_world);
+}
+
+//==============================================================================
+template<typename T>
+void PhysicsWorld::cleanupMarkedForDeletion(
+	List<T*>& container, AtomicU32& count)
+{
+	while(count > 0)
+	{
+		Bool found = false;
+		auto it = container.begin();
+		auto end = container.end();
+		for(; it != end; it++)
+		{
+			if((*it)->getMarkedForDeletion())
+			{
+				// Delete node
+				container.erase(m_alloc, it);
+				m_alloc.deleteInstance(*it);
+				found = true;
+				break;
+			}
+		}
+
+		(void)found;
+		ANKI_ASSERT(found && "Something is wrong with marked for deletion");
+	}
+}
+
 } // end namespace anki
 } // end namespace anki

+ 0 - 2
src/resource/Model.cpp

@@ -325,8 +325,6 @@ Error Model::load(const CString& filename, ResourceInitializer& init)
 		{
 		{
 			F64 tmp;
 			F64 tmp;
 			ANKI_CHECK(valEl.getF64(tmp));
 			ANKI_CHECK(valEl.getF64(tmp));
-			m_physicsInfo.m_type = PhysicsCollisionShape::Type::SPHERE;
-			m_physicsInfo.m_radius = tmp;
 		}
 		}
 		else if(type == "box")
 		else if(type == "box")
 		{
 		{

+ 1 - 0
src/resource/ResourceManager.cpp

@@ -37,6 +37,7 @@ Error ResourceManager::create(Initializer& init)
 	Error err = ErrorCode::NONE;
 	Error err = ErrorCode::NONE;
 
 
 	m_gl = init.m_gl;
 	m_gl = init.m_gl;
+	m_physics = init.m_physics;
 	m_alloc = ResourceAllocator<U8>(
 	m_alloc = ResourceAllocator<U8>(
 		init.m_allocCallback, init.m_allocCallbackData);
 		init.m_allocCallback, init.m_allocCallbackData);
 
 

+ 1 - 1
src/scene/SceneNode.cpp

@@ -84,7 +84,7 @@ Error SceneNode::addComponent(SceneComponent* comp)
 	ANKI_ASSERT(comp);
 	ANKI_ASSERT(comp);
 	Error err = ErrorCode::NONE;
 	Error err = ErrorCode::NONE;
 
 
-	if(m_components.getSize() < m_componentsCount + 1)
+	if(m_components.getSize() < m_componentsCount + 1u)
 	{
 	{
 		// Not enough room
 		// Not enough room
 		const U extra = 2;
 		const U extra = 2;