Browse Source

Physics work + occlusion query work

Panagiotis Christopoulos Charitos 11 years ago
parent
commit
579049b98f

+ 6 - 0
include/anki/gl/GlCommandBufferHandle.h

@@ -14,6 +14,7 @@ namespace anki {
 // Forward
 // Forward
 class GlDevice;
 class GlDevice;
 class GlTextureHandle;
 class GlTextureHandle;
+class GlOcclusionQueryHandle;
 
 
 /// @addtogroup opengl_other
 /// @addtogroup opengl_other
 /// @{
 /// @{
@@ -148,6 +149,11 @@ public:
 
 
 	void drawArrays(GLenum mode, U32 count, U32 instanceCount = 1,
 	void drawArrays(GLenum mode, U32 count, U32 instanceCount = 1,
 		U32 first = 0, U32 baseInstance = 0);
 		U32 first = 0, U32 baseInstance = 0);
+
+	void drawElementsConditional(GlOcclusionQueryHandle& query, 
+		GLenum mode, U8 indexSize, 
+		U32 count, U32 instanceCount = 1, U32 firstIndex = 0,
+		U32 baseVertex = 0, U32 baseInstance = 0);
 	/// @}
 	/// @}
 
 
 	/// @privatesection
 	/// @privatesection

+ 1 - 0
include/anki/gl/GlFramebufferHandle.h

@@ -52,6 +52,7 @@ public:
 		GLbitfield attachmentMask,
 		GLbitfield attachmentMask,
 		Bool linear);
 		Bool linear);
 };
 };
+/// @}
 
 
 } // end namespace anki
 } // end namespace anki
 
 

+ 56 - 0
include/anki/gl/GlOcclusionQuery.h

@@ -0,0 +1,56 @@
+// Copyright (C) 2014, Panagiotis Christopoulos Charitos.
+// All rights reserved.
+// Code licensed under the BSD License.
+// http://www.anki3d.org/LICENSE
+
+#ifndef ANKI_GL_GL_OCCLUSION_QUERY_H
+#define ANKI_GL_GL_OCCLUSION_QUERY_H
+
+#include "anki/gl/GlObject.h"
+
+namespace anki {
+
+/// @addtogroup opengl_private
+/// @{
+
+/// Occlusion query.
+class GlOcclusionQuery: public GlObject
+{
+public:
+	using Base = GlObject;
+
+	enum class Result: U
+	{
+		NOT_AVAILABLE,
+		VISIBLE,
+		NOT_VISIBLE
+	};
+
+	GlOcclusionQuery() = default;
+
+	~GlOcclusionQuery()
+	{
+		destroy();
+	}
+
+	/// Create the query.
+	ANKI_USE_RESULT Error create();
+
+	/// Begin query.
+	void begin();
+
+	/// End query.
+	void end();
+
+	/// Get query result.
+	Result getResult();
+
+private:
+	void destroy();
+};
+/// @}
+
+} // end namespace anki
+
+#endif
+

+ 43 - 0
include/anki/gl/GlOcclusionQueryHandle.h

@@ -0,0 +1,43 @@
+// Copyright (C) 2014, Panagiotis Christopoulos Charitos.
+// All rights reserved.
+// Code licensed under the BSD License.
+// http://www.anki3d.org/LICENSE
+
+#ifndef ANKI_GL_GL_OCCLUSION_QUERY_HANDLE_H
+#define ANKI_GL_GL_OCCLUSION_QUERY_HANDLE_H
+
+#include "anki/gl/GlContainerHandle.h"
+
+namespace anki {
+
+// Forward
+class GlOcclusionQuery;
+
+/// @addtogroup opengl_other
+/// @{
+
+/// Occlusion query handle.
+class GlOcclusionQueryHandle: public GlContainerHandle<GlOcclusionQuery>
+{
+public:
+	using Base = GlContainerHandle<GlOcclusionQuery>;
+
+	GlOcclusionQueryHandle();
+
+	~GlOcclusionQueryHandle();
+
+	/// Create a query.
+	ANKI_USE_RESULT Error create(GlCommandBufferHandle& commands);
+
+	/// Begin query.
+	void begin(GlCommandBufferHandle& commands);
+
+	/// End query.
+	void end(GlCommandBufferHandle& commands);
+};
+/// @}
+
+} // end namespace anki
+
+#endif
+

+ 1 - 6
include/anki/gl/GlShader.h

@@ -7,7 +7,6 @@
 #define ANKI_GL_GL_SHADER_H
 #define ANKI_GL_GL_SHADER_H
 
 
 #include "anki/gl/GlObject.h"
 #include "anki/gl/GlObject.h"
-#include "anki/util/Dictionary.h"
 
 
 namespace anki {
 namespace anki {
 
 
@@ -48,14 +47,10 @@ public:
 	}
 	}
 
 
 private:
 private:
-	GLenum m_type;
+	GLenum m_type = 0;
 
 
 	void destroy();
 	void destroy();
 
 
-	/// Query the shader for blocks
-	ANKI_USE_RESULT Error initBlocksOfType(GLenum programInterface, 
-		U count, U index, char*& namesPtr, U& namesLen);
-
 	ANKI_USE_RESULT Error handleError(GlAllocator<U8>& alloc, String& src);
 	ANKI_USE_RESULT Error handleError(GlAllocator<U8>& alloc, String& src);
 };
 };
 
 

+ 1 - 1
include/anki/physics/PhysicsBody.h

@@ -16,7 +16,7 @@ namespace anki {
 /// Initializer for PhysicsBody.
 /// Initializer for PhysicsBody.
 struct PhysicsBodyInitializer
 struct PhysicsBodyInitializer
 {
 {
-	PhysicsCollisionShape* m_shape = nullptr;
+	const PhysicsCollisionShape* m_shape = nullptr;
 	F32 m_mass = 0.0;
 	F32 m_mass = 0.0;
 	Transform m_startTrf = Transform::getIdentity();
 	Transform m_startTrf = Transform::getIdentity();
 	Bool m_kinematic = false;
 	Bool m_kinematic = false;

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

@@ -39,7 +39,7 @@ public:
 
 
 	/// @privatesection
 	/// @privatesection
 	/// @{
 	/// @{
-	NewtonCollision* _getNewtonShape()
+	NewtonCollision* _getNewtonShape() const
 	{
 	{
 		ANKI_ASSERT(m_shape);
 		ANKI_ASSERT(m_shape);
 		return m_shape;
 		return m_shape;
@@ -52,42 +52,42 @@ protected:
 };
 };
 
 
 /// Sphere collision shape.
 /// Sphere collision shape.
-class PhysicsSphere: public PhysicsCollisionShape
+class PhysicsSphere final: public PhysicsCollisionShape
 {
 {
 public:
 public:
 	PhysicsSphere(PhysicsWorld* world)
 	PhysicsSphere(PhysicsWorld* world)
 	:	PhysicsCollisionShape(world)
 	:	PhysicsCollisionShape(world)
 	{}
 	{}
 
 
-	~PhysicsSphere() final
+	~PhysicsSphere()
 	{}
 	{}
 
 
 	ANKI_USE_RESULT Error create(Initializer& init, F32 radius);
 	ANKI_USE_RESULT Error create(Initializer& init, F32 radius);
 };
 };
 
 
 /// Box collision shape.
 /// Box collision shape.
-class PhysicsBox: public PhysicsCollisionShape
+class PhysicsBox final: public PhysicsCollisionShape
 {
 {
 public:
 public:
 	PhysicsBox(PhysicsWorld* world)
 	PhysicsBox(PhysicsWorld* world)
 	:	PhysicsCollisionShape(world)
 	:	PhysicsCollisionShape(world)
 	{}
 	{}
 
 
-	~PhysicsBox() final
+	~PhysicsBox()
 	{}
 	{}
 
 
 	ANKI_USE_RESULT Error create(Initializer& init, const Vec3& extend);
 	ANKI_USE_RESULT Error create(Initializer& init, const Vec3& extend);
 };
 };
 
 
 /// Convex hull collision shape.
 /// Convex hull collision shape.
-class PhysicsConvexHull: public PhysicsCollisionShape
+class PhysicsConvexHull final: public PhysicsCollisionShape
 {
 {
 public:
 public:
 	PhysicsConvexHull(PhysicsWorld* world)
 	PhysicsConvexHull(PhysicsWorld* world)
 	:	PhysicsCollisionShape(world)
 	:	PhysicsCollisionShape(world)
 	{}
 	{}
 
 
-	~PhysicsConvexHull() final
+	~PhysicsConvexHull()
 	{}
 	{}
 
 
 	ANKI_USE_RESULT Error create(Initializer& init, 
 	ANKI_USE_RESULT Error create(Initializer& init, 
@@ -95,14 +95,14 @@ public:
 };
 };
 
 
 /// Static triangle mesh shape.
 /// Static triangle mesh shape.
-class PhysicsTriangleSoup: public PhysicsCollisionShape
+class PhysicsTriangleSoup final: public PhysicsCollisionShape
 {
 {
 public:
 public:
 	PhysicsTriangleSoup(PhysicsWorld* world)
 	PhysicsTriangleSoup(PhysicsWorld* world)
 	:	PhysicsCollisionShape(world)
 	:	PhysicsCollisionShape(world)
 	{}
 	{}
 
 
-	~PhysicsTriangleSoup() final
+	~PhysicsTriangleSoup()
 	{}
 	{}
 
 
 	ANKI_USE_RESULT Error createStaticTriangleSoup(Initializer& init,
 	ANKI_USE_RESULT Error createStaticTriangleSoup(Initializer& init,

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

@@ -29,13 +29,13 @@ public:
 	template<typename T, typename... TArgs>
 	template<typename T, typename... TArgs>
 	T* newCollisionShape(TArgs&&... args)
 	T* newCollisionShape(TArgs&&... args)
 	{
 	{
-		return newObjectInternal(m_collisions, std::forward<TArgs>(args)...);
+		return newObjectInternal<T>(m_collisions, std::forward<TArgs>(args)...);
 	}
 	}
 
 
 	template<typename T, typename... TArgs>
 	template<typename T, typename... TArgs>
 	T* newBody(TArgs&&... args)
 	T* newBody(TArgs&&... args)
 	{
 	{
-		return newObjectInternal(m_bodies, std::forward<TArgs>(args)...);
+		return newObjectInternal<T>(m_bodies, std::forward<TArgs>(args)...);
 	}
 	}
 
 
 	/// Start asynchronous update.
 	/// Start asynchronous update.

+ 1 - 1
include/anki/resource/Model.h

@@ -192,7 +192,7 @@ public:
 		const CString& filename, ResourceInitializer& init);
 		const CString& filename, ResourceInitializer& init);
 
 
 private:
 private:
-	ResourceAllocator<U8> m_alloc;
+	ResourceManager* m_resources = nullptr;
 	ResourceDArray<ModelPatchBase*> m_modelPatches;
 	ResourceDArray<ModelPatchBase*> m_modelPatches;
 	Obb m_visibilityShape;
 	Obb m_visibilityShape;
 	SkeletonResourcePointer m_skeleton;
 	SkeletonResourcePointer m_skeleton;

+ 1 - 0
include/anki/scene/BodyComponent.h

@@ -8,6 +8,7 @@
 
 
 #include "anki/scene/Common.h"
 #include "anki/scene/Common.h"
 #include "anki/scene/SceneComponent.h"
 #include "anki/scene/SceneComponent.h"
+#include "anki/physics/PhysicsBody.h"
 
 
 namespace anki {
 namespace anki {
 
 

+ 3 - 1
include/anki/scene/ModelNode.h

@@ -19,6 +19,7 @@ namespace anki {
 // Forward
 // Forward
 class ObbSpatialComponent;
 class ObbSpatialComponent;
 class BodyComponent;
 class BodyComponent;
+class PhysicsBody;
 
 
 /// @addtogroup scene
 /// @addtogroup scene
 /// @{
 /// @{
@@ -110,7 +111,8 @@ private:
 	SceneDArray<ModelPatchNode*> m_modelPatches;
 	SceneDArray<ModelPatchNode*> m_modelPatches;
 	SceneDArray<Transform> m_transforms; ///< Cache the transforms of instances
 	SceneDArray<Transform> m_transforms; ///< Cache the transforms of instances
 	Timestamp m_transformsTimestamp;
 	Timestamp m_transformsTimestamp;
-	BodyComponent* m_body = nullptr;
+	PhysicsBody* m_body = nullptr;
+	BodyComponent* m_bodyComp = nullptr;
 };
 };
 
 
 /// @}
 /// @}

+ 6 - 12
include/anki/scene/SceneGraph.h

@@ -15,7 +15,6 @@
 #include "anki/util/HighRezTimer.h"
 #include "anki/util/HighRezTimer.h"
 #include "anki/core/App.h"
 #include "anki/core/App.h"
 
 
-#include "anki/physics/PhysicsWorld.h"
 #include "anki/event/EventManager.h"
 #include "anki/event/EventManager.h"
 
 
 namespace anki {
 namespace anki {
@@ -94,15 +93,6 @@ public:
 		return m_nodesCount;
 		return m_nodesCount;
 	}
 	}
 
 
-	PhysicsWorld& getPhysics()
-	{
-		return m_physics;
-	}
-	const PhysicsWorld& getPhysics() const
-	{
-		return m_physics;
-	}
-
 	EventManager& getEventManager()
 	EventManager& getEventManager()
 	{
 	{
 		return m_events;
 		return m_events;
@@ -171,12 +161,18 @@ public:
 	{
 	{
 		return *m_gl;
 		return *m_gl;
 	}
 	}
+
+	PhysicsWorld& _getPhysicsWorld()
+	{
+		return *m_physics;
+	}
 	/// @}
 	/// @}
 
 
 private:
 private:
 	Threadpool* m_threadpool = nullptr;
 	Threadpool* m_threadpool = nullptr;
 	ResourceManager* m_resources = nullptr;
 	ResourceManager* m_resources = nullptr;
 	GlDevice* m_gl = nullptr;
 	GlDevice* m_gl = nullptr;
+	PhysicsWorld* m_physics = nullptr;
 
 
 	SceneAllocator<U8> m_alloc;
 	SceneAllocator<U8> m_alloc;
 	SceneFrameAllocator<U8> m_frameAlloc;
 	SceneFrameAllocator<U8> m_frameAlloc;
@@ -190,8 +186,6 @@ private:
 	Camera* m_mainCam = nullptr;
 	Camera* m_mainCam = nullptr;
 	Timestamp m_activeCameraChangeTimestamp = getGlobTimestamp();
 	Timestamp m_activeCameraChangeTimestamp = getGlobTimestamp();
 
 
-	PhysicsWorld m_physics;
-
 	EventManager m_events;
 	EventManager m_events;
 
 
 	AtomicU32 m_objectsMarkedForDeletionCount;
 	AtomicU32 m_objectsMarkedForDeletionCount;

+ 1 - 1
shaders/IsLp.frag.glsl

@@ -246,7 +246,7 @@ void main()
 
 
 #if GROUND_LIGHT
 #if GROUND_LIGHT
 	outColor += max(dot(normal, uGroundLightDir.xyz), 0.0) 
 	outColor += max(dot(normal, uGroundLightDir.xyz), 0.0) 
-		* vec3(0.05, 0.05, 0.01);
+		* vec3(0.10, 0.01, 0.01);
 #endif
 #endif
 
 
 #if 0
 #if 0

+ 1 - 0
src/core/App.cpp

@@ -221,6 +221,7 @@ Error App::createInternal(const ConfigSet& config_,
 	//
 	//
 	ResourceManager::Initializer rinit;
 	ResourceManager::Initializer rinit;
 	rinit.m_gl = m_gl;
 	rinit.m_gl = m_gl;
+	rinit.m_physics = m_physics;
 	rinit.m_config = &config;
 	rinit.m_config = &config;
 	rinit.m_cacheDir = m_cacheDir.toCString();
 	rinit.m_cacheDir = m_cacheDir.toCString();
 	rinit.m_allocCallback = m_allocCb;
 	rinit.m_allocCallback = m_allocCb;

+ 96 - 0
src/gl/GlCommandBufferHandle.cpp

@@ -9,6 +9,8 @@
 #include "anki/gl/GlFramebuffer.h"
 #include "anki/gl/GlFramebuffer.h"
 #include "anki/gl/GlTextureHandle.h"
 #include "anki/gl/GlTextureHandle.h"
 #include "anki/gl/GlTexture.h"
 #include "anki/gl/GlTexture.h"
+#include "anki/gl/GlOcclusionQueryHandle.h"
+#include "anki/gl/GlOcclusionQuery.h"
 #include "anki/core/Counters.h"
 #include "anki/core/Counters.h"
 #include <utility>
 #include <utility>
 
 
@@ -601,4 +603,98 @@ void GlCommandBufferHandle::drawArrays(
 	}
 	}
 }
 }
 
 
+//==============================================================================
+// Use the template trick to avoid allocating too much things in the 
+// command buffer
+template<GLenum mode, U8 indexSize>
+class DrawElementsCondCommand: public GlCommand
+{
+public:
+	GlDrawElementsIndirectInfo m_info;
+	GlOcclusionQueryHandle m_query;
+
+	DrawElementsCondCommand(GlDrawElementsIndirectInfo& info,
+		GlOcclusionQueryHandle query)
+	:	m_info(info),
+		m_query(query)
+	{}
+
+	Error operator()(GlCommandBuffer*)
+	{
+		ANKI_ASSERT(indexSize != 0);
+
+		GLenum indicesType = 0;
+		switch(indexSize)
+		{
+		case 1:
+			indicesType = GL_UNSIGNED_BYTE;
+			break;
+		case 2:
+			indicesType = GL_UNSIGNED_SHORT;
+			break;
+		case 4:
+			indicesType = GL_UNSIGNED_INT;
+			break;
+		default:
+			ANKI_ASSERT(0);
+			break;
+		};
+
+		if(m_query._get().getResult() != GlOcclusionQuery::Result::NOT_VISIBLE)
+		{
+			glDrawElementsInstancedBaseVertexBaseInstance(
+				mode,
+				m_info.m_count,
+				indicesType,
+				(const void*)(PtrSize)(m_info.m_firstIndex * indexSize),
+				m_info.m_instanceCount,
+				m_info.m_baseVertex,
+				m_info.m_baseInstance);
+
+			ANKI_COUNTER_INC(GL_DRAWCALLS_COUNT, (U64)1);
+		}
+
+		return ErrorCode::NONE;
+	}
+};
+
+void GlCommandBufferHandle::drawElementsConditional(
+	GlOcclusionQueryHandle& query, 
+	GLenum mode, U8 indexSize, 
+	U32 count, U32 instanceCount, U32 firstIndex,
+	U32 baseVertex, U32 baseInstance)
+{
+	GlDrawElementsIndirectInfo info(count, instanceCount, firstIndex, 
+		baseVertex, baseInstance);
+
+	if(indexSize == 2)
+	{
+		switch(mode)
+		{
+		case GL_TRIANGLES:
+			_pushBackNewCommand<DrawElementsCondCommand<GL_TRIANGLES, 2>>(
+				info, query);
+			break;
+		case GL_POINTS:
+			_pushBackNewCommand<DrawElementsCondCommand<GL_POINTS, 2>>(
+				info, query);
+			break;
+		case GL_LINES:
+			_pushBackNewCommand<DrawElementsCondCommand<GL_LINES, 2>>(
+				info, query);
+			break;
+		case GL_PATCHES:
+			_pushBackNewCommand<DrawElementsCondCommand<GL_PATCHES, 2>>(
+				info, query);
+			break;
+		default:
+			ANKI_ASSERT(0 && "Not implemented");
+		}
+	}
+	else
+	{
+		ANKI_ASSERT(0 && "Not implemented");
+	}
+}
+
 } // end namespace anki
 } // end namespace anki

+ 61 - 0
src/gl/GlOcclusionQuery.cpp

@@ -0,0 +1,61 @@
+// Copyright (C) 2014, Panagiotis Christopoulos Charitos.
+// All rights reserved.
+// Code licensed under the BSD License.
+// http://www.anki3d.org/LICENSE
+
+#include "anki/gl/GlOcclusionQuery.h"
+
+namespace anki {
+
+//==============================================================================
+Error GlOcclusionQuery::create()
+{
+	glGenQueries(1, &m_glName);
+	ANKI_ASSERT(m_glName != 0);
+	return ErrorCode::NONE;
+}
+
+//==============================================================================
+void GlOcclusionQuery::begin()
+{
+	ANKI_ASSERT(isCreated());
+	glBeginQuery(GL_ANY_SAMPLES_PASSED_CONSERVATIVE, m_glName);
+}
+
+//==============================================================================
+void GlOcclusionQuery::end()
+{
+	ANKI_ASSERT(isCreated());
+	glEndQuery(GL_ANY_SAMPLES_PASSED_CONSERVATIVE);
+}
+
+//==============================================================================
+GlOcclusionQuery::Result GlOcclusionQuery::getResult()
+{
+	ANKI_ASSERT(isCreated());
+	Result result = Result::NOT_AVAILABLE;
+	GLuint params;
+	glGetQueryObjectuiv(m_glName, GL_QUERY_RESULT_AVAILABLE, &params);
+
+	if(params != 0)
+	{
+		glGetQueryObjectuiv(m_glName, GL_QUERY_RESULT, &params);
+
+		result = (params == 1) ? Result::VISIBLE : Result::NOT_VISIBLE;
+	}
+
+	return result;
+}
+
+//==============================================================================
+void GlOcclusionQuery::destroy()
+{
+	if(m_glName != 0)
+	{
+		glDeleteQueries(1, &m_glName);
+		m_glName = 0;
+	}
+}
+
+} // end namespace anki
+

+ 110 - 0
src/gl/GlOcclusionQueryHandle.cpp

@@ -0,0 +1,110 @@
+// Copyright (C) 2014, Panagiotis Christopoulos Charitos.
+// All rights reserved.
+// Code licensed under the BSD License.
+// http://www.anki3d.org/LICENSE
+
+#include "anki/gl/GlOcclusionQueryHandle.h"
+#include "anki/gl/GlOcclusionQuery.h"
+#include "anki/gl/GlHandleDeferredDeleter.h"
+
+namespace anki {
+
+//==============================================================================
+GlOcclusionQueryHandle::GlOcclusionQueryHandle()
+{}
+
+//==============================================================================
+GlOcclusionQueryHandle::~GlOcclusionQueryHandle()
+{}
+
+//==============================================================================
+Error GlOcclusionQueryHandle::create(GlCommandBufferHandle& commands)
+{
+	class Command: public GlCommand
+	{
+	public:	
+		GlOcclusionQueryHandle m_handle;
+
+		Command(GlOcclusionQueryHandle& handle)
+		:	m_handle(handle)
+		{}
+
+		Error operator()(GlCommandBuffer*)
+		{
+			Error err = m_handle._get().create();
+
+			GlHandleState oldState = m_handle._setState(
+				(err) ? GlHandleState::ERROR : GlHandleState::CREATED);
+			ANKI_ASSERT(oldState == GlHandleState::TO_BE_CREATED);
+			(void)oldState;
+
+			return err;
+		}
+	};
+
+	using Alloc = GlAllocator<GlOcclusionQuery>;
+	using DeleteCommand = GlDeleteObjectCommand<GlOcclusionQuery, Alloc>;
+	using Deleter = 
+		GlHandleDeferredDeleter<GlOcclusionQuery, Alloc, DeleteCommand>;
+
+	Error err = _createAdvanced(
+		&commands._get().getQueue().getDevice(),
+		commands._get().getGlobalAllocator(), 
+		Deleter());
+
+	if(!err)
+	{
+		_setState(GlHandleState::TO_BE_CREATED);
+
+		commands._pushBackNewCommand<Command>(*this);
+	}
+
+	return err;
+}
+
+//==============================================================================
+void GlOcclusionQueryHandle::begin(GlCommandBufferHandle& commands)
+{
+	class Command: public GlCommand
+	{
+	public:
+		GlOcclusionQueryHandle m_handle;
+
+		Command(GlOcclusionQueryHandle& handle)
+		:	m_handle(handle)
+		{}
+
+		Error operator()(GlCommandBuffer*)
+		{
+			m_handle._get().begin();
+			return ErrorCode::NONE;
+		}
+	};
+
+	commands._pushBackNewCommand<Command>(*this);
+}
+
+//==============================================================================
+void GlOcclusionQueryHandle::end(GlCommandBufferHandle& commands)
+{
+	class Command: public GlCommand
+	{
+	public:
+		GlOcclusionQueryHandle m_handle;
+
+		Command(GlOcclusionQueryHandle& handle)
+		:	m_handle(handle)
+		{}
+
+		Error operator()(GlCommandBuffer*)
+		{
+			m_handle._get().end();
+			return ErrorCode::NONE;
+		}
+	};
+
+	commands._pushBackNewCommand<Command>(*this);
+}
+
+} // end namespace anki
+

+ 4 - 3
src/resource/CMakeLists.txt

@@ -1,4 +1,5 @@
-FILE(GLOB_RECURSE ANKI_RSRC_SOURCES *.cpp)
-FILE(GLOB_RECURSE ANKI_RSRC_HEADERS *.h)
+file(GLOB_RECURSE ANKI_RSRC_SOURCES *.cpp)
+file(GLOB_RECURSE ANKI_RSRC_HEADERS *.h)
 
 
-ADD_LIBRARY(ankiresource ${ANKI_RSRC_SOURCES} ${ANKI_RSRC_HEADERS})
+add_library(ankiresource ${ANKI_RSRC_SOURCES} ${ANKI_RSRC_HEADERS})
+target_link_libraries(ankiresource ankiphysics ankigl)

+ 27 - 10
src/resource/Model.cpp

@@ -9,6 +9,7 @@
 #include "anki/resource/ProgramResource.h"
 #include "anki/resource/ProgramResource.h"
 #include "anki/misc/Xml.h"
 #include "anki/misc/Xml.h"
 #include "anki/util/Logger.h"
 #include "anki/util/Logger.h"
+#include "anki/physics/PhysicsWorld.h"
 
 
 namespace anki {
 namespace anki {
 
 
@@ -286,19 +287,25 @@ Model::Model(ResourceAllocator<U8>& alloc)
 //==============================================================================
 //==============================================================================
 Model::~Model()
 Model::~Model()
 {
 {
-	for(ModelPatchBase* patch : m_modelPatches)
+	if(m_resources)
 	{
 	{
-		m_alloc.deleteInstance(patch);
-	}
+		auto alloc = m_resources->_getAllocator();
 
 
-	m_modelPatches.destroy(m_alloc);
+		for(ModelPatchBase* patch : m_modelPatches)
+		{
+			alloc.deleteInstance(patch);
+		}
+
+		m_modelPatches.destroy(alloc);
+	}
 }
 }
 
 
 //==============================================================================
 //==============================================================================
 Error Model::load(const CString& filename, ResourceInitializer& init)
 Error Model::load(const CString& filename, ResourceInitializer& init)
 {
 {
 	Error err = ErrorCode::NONE;
 	Error err = ErrorCode::NONE;
-	m_alloc = init.m_alloc;
+	m_resources = &init.m_resources;
+	auto alloc = init.m_alloc;
 
 
 	// Load
 	// Load
 	//
 	//
@@ -321,10 +328,15 @@ Error Model::load(const CString& filename, ResourceInitializer& init)
 		XmlElement valEl;
 		XmlElement valEl;
 		ANKI_CHECK(collEl.getChildElement("value", valEl));
 		ANKI_CHECK(collEl.getChildElement("value", valEl));
 
 
+		PhysicsWorld& physics = m_resources->_getPhysicsWorld();
+		PhysicsCollisionShape::Initializer csInit;
+
 		if(type == "sphere")
 		if(type == "sphere")
 		{
 		{
 			F64 tmp;
 			F64 tmp;
 			ANKI_CHECK(valEl.getF64(tmp));
 			ANKI_CHECK(valEl.getF64(tmp));
+			m_physicsShape = physics.newCollisionShape<PhysicsSphere>(
+				csInit, tmp);
 		}
 		}
 		else if(type == "box")
 		else if(type == "box")
 		{
 		{
@@ -339,6 +351,11 @@ Error Model::load(const CString& filename, ResourceInitializer& init)
 			ANKI_LOGE("Incorrect collision type");
 			ANKI_LOGE("Incorrect collision type");
 			return ErrorCode::USER_DATA;
 			return ErrorCode::USER_DATA;
 		}
 		}
+
+		if(m_physicsShape == nullptr)
+		{
+			return ErrorCode::OUT_OF_MEMORY;
+		}
 	}
 	}
 
 
 	// <modelPatches>
 	// <modelPatches>
@@ -365,7 +382,7 @@ Error Model::load(const CString& filename, ResourceInitializer& init)
 		return ErrorCode::USER_DATA;
 		return ErrorCode::USER_DATA;
 	}
 	}
 
 
-	ANKI_CHECK(m_modelPatches.create(m_alloc, count));
+	ANKI_CHECK(m_modelPatches.create(alloc, count));
 
 
 	count = 0;
 	count = 0;
 	ANKI_CHECK(modelPatchesEl.getChildElement("modelPatch", modelPatchEl));
 	ANKI_CHECK(modelPatchesEl.getChildElement("modelPatch", modelPatchEl));
@@ -405,8 +422,8 @@ Error Model::load(const CString& filename, ResourceInitializer& init)
 
 
 			CString cstr;
 			CString cstr;
 			ANKI_CHECK(materialEl.getText(cstr));
 			ANKI_CHECK(materialEl.getText(cstr));
-			ModelPatch<MeshResourcePointer>* mpatch = m_alloc.newInstance<
-				ModelPatch<MeshResourcePointer>>(m_alloc);
+			ModelPatch<MeshResourcePointer>* mpatch = alloc.newInstance<
+				ModelPatch<MeshResourcePointer>>(alloc);
 
 
 			if(mpatch == nullptr)
 			if(mpatch == nullptr)
 			{
 			{
@@ -449,8 +466,8 @@ Error Model::load(const CString& filename, ResourceInitializer& init)
 			ANKI_CHECK(materialEl.getText(cstr));
 			ANKI_CHECK(materialEl.getText(cstr));
 
 
 			ModelPatch<BucketMeshResourcePointer>* mpatch = 
 			ModelPatch<BucketMeshResourcePointer>* mpatch = 
-				init.m_alloc.newInstance<
-				ModelPatch<BucketMeshResourcePointer>>(m_alloc);
+				alloc.newInstance<
+				ModelPatch<BucketMeshResourcePointer>>(alloc);
 
 
 			if(mpatch == nullptr)
 			if(mpatch == nullptr)
 			{
 			{

+ 32 - 17
src/scene/ModelNode.cpp

@@ -6,6 +6,7 @@
 #include "anki/scene/ModelNode.h"
 #include "anki/scene/ModelNode.h"
 #include "anki/scene/SceneGraph.h"
 #include "anki/scene/SceneGraph.h"
 #include "anki/scene/InstanceNode.h"
 #include "anki/scene/InstanceNode.h"
+#include "anki/scene/BodyComponent.h"
 #include "anki/scene/Misc.h"
 #include "anki/scene/Misc.h"
 #include "anki/resource/Model.h"
 #include "anki/resource/Model.h"
 #include "anki/resource/Skeleton.h"
 #include "anki/resource/Skeleton.h"
@@ -205,13 +206,16 @@ ModelNode::~ModelNode()
 {
 {
 	m_modelPatches.destroy(getSceneAllocator());
 	m_modelPatches.destroy(getSceneAllocator());
 	m_transforms.destroy(getSceneAllocator());
 	m_transforms.destroy(getSceneAllocator());
-#if 0
-	RigidBody* body = tryGetComponent<RigidBody>();
-	if(body)
+
+	if(m_bodyComp)
+	{
+		getSceneAllocator().deleteInstance(m_bodyComp);
+	}
+
+	if(m_body)
 	{
 	{
-		getSceneGraph().getPhysics().deletePhysicsObject(body);
+		getSceneAllocator().deleteInstance(m_body);
 	}
 	}
-#endif
 }
 }
 
 
 //==============================================================================
 //==============================================================================
@@ -257,22 +261,33 @@ Error ModelNode::create(const CString& name, const CString& modelFname)
 	}
 	}
 
 
 	// Load rigid body
 	// Load rigid body
-#if 0
-	if(m_model->getCollisionShape() != nullptr)
+	const PhysicsCollisionShape* shape = m_model->getPhysicsCollisionShape();
+	if(shape != nullptr)
 	{
 	{
-		RigidBody::Initializer init;
-		init.mass = 1.0;
-		init.shape = const_cast<btCollisionShape*>(m_model->getCollisionShape());
-		init.node = this;
+		PhysicsBody::Initializer init;
+		init.m_mass = 1.0;
+		init.m_shape = shape;
 
 
-		RigidBody* body;
-		
-		getSceneGraph().getPhysics().newPhysicsObject<RigidBody>(
-			body, init);
+		m_body = 
+			getSceneGraph()._getPhysicsWorld().newBody<PhysicsBody>(init);
+		if(m_body == nullptr)
+		{
+			return ErrorCode::OUT_OF_MEMORY;
+		}
+
+		m_bodyComp = 
+			getSceneAllocator().newInstance<BodyComponent>(this, m_body);
+		if(m_bodyComp == nullptr)
+		{
+			return ErrorCode::OUT_OF_MEMORY;
+		}
 
 
-		addComponent(static_cast<RigidBody*>(body));
+		err = addComponent(m_bodyComp);
+		if(err)
+		{
+			return err;
+		}
 	}
 	}
-#endif
 
 
 	return err;
 	return err;
 }
 }

+ 5 - 1
src/scene/SceneGraph.cpp

@@ -9,6 +9,7 @@
 #include "anki/scene/InstanceNode.h"
 #include "anki/scene/InstanceNode.h"
 #include "anki/core/Counters.h"
 #include "anki/core/Counters.h"
 #include "anki/renderer/Renderer.h"
 #include "anki/renderer/Renderer.h"
+#include "anki/physics/PhysicsWorld.h"
 
 
 namespace anki {
 namespace anki {
 
 
@@ -109,6 +110,7 @@ Error SceneGraph::create(
 	m_objectsMarkedForDeletionCount.store(0);
 	m_objectsMarkedForDeletionCount.store(0);
 	m_ambientCol = Vec3(0.0);
 	m_ambientCol = Vec3(0.0);
 	m_gl = &m_resources->_getGlDevice();
 	m_gl = &m_resources->_getGlDevice();
+	m_physics = &m_resources->_getPhysicsWorld();
 
 
 	m_alloc = SceneAllocator<U8>(
 	m_alloc = SceneAllocator<U8>(
 		allocCb, allocCbData, 
 		allocCb, allocCbData, 
@@ -260,8 +262,10 @@ Error SceneGraph::update(F32 prevUpdateTime, F32 crntTime, Renderer& renderer)
 	Threadpool& threadPool = *m_threadpool;
 	Threadpool& threadPool = *m_threadpool;
 	(void)threadPool;
 	(void)threadPool;
 
 
-	//m_physics.update(prevUpdateTime, crntTime);
+	// Update
+	m_physics->updateAsync(crntTime - prevUpdateTime);
 	renderer.getTiler().updateTiles(*m_mainCam);
 	renderer.getTiler().updateTiles(*m_mainCam);
+	m_physics->waitUpdate();
 	err = m_events.updateAllEvents(prevUpdateTime, crntTime);
 	err = m_events.updateAllEvents(prevUpdateTime, crntTime);
 	if(err) return err;
 	if(err) return err;
 
 

+ 1 - 1
tools/scene/Model.cpp

@@ -277,7 +277,7 @@ void exportMaterial(
 	// Diffuse texture
 	// Diffuse texture
 	if(mtl.GetTextureCount(aiTextureType_DIFFUSE) < 1)
 	if(mtl.GetTextureCount(aiTextureType_DIFFUSE) < 1)
 	{
 	{
-		ERROR("Material has no diffuse textures\n");
+		ERROR("Material has no diffuse textures. Skipping\n");
 	}
 	}
 
 
 	aiString path;
 	aiString path;