Kaynağa Gözat

Merge branch 'master' of https://github.com/taylor001/crown

Conflicts:
	engine/lua/LuaPhysicsWorld.cpp
mikymod 12 yıl önce
ebeveyn
işleme
604b40146e
43 değiştirilmiş dosya ile 616 ekleme ve 500 silme
  1. 1 1
      engine/CMakeLists.txt
  2. 1 0
      engine/ConsoleServer.cpp
  3. 2 0
      engine/core/Macros.h
  4. 1 1
      engine/core/filesystem/DiskFile.cpp
  5. 1 0
      engine/core/filesystem/File.cpp
  6. 1 0
      engine/core/json/JSONParser.h
  7. 1 1
      engine/core/math/MathUtils.h
  8. 10 38
      engine/core/mem/Allocator.h
  9. 5 1
      engine/core/mem/LinearAllocator.cpp
  10. 11 11
      engine/core/mem/LinearAllocator.h
  11. 1 1
      engine/core/mem/Memory.cpp
  12. 28 2
      engine/core/mem/Memory.h
  13. 1 0
      engine/core/mem/PoolAllocator.cpp
  14. 11 13
      engine/core/mem/PoolAllocator.h
  15. 6 6
      engine/core/mem/ProxyAllocator.cpp
  16. 14 16
      engine/core/mem/ProxyAllocator.h
  17. 6 6
      engine/core/mem/StackAllocator.cpp
  18. 9 9
      engine/core/mem/StackAllocator.h
  19. 15 11
      engine/core/mem/TempAllocator.h
  20. 1 1
      engine/core/strings/DynamicString.h
  21. 138 35
      engine/lua/LuaActor.cpp
  22. 2 1
      engine/lua/LuaPhysicsWorld.cpp
  23. 0 29
      engine/lua/LuaSprite.cpp
  24. 0 12
      engine/lua/LuaVector2.cpp
  25. 0 12
      engine/lua/LuaVector3.cpp
  26. 1 0
      engine/os/linux/main.cpp
  27. 193 84
      engine/physics/Actor.cpp
  28. 61 45
      engine/physics/Actor.h
  29. 2 2
      engine/physics/PhysicsCallback.h
  30. 7 38
      engine/physics/PhysicsWorld.cpp
  31. 0 5
      engine/physics/PhysicsWorld.h
  32. 0 41
      engine/renderers/Sprite.cpp
  33. 0 16
      engine/renderers/Sprite.h
  34. 1 1
      engine/renderers/backend/gl/GLRenderer.cpp
  35. 1 1
      engine/resource/FileBundle.cpp
  36. 1 0
      engine/resource/FontResource.h
  37. 52 56
      engine/resource/PhysicsResource.cpp
  38. 25 2
      engine/resource/PhysicsResource.h
  39. 1 0
      engine/resource/UnitResource.cpp
  40. 1 0
      engine/world/SceneGraph.cpp
  41. 1 0
      engine/world/SceneGraphManager.cpp
  42. 1 1
      engine/world/Unit.cpp
  43. 2 1
      engine/world/World.cpp

+ 1 - 1
engine/CMakeLists.txt

@@ -486,7 +486,7 @@ if (LINUX)
 		#-pedantic-errors
 		-Wall
 		-Wextra
-		#-Werror
+		-Werror
 		-Wno-long-long
 		-Wno-variadic-macros
 		-Wno-unknown-pragmas

+ 1 - 0
engine/ConsoleServer.cpp

@@ -35,6 +35,7 @@ OTHER DEALINGS IN THE SOFTWARE.
 #include "File.h"
 #include "Filesystem.h"
 #include "MathUtils.h"
+#include "Memory.h"
 
 namespace crown
 {

+ 2 - 0
engine/core/Macros.h

@@ -24,6 +24,8 @@ FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
 OTHER DEALINGS IN THE SOFTWARE.
 */
 
+#pragma once
+
 #ifdef _MSC_VER
 	#define CE_ALIGNOF(x) __alignof(x)
 	#define CE_EXPORT __declspec(dllexport)

+ 1 - 1
engine/core/filesystem/DiskFile.cpp

@@ -28,7 +28,7 @@ OTHER DEALINGS IN THE SOFTWARE.
 #include "Types.h"
 #include "Log.h"
 #include "MathUtils.h"
-#include "Allocator.h"
+#include "Memory.h"
 
 namespace crown
 {

+ 1 - 0
engine/core/filesystem/File.cpp

@@ -27,6 +27,7 @@ OTHER DEALINGS IN THE SOFTWARE.
 #include "File.h"
 #include "Types.h"
 #include "Compressor.h"
+#include "Memory.h"
 
 namespace crown
 {

+ 1 - 0
engine/core/json/JSONParser.h

@@ -28,6 +28,7 @@ OTHER DEALINGS IN THE SOFTWARE.
 
 #include "Types.h"
 #include "ContainerTypes.h"
+#include "Macros.h"
 
 namespace crown
 {

+ 1 - 1
engine/core/math/MathUtils.h

@@ -30,7 +30,7 @@ OTHER DEALINGS IN THE SOFTWARE.
 
 #include "Assert.h"
 #include "Types.h"
-#include "Allocator.h"
+#include "Memory.h"
 
 namespace crown
 {

+ 10 - 38
engine/core/mem/Allocator.h

@@ -26,10 +26,7 @@ OTHER DEALINGS IN THE SOFTWARE.
 
 #pragma once
 
-#include <new>
-
 #include "Types.h"
-#include "Memory.h"
 
 namespace crown
 {
@@ -41,52 +38,27 @@ class Allocator
 {
 public:
 
-						Allocator() {}
-	virtual				~Allocator() {}
+	Allocator() {}
+	virtual	~Allocator() {}
 
 	/// Allocates @a size bytes of memory aligned to the specified
 	/// @a align byte and returns a pointer to the first allocated byte.
-	virtual void*		allocate(size_t size, size_t align = memory::DEFAULT_ALIGN) = 0;
+	virtual void* allocate(size_t size, size_t align = DEFAULT_ALIGN) = 0;
 
 	/// Deallocates a previously allocated block of memory pointed by @a data.
-	virtual void		deallocate(void* data) = 0;
+	virtual void deallocate(void* data) = 0;
 
 	/// Returns the total number of bytes allocated.
-	virtual size_t		allocated_size() = 0;
+	virtual size_t allocated_size() = 0;
+
+	/// Default memory alignment in bytes.
+	static const size_t DEFAULT_ALIGN = 4;
 
 private:
 
 	// Disable copying
-						Allocator(const Allocator&);
-	Allocator&			operator=(const Allocator&);
+	Allocator(const Allocator&);
+	Allocator& operator=(const Allocator&);
 };
 
-CE_EXPORT Allocator& default_allocator();
-
-/// Respects standard behaviour when calling on NULL @a ptr
-template <typename T>
-inline void call_destructor_and_deallocate(Allocator& a, T* ptr)
-{
-	if (ptr != NULL)
-	{
-		ptr->~T();
-
-		a.deallocate(ptr);
-	}
-}
-
-/// Allocates memory with @a allocator for the given @a T type
-/// and calls constructor on it.
-/// @note
-/// @a allocator must be a reference to an existing allocator.
-#define CE_NEW(allocator, T)\
-	new ((allocator).allocate(sizeof(T), CE_ALIGNOF(T))) T
-
-/// Calls destructor on @a ptr and deallocates memory using the
-/// given @a allocator.
-/// @note
-/// @a allocator must be a reference to an existing allocator.
-#define CE_DELETE(allocator, ptr)\
-	call_destructor_and_deallocate(allocator, ptr)
-
 } // namespace crown

+ 5 - 1
engine/core/mem/LinearAllocator.cpp

@@ -25,13 +25,17 @@ OTHER DEALINGS IN THE SOFTWARE.
 */
 
 #include "LinearAllocator.h"
+#include "Memory.h"
 
 namespace crown
 {
 
 //-----------------------------------------------------------------------------
 LinearAllocator::LinearAllocator(Allocator& backing, size_t size)
-	: m_backing(&backing), m_physical_start(NULL), m_total_size(size), m_offset(0)
+	: m_backing(&backing)
+	, m_physical_start(NULL)
+	, m_total_size(size)
+	, m_offset(0)
 {
 	m_physical_start = backing.allocate(size);
 }

+ 11 - 11
engine/core/mem/LinearAllocator.h

@@ -39,32 +39,32 @@ class LinearAllocator : public Allocator
 {
 public:
 
-				LinearAllocator(Allocator& backing, size_t size);
-				LinearAllocator(void* start, size_t size);
-				~LinearAllocator();
+	LinearAllocator(Allocator& backing, size_t size);
+	LinearAllocator(void* start, size_t size);
+	~LinearAllocator();
 
 	/// @copydoc Allocator::allocate()
-	void*		allocate(size_t size, size_t align = memory::DEFAULT_ALIGN);
+	void* allocate(size_t size, size_t align = Allocator::DEFAULT_ALIGN);
 
 	/// @copydoc Allocator::deallocate()
 	/// @note
 	/// The linear allocator does not support deallocating
 	/// individual allocations, rather you have to call
 	/// clear() to free all memory at once.
-	void		deallocate(void* data);
+	void deallocate(void* data);
 
 	/// Frees all the allocations made by allocate()
-	void		clear();
+	void clear();
 
 	/// @copydoc Allocator::allocated_size()
-	size_t		allocated_size();
+	size_t allocated_size();
 
 private:
 
-	Allocator*	m_backing;
-	void*		m_physical_start;
-	size_t		m_total_size;
-	size_t		m_offset;
+	Allocator* m_backing;
+	void* m_physical_start;
+	size_t m_total_size;
+	size_t m_offset;
 };
 
 } // namespace crown

+ 1 - 1
engine/core/mem/Memory.cpp

@@ -79,7 +79,7 @@ public:
 	}
 
 	/// @copydoc Allocator::allocate()
-	void* allocate(size_t size, size_t align = memory::DEFAULT_ALIGN)
+	void* allocate(size_t size, size_t align = Allocator::DEFAULT_ALIGN)
 	{
 		ScopedMutex sm(m_mutex);
 

+ 28 - 2
engine/core/mem/Memory.h

@@ -26,18 +26,22 @@ OTHER DEALINGS IN THE SOFTWARE.
 
 #pragma once
 
+#include <new>
 #include "Types.h"
 #include "Assert.h"
+#include "Allocator.h"
 
 namespace crown
 {
 
+CE_EXPORT Allocator& default_allocator();
+
 /// @defgroup Memory Memory
 namespace memory
 {
 
-const uint32_t	PADDING_VALUE	= 0xFFFFFFFFu;	//!< Value used to fill unused memory
-const size_t	DEFAULT_ALIGN	= 4;			//!< Default memory alignment in bytes
+/// Value used to fill unused memory
+const uint32_t PADDING_VALUE = 0xFFFFFFFFu;
 
 /// Constructs the initial default allocators.
 /// @note
@@ -67,5 +71,27 @@ inline void* align_top(void* p, size_t align)
 	return (void*) ptr;
 }
 
+/// Respects standard behaviour when calling on NULL @a ptr
+template <typename T>
+inline void call_destructor_and_deallocate(Allocator& a, T* ptr)
+{
+	if (!ptr)
+		return;
+
+	ptr->~T();
+	a.deallocate(ptr);
+}
+
+/// Allocates memory with @a allocator for the given @a T type
+/// and calls constructor on it.
+/// @note
+/// @a allocator must be a reference to an existing allocator.
+#define CE_NEW(allocator, T) new ((allocator).allocate(sizeof(T), CE_ALIGNOF(T))) T
+
+/// Calls destructor on @a ptr and deallocates memory using the
+/// given @a allocator.
+/// @note
+/// @a allocator must be a reference to an existing allocator.
+#define CE_DELETE(allocator, ptr) crown::memory::call_destructor_and_deallocate(allocator, ptr)
 } // namespace memory
 } // namespace crown

+ 1 - 0
engine/core/mem/PoolAllocator.cpp

@@ -25,6 +25,7 @@ OTHER DEALINGS IN THE SOFTWARE.
 */
 
 #include "PoolAllocator.h"
+#include "Assert.h"
 
 namespace crown
 {

+ 11 - 13
engine/core/mem/PoolAllocator.h

@@ -26,8 +26,6 @@ OTHER DEALINGS IN THE SOFTWARE.
 
 #pragma once
 
-#include "Types.h"
-#include "Memory.h"
 #include "Allocator.h"
 
 namespace crown
@@ -43,31 +41,31 @@ public:
 
 	/// Uses @a backing to allocate the memory pool for containing exactly
 	/// @a num_blocks blocks of @a block_size size each aligned to @a block_align.
-				PoolAllocator(Allocator& backing, size_t num_blocks, size_t block_size, size_t block_align = memory::DEFAULT_ALIGN);
-				~PoolAllocator();
+	PoolAllocator(Allocator& backing, size_t num_blocks, size_t block_size, size_t block_align = Allocator::DEFAULT_ALIGN);
+	~PoolAllocator();
 
 	/// Allocates a block of memory from the memory pool.
 	/// @note
 	/// The @a size and @a align must match those passed to PoolAllocator::PoolAllocator()
-	void*		allocate(size_t size, size_t align = memory::DEFAULT_ALIGN);
+	void* allocate(size_t size, size_t align = Allocator::DEFAULT_ALIGN);
 
 	/// @copydoc Allocator::deallocate()
-	void		deallocate(void* data);
+	void deallocate(void* data);
 
 	/// @copydoc Allocator::allocated_size()
-	size_t		allocated_size();
+	size_t allocated_size();
 
 private:
 
 	Allocator&	m_backing;
 
-	void*		m_start;
-	void*		m_freelist;
-	size_t		m_block_size;
-	size_t		m_block_align;
+	void* m_start;
+	void* m_freelist;
+	size_t m_block_size;
+	size_t m_block_align;
 
-	uint32_t	m_num_allocations;
-	size_t		m_allocated_size;
+	uint32_t m_num_allocations;
+	size_t m_allocated_size;
 };
 
 } // namespace crown

+ 6 - 6
engine/core/mem/ProxyAllocator.cpp

@@ -26,8 +26,8 @@ OTHER DEALINGS IN THE SOFTWARE.
 
 #include "Assert.h"
 #include "ProxyAllocator.h"
-#include "Allocator.h"
 #include "StringUtils.h"
+#include "ScopedMutex.h"
 
 namespace crown
 {
@@ -36,11 +36,11 @@ static ProxyAllocator* g_proxy_allocators_head = NULL;
 static Mutex g_proxy_allocators_mutex;
 
 //-----------------------------------------------------------------------------
-ProxyAllocator::ProxyAllocator(const char* name, Allocator& allocator) :
-	m_allocator(allocator),
-	m_name(name),
-	m_total_allocated(0),
-	m_next(NULL)
+ProxyAllocator::ProxyAllocator(const char* name, Allocator& allocator)
+	: m_allocator(allocator)
+	, m_name(name)
+	, m_total_allocated(0)
+	, m_next(NULL)
 {
 	ScopedMutex sm(g_proxy_allocators_mutex);
 

+ 14 - 16
engine/core/mem/ProxyAllocator.h

@@ -26,10 +26,8 @@ OTHER DEALINGS IN THE SOFTWARE.
 
 #pragma once
 
-#include "Types.h"
-#include "Memory.h"
 #include "Allocator.h"
-#include "ScopedMutex.h"
+#include "Macros.h"
 
 namespace crown
 {
@@ -44,44 +42,44 @@ class CE_EXPORT ProxyAllocator : public Allocator
 public:
 
 	/// Tag all allocations made with @a allocator by the given @a name
-							ProxyAllocator(const char* name, Allocator& allocator);
+	ProxyAllocator(const char* name, Allocator& allocator);
 
 	/// @copydoc Allocator::allocate()
-	void*					allocate(size_t size, size_t align = memory::DEFAULT_ALIGN);
+	void* allocate(size_t size, size_t align = Allocator::DEFAULT_ALIGN);
 
 	/// @copydoc Allocator::deallocate()
-	void					deallocate(void* data);
+	void deallocate(void* data);
 
 	/// @copydoc Allocator::allocated_size()
-	size_t					allocated_size();
+	size_t allocated_size();
 
 	/// Returns the name of the proxy allocator
-	const char*				name() const;
+	const char* name() const;
 
 public:
 
 	/// Returns the total number of proxy allocators.
 	/// in the global list.
-	static uint32_t			count();
+	static uint32_t count();
 
 	/// Returns the proxy allocator @name or NULL if not found.
-	static ProxyAllocator*	find(const char* name);
+	static ProxyAllocator* find(const char* name);
 
 	/// Returns the first proxy allocator in the global list or
 	/// NULL if the list is empty.
-	static ProxyAllocator*	begin();
+	static ProxyAllocator* begin();
 
 	/// Returns the next proxy allocator to @a a in the global list
 	/// or NULL if end-of-list is reached.
-	static ProxyAllocator*	next(ProxyAllocator* a);
+	static ProxyAllocator* next(ProxyAllocator* a);
 
 private:
 
-	Allocator&				m_allocator;
-	const char*				m_name;
-	size_t					m_total_allocated;
+	Allocator& m_allocator;
+	const char* m_name;
+	size_t m_total_allocated;
 
-	ProxyAllocator*			m_next;
+	ProxyAllocator* m_next;
 };
 
 } // namespace crown

+ 6 - 6
engine/core/mem/StackAllocator.cpp

@@ -25,17 +25,17 @@ OTHER DEALINGS IN THE SOFTWARE.
 */
 
 #include "StackAllocator.h"
-#include "OS.h"
+#include "Memory.h"
 
 namespace crown
 {
 
 //-----------------------------------------------------------------------------
-StackAllocator::StackAllocator(void* start, size_t size) :
-	m_physical_start(start),
-	m_total_size(size),
-	m_top(start),
-	m_allocation_count(0)
+StackAllocator::StackAllocator(void* start, size_t size)
+	: m_physical_start(start)
+	, m_total_size(size)
+	, m_top(start)
+	, m_allocation_count(0)
 {
 }
 

+ 9 - 9
engine/core/mem/StackAllocator.h

@@ -40,20 +40,20 @@ class StackAllocator : public Allocator
 {
 public:
 
-				StackAllocator(void* start, size_t size);
-				~StackAllocator();
+	StackAllocator(void* start, size_t size);
+	~StackAllocator();
 
 	/// @copydoc Allocator::allocate()
-	void*		allocate(size_t size, size_t align = memory::DEFAULT_ALIGN);
+	void* allocate(size_t size, size_t align = Allocator::DEFAULT_ALIGN);
 
 	/// @copydoc Allocator::deallocate()
 	/// @note
 	/// Deallocations must occur in LIFO order i.e. the
 	/// last allocation must be freed for first.
-	void		deallocate(void* data);
+	void deallocate(void* data);
 
 	/// @copydoc Allocator::allocated_size()
-	size_t		allocated_size();
+	size_t allocated_size();
 
 private:
 
@@ -63,12 +63,12 @@ private:
 		uint32_t alloc_id;
 	};
 
-	void*		m_physical_start;
-	size_t		m_total_size;
+	void* m_physical_start;
+	size_t m_total_size;
 
-	void*		m_top;
+	void* m_top;
 
-	uint32_t	m_allocation_count;
+	uint32_t m_allocation_count;
 };
 
 } // namespace crown

+ 15 - 11
engine/core/mem/TempAllocator.h

@@ -27,6 +27,7 @@ OTHER DEALINGS IN THE SOFTWARE.
 #pragma once
 
 #include "Allocator.h"
+#include "Memory.h"
 
 namespace crown
 {
@@ -44,28 +45,28 @@ public:
 
 	/// Uses the @a backing allocator when internal memory is exahusted
 	/// or the allocation size exceeds the remaining storage.
-				TempAllocator(Allocator& backing = default_allocator());
-				~TempAllocator();
+	TempAllocator(Allocator& backing = default_allocator());
+	~TempAllocator();
 
 	/// @copydoc Allocator::allocate()
-	void*		allocate(size_t size, size_t align = memory::DEFAULT_ALIGN);
+	void* allocate(size_t size, size_t align = Allocator::DEFAULT_ALIGN);
 
 	/// Does nothing, the memory is automatically freed when the
 	/// allocator is destroyed.
-	void		deallocate(void* data);
+	void deallocate(void* data);
 
 	/// @copydoc Allocator::allocated_size()
-	size_t		allocated_size();
+	size_t allocated_size();
 
 private:
 
 	Allocator&	m_backing;
 
-	char*		m_begin;
-	char*		m_end;
-	char*		m_cur;
-	size_t		m_chunk_size;
-	char		m_buffer[SIZE];
+	char* m_begin;
+	char* m_end;
+	char* m_cur;
+	size_t m_chunk_size;
+	char m_buffer[SIZE];
 };
 
 typedef TempAllocator<64> TempAllocator64;
@@ -93,7 +94,10 @@ inline TempAllocator<SIZE>::TempAllocator(Allocator& backing)
 template <size_t SIZE>
 inline TempAllocator<SIZE>::~TempAllocator()
 {
-	void *p = *(void **)m_buffer;
+	union { char* as_char; void** as_dvoid; };
+	as_char = m_buffer;
+
+	void *p = *(void **)as_dvoid;
 	while (p)
 	{
 		void *next = *(void **)p;

+ 1 - 1
engine/core/strings/DynamicString.h

@@ -30,7 +30,7 @@ OTHER DEALINGS IN THE SOFTWARE.
 #include <cstring>
 
 #include "Assert.h"
-#include "Allocator.h"
+#include "Memory.h"
 #include "StringUtils.h"
 #include "Array.h"
 #include "StringUtils.h"

+ 138 - 35
engine/lua/LuaActor.cpp

@@ -31,6 +31,72 @@ OTHER DEALINGS IN THE SOFTWARE.
 namespace crown
 {
 
+//-----------------------------------------------------------------------------
+static int actor_world_position(lua_State* L)
+{
+	LuaStack stack(L);
+	Actor* actor = stack.get_actor(1);
+	stack.push_vector3(actor->world_position());
+	return 1;
+}
+
+//-----------------------------------------------------------------------------
+static int actor_world_rotation(lua_State* L)
+{
+	LuaStack stack(L);
+	Actor* actor = stack.get_actor(1);
+	stack.push_quaternion(actor->world_rotation());
+	return 1;
+}
+
+//-----------------------------------------------------------------------------
+static int actor_world_pose(lua_State* L)
+{
+	LuaStack stack(L);
+	Actor* actor = stack.get_actor(1);
+	stack.push_matrix4x4(actor->world_pose());
+	return 1;
+}
+
+//-----------------------------------------------------------------------------
+static int actor_teleport_world_position(lua_State* L)
+{
+	LuaStack stack(L);
+	Actor* actor = stack.get_actor(1);
+	const Vector3& pos = stack.get_vector3(2);
+	actor->teleport_world_position(pos);
+	return 0;
+}
+
+//-----------------------------------------------------------------------------
+static int actor_teleport_world_rotation(lua_State* L)
+{
+	LuaStack stack(L);
+	Actor* actor = stack.get_actor(1);
+	const Quaternion& rot = stack.get_quaternion(2);
+	actor->teleport_world_rotation(rot);
+	return 0;
+}
+
+//-----------------------------------------------------------------------------
+static int actor_teleport_world_pose(lua_State* L)
+{
+	LuaStack stack(L);
+	Actor* actor = stack.get_actor(1);
+	const Matrix4x4& mat = stack.get_matrix4x4(2);
+	actor->teleport_world_pose(mat);
+	return 0;
+}
+
+//-----------------------------------------------------------------------------
+static int actor_center_of_mass(lua_State* L)
+{
+	LuaStack stack(L);
+	Actor* actor = stack.get_actor(1);
+	stack.push_vector3(actor->center_of_mass());
+	return 1;
+}
+
 //-----------------------------------------------------------------------------
 static int actor_enable_gravity(lua_State* L)
 {
@@ -75,24 +141,20 @@ static int actor_disable_collision(lua_State* L)
 }
 
 //-----------------------------------------------------------------------------
-static int actor_set_kinematic(lua_State* L)
+static int actor_set_collision_filter(lua_State* L)
 {
 	LuaStack stack(L);
 	Actor* actor = stack.get_actor(1);
-
-	actor->set_kinematic();
-
+	actor->set_collision_filter(stack.get_string(2));
 	return 0;
 }
 
 //-----------------------------------------------------------------------------
-static int actor_clear_kinematic(lua_State* L)
+static int actor_set_kinematic(lua_State* L)
 {
 	LuaStack stack(L);
 	Actor* actor = stack.get_actor(1);
-
-	actor->clear_kinematic();
-
+	actor->set_kinematic(stack.get_bool(2));
 	return 0;
 }
 
@@ -141,6 +203,18 @@ static int actor_is_kinematic(lua_State* L)
 	return 1;
 }
 
+//-----------------------------------------------------------------------------
+static int actor_is_nonkinematic(lua_State* L)
+{
+	LuaStack stack(L);
+
+	Actor* actor = stack.get_actor(1);
+
+	stack.push_bool(actor->is_nonkinematic());
+	return 1;
+}
+
+
 //-----------------------------------------------------------------------------
 static int actor_linear_damping(lua_State* L)
 {
@@ -260,6 +334,15 @@ static int actor_add_impulse_at(lua_State* L)
 	return 0;
 }
 
+//-----------------------------------------------------------------------------
+static int actor_add_torque_impulse(lua_State* L)
+{
+	LuaStack stack(L);
+	Actor* actor = stack.get_actor(1);
+	actor->add_torque_impulse(stack.get_vector3(2));
+	return 0;
+}
+
 //-----------------------------------------------------------------------------
 static int actor_push(lua_State* L)
 {
@@ -274,6 +357,16 @@ static int actor_push(lua_State* L)
 	return 0;
 }
 
+//-----------------------------------------------------------------------------
+static int actor_push_at(lua_State* L)
+{
+	LuaStack stack(L);
+
+	Actor* actor = stack.get_actor(1);
+	actor->push_at(stack.get_vector3(2), stack.get_float(2), stack.get_vector3(3));
+	return 0;
+}
+
 //-----------------------------------------------------------------------------
 static int actor_is_sleeping(lua_State* L)
 {
@@ -312,30 +405,40 @@ static int actor_unit(lua_State* L)
 //-----------------------------------------------------------------------------
 void load_actor(LuaEnvironment& env)
 {
-	env.load_module_function("Actor", "enable_gravity",			actor_enable_gravity);
-	env.load_module_function("Actor", "disable_gravity",		actor_disable_gravity);
-	env.load_module_function("Actor", "enable_collision",		actor_enable_collision);
-	env.load_module_function("Actor", "disable_collision",		actor_disable_collision);
-	env.load_module_function("Actor", "set_kinematic",			actor_set_kinematic);
-	env.load_module_function("Actor", "clear_kinematic",		actor_clear_kinematic);
-	env.load_module_function("Actor", "move",					actor_move);
-	env.load_module_function("Actor", "is_static",				actor_is_static);
-	env.load_module_function("Actor", "is_dynamic",				actor_is_dynamic);
-	env.load_module_function("Actor", "is_kinematic",			actor_is_kinematic);
-	env.load_module_function("Actor", "linear_damping",			actor_linear_damping);
-	env.load_module_function("Actor", "set_linear_damping",		actor_set_linear_damping);
-	env.load_module_function("Actor", "angular_damping",		actor_angular_damping);
-	env.load_module_function("Actor", "set_angular_damping",	actor_set_angular_damping);
-	env.load_module_function("Actor", "linear_velocity",		actor_linear_velocity);
-	env.load_module_function("Actor", "set_linear_velocity",	actor_set_linear_velocity);
-	env.load_module_function("Actor", "angular_velocity",		actor_angular_velocity);
-	env.load_module_function("Actor", "set_angular_velocity",	actor_set_angular_velocity);
-	env.load_module_function("Actor", "add_impulse",			actor_add_impulse);
-	env.load_module_function("Actor", "add_impulse_at",			actor_add_impulse_at);
-	env.load_module_function("Actor", "push",					actor_push);
-	env.load_module_function("Actor", "is_sleeping",			actor_is_sleeping);
-	env.load_module_function("Actor", "wake_up",				actor_wake_up);
-	env.load_module_function("Actor", "unit",					actor_unit);
-}
-
-} // namespace crown
+	env.load_module_function("Actor", "world_position", 			actor_world_position);
+	env.load_module_function("Actor", "world_rotation", 			actor_world_rotation);
+	env.load_module_function("Actor", "world_pose", 				actor_world_pose);
+	env.load_module_function("Actor", "teleport_world_position",	actor_teleport_world_position);
+	env.load_module_function("Actor", "teleport_world_rotation",	actor_teleport_world_rotation);
+	env.load_module_function("Actor", "teleport_world_pose",		actor_teleport_world_pose);
+	env.load_module_function("Actor", "center_of_mass",				actor_center_of_mass);
+	env.load_module_function("Actor", "enable_gravity",				actor_enable_gravity);
+	env.load_module_function("Actor", "disable_gravity",			actor_disable_gravity);
+	env.load_module_function("Actor", "enable_collision",			actor_enable_collision);
+	env.load_module_function("Actor", "set_collision_filter",		actor_set_collision_filter);
+	env.load_module_function("Actor", "disable_collision",			actor_disable_collision);
+	env.load_module_function("Actor", "set_kinematic",				actor_set_kinematic);
+	env.load_module_function("Actor", "move",						actor_move);
+	env.load_module_function("Actor", "is_static",					actor_is_static);
+	env.load_module_function("Actor", "is_dynamic",					actor_is_dynamic);
+	env.load_module_function("Actor", "is_kinematic",				actor_is_kinematic);
+	env.load_module_function("Actor", "is_nonkinematic",			actor_is_nonkinematic);
+	env.load_module_function("Actor", "linear_damping",				actor_linear_damping);
+	env.load_module_function("Actor", "set_linear_damping",			actor_set_linear_damping);
+	env.load_module_function("Actor", "angular_damping",			actor_angular_damping);
+	env.load_module_function("Actor", "set_angular_damping",		actor_set_angular_damping);
+	env.load_module_function("Actor", "linear_velocity",			actor_linear_velocity);
+	env.load_module_function("Actor", "set_linear_velocity",		actor_set_linear_velocity);
+	env.load_module_function("Actor", "angular_velocity",			actor_angular_velocity);
+	env.load_module_function("Actor", "set_angular_velocity",		actor_set_angular_velocity);
+	env.load_module_function("Actor", "add_impulse",				actor_add_impulse);
+	env.load_module_function("Actor", "add_impulse_at",				actor_add_impulse_at);
+	env.load_module_function("Actor", "add_torque_impulse",			actor_add_torque_impulse);
+	env.load_module_function("Actor", "push",						actor_push);
+	env.load_module_function("Actor", "push_at",					actor_push_at);
+	env.load_module_function("Actor", "is_sleeping",				actor_is_sleeping);
+	env.load_module_function("Actor", "wake_up",					actor_wake_up);
+	env.load_module_function("Actor", "unit",						actor_unit);
+}
+
+} // namespace crown

+ 2 - 1
engine/lua/LuaPhysicsWorld.cpp

@@ -61,7 +61,7 @@ static int physics_world_make_raycast(lua_State* L)
 	LuaStack stack(L);
 
 	PhysicsWorld* world = stack.get_physics_world(1);
-	const char* callback = stack.get_string(2);
+	/* const char* callback = */ stack.get_string(2);
 	int mode = stack.get_int(3);
 	int filter = stack.get_int(4);
 
@@ -83,6 +83,7 @@ static int physics_world_overlap_test(lua_State* L)
 	Quaternion rot = stack.get_quaternion(5);
 	Vector3 size = stack.get_vector3(6);
 
+
 	Array<Actor*> actors(default_allocator());
 
 	world->overlap_test(filter, shape_type, pos, rot, size, actors);

+ 0 - 29
engine/lua/LuaSprite.cpp

@@ -110,32 +110,6 @@ static int sprite_set_local_pose(lua_State* L)
 	return 0;
 }
 
-//-----------------------------------------------------------------------------
-static int sprite_play_animation(lua_State* L)
-{
-	LuaStack stack(L);
-
-	Sprite* sprite = stack.get_sprite(1);
-	uint32_t start = stack.get_int(2);
-	uint32_t end = stack.get_int(3);
-	float time = stack.get_float(4);
-	bool loop = stack.get_bool(5);
-
-	sprite->play_animation(start, end, time, loop);
-	return 0;
-}
-
-//-----------------------------------------------------------------------------
-static int sprite_stop_animation(lua_State* L)
-{
-	LuaStack stack(L);
-
-	Sprite* sprite = stack.get_sprite(1);
-
-	sprite->stop_animation();
-	return 0;
-}
-
 //-----------------------------------------------------------------------------
 void load_sprite(LuaEnvironment& env)
 {
@@ -145,9 +119,6 @@ void load_sprite(LuaEnvironment& env)
 	env.load_module_function("Sprite", "set_local_position", 	sprite_set_local_position);
 	env.load_module_function("Sprite", "set_local_rotation", 	sprite_set_local_rotation);
 	env.load_module_function("Sprite", "set_local_pose", 		sprite_set_local_pose);
-
-	env.load_module_function("Sprite", "play_animation", 		sprite_play_animation);
-	env.load_module_function("Sprite", "stop_animation", 		sprite_stop_animation);	
 }
 
 } // namespace crown

+ 0 - 12
engine/lua/LuaVector2.cpp

@@ -238,18 +238,6 @@ static int vector2_normalize(lua_State* L)
 	return 1;
 }
 
-//-----------------------------------------------------------------------------
-static int vector2_negate(lua_State* L)
-{
-	LuaStack stack(L);
-
-	Vector2& a = stack.get_vector2(1);
-
-	stack.push_vector2(-a);
-
-	return 1;
-}
-
 //-----------------------------------------------------------------------------
 static int vector2_distance(lua_State* L)
 {

+ 0 - 12
engine/lua/LuaVector3.cpp

@@ -276,18 +276,6 @@ static int vector3_normalize(lua_State* L)
 	return 1;
 }
 
-//-----------------------------------------------------------------------------
-static int vector3_negate(lua_State* L)
-{
-	LuaStack stack(L);
-
-	Vector3& a = stack.get_vector3(1);
-
-	stack.push_vector3(-a);
-
-	return 1;
-}
-
 //-----------------------------------------------------------------------------
 static int vector3_distance(lua_State* L)
 {

+ 1 - 0
engine/os/linux/main.cpp

@@ -34,6 +34,7 @@ OTHER DEALINGS IN THE SOFTWARE.
 #include "OsTypes.h"
 #include "OsEventQueue.h"
 #include "BundleCompiler.h"
+#include "Memory.h"
 
 namespace crown
 {

+ 193 - 84
engine/physics/Actor.cpp

@@ -38,6 +38,8 @@ OTHER DEALINGS IN THE SOFTWARE.
 #include "Vector3.h"
 #include "World.h"
 #include "PhysicsWorld.h"
+#include "Quaternion.h"
+#include "StringUtils.h"
 #include "PxCooking.h"
 #include "PxDefaultStreams.h"
 
@@ -74,6 +76,7 @@ using physx::PxVec3;
 using physx::PxDefaultMemoryOutputStream;
 using physx::PxDefaultMemoryInputData;
 using physx::PxConvexMeshGeometry;
+using physx::PxRigidBodyFlag;
 
 namespace crown
 {
@@ -189,6 +192,11 @@ void Actor::create_objects()
 			}
 		}
 
+		PxFilterData filter_data;
+		filter_data.word0 = config->filter(shape_class.collision_filter).me;
+		filter_data.word1 = config->filter(shape_class.collision_filter).mask;
+		px_shape->setSimulationFilterData(filter_data);
+
 		if (shape_class.trigger)
 		{
 			px_shape->setFlag(PxShapeFlag::eSIMULATION_SHAPE, false);
@@ -198,6 +206,10 @@ void Actor::create_objects()
 		shape_index++;
 	}
 
+	if (is_dynamic())
+	{
+		PxRigidBodyExt::updateMassAndInertia(*static_cast<PxRigidBody*>(m_actor), actor.mass);
+	}
 	m_actor->userData = this;
 	scene->addActor(*m_actor);
 }
@@ -213,92 +225,155 @@ void Actor::destroy_objects()
 }
 
 //-----------------------------------------------------------------------------
-void Actor::enable_gravity()
+Vector3 Actor::world_position() const
 {
-	m_actor->setActorFlag(PxActorFlag::eDISABLE_GRAVITY, false);
+	const PxTransform tr = m_actor->getGlobalPose();
+	return Vector3(tr.p.x, tr.p.y, tr.p.z);
 }
 
 //-----------------------------------------------------------------------------
-void Actor::disable_gravity()
+Quaternion Actor::world_rotation() const
 {
-	m_actor->setActorFlag(PxActorFlag::eDISABLE_GRAVITY, true);
+	const PxTransform tr = m_actor->getGlobalPose();
+	return Quaternion(tr.q.x, tr.q.y, tr.q.z, tr.q.w);
 }
 
 //-----------------------------------------------------------------------------
-void Actor::enable_collision()
+Matrix4x4 Actor::world_pose() const
 {
-	// PxFilterData filter_data;
-	// filter_data.word0 = (PxU32) m_group;
-	// filter_data.word1 = (PxU32) m_mask;
+	const PxTransform tr = m_actor->getGlobalPose();
+	return Matrix4x4(Quaternion(tr.q.x, tr.q.y, tr.q.z, tr.q.w), Vector3(tr.p.x, tr.p.y, tr.p.z));
+}
 
-	// const PxU32 num_shapes = m_actor->getNbShapes();
+//-----------------------------------------------------------------------------
+void Actor::teleport_world_position(const Vector3& p)
+{
+	PxTransform tr = m_actor->getGlobalPose();
+	tr.p.x = p.x;
+	tr.p.y = p.y;
+	tr.p.z = p.z;
+	m_actor->setGlobalPose(tr);
+}
 
-	// PxShape** shapes = (PxShape**) default_allocator().allocate((sizeof(PxShape*) * num_shapes));
-	// m_actor->getShapes(shapes, num_shapes);
+//-----------------------------------------------------------------------------
+void Actor::teleport_world_rotation(const Quaternion& r)
+{
+	PxTransform tr = m_actor->getGlobalPose();
+	tr.q.x = r.x;
+	tr.q.y = r.y;
+	tr.q.z = r.z;
+	tr.q.w = r.w;
+	m_actor->setGlobalPose(tr);
+}
 
-	// for(PxU32 i = 0; i < num_shapes; i++)
-	// {
-	// 	PxShape* shape = shapes[i];
-	// 	shape->setSimulationFilterData(filter_data);
-	// }
+//-----------------------------------------------------------------------------
+void Actor::teleport_world_pose(const Matrix4x4& m)
+{
+	const PxVec3 x(m.x().x, m.x().y, m.x().z);
+	const PxVec3 y(m.y().x, m.y().y, m.y().z);
+	const PxVec3 z(m.z().x, m.z().y, m.z().z);
+	const PxVec3 t(m.translation().x, m.translation().y, m.translation().z);
+	m_actor->setGlobalPose(PxTransform(PxMat44(x, y, z, t)));
+}
 
-	// default_allocator().deallocate(shapes);
+//-----------------------------------------------------------------------------
+Vector3 Actor::center_of_mass() const
+{
+	if (is_static())
+		return Vector3(0, 0, 0);
+
+	const PxTransform tr = static_cast<PxRigidBody*>(m_actor)->getCMassLocalPose();
+	return Vector3(tr.p.x, tr.p.y, tr.p.z);
 }
 
 //-----------------------------------------------------------------------------
-void Actor::disable_collision()
+void Actor::enable_gravity()
 {
-	// PxFilterData filter_data;
-	// filter_data.word0 = (PxU32) CollisionGroup::GROUP_0;
-	// filter_data.word1 = (PxU32) CollisionGroup::GROUP_0;
+	m_actor->setActorFlag(PxActorFlag::eDISABLE_GRAVITY, false);
+}
 
-	// const PxU32 num_shapes = m_actor->getNbShapes();
+//-----------------------------------------------------------------------------
+void Actor::disable_gravity()
+{
+	m_actor->setActorFlag(PxActorFlag::eDISABLE_GRAVITY, true);
+}
 
-	// PxShape** shapes = (PxShape**) default_allocator().allocate((sizeof(PxShape*) * num_shapes));
-	// m_actor->getShapes(shapes, num_shapes);
+//-----------------------------------------------------------------------------
+void Actor::enable_collision()
+{
+	// const PxU32 num_shapes = m_actor->getNbShapes();
+	// PxU32 idx = 0;
 
-	// for(PxU32 i = 0; i < num_shapes; i++)
+	// while (idx != num_shapes)
 	// {
-	// 	PxShape* shape = shapes[i];
-	// 	shape->setSimulationFilterData(filter_data);
+	// 	PxShape* shapes[8];
+	// 	const PxU32 written = m_actor->getShapes(shapes, 8, idx);
+
+	// 	for (PxU32 i = 0; i < written; i++)
+	// 	{
+	// 		PxFilterData fdata;
+	// 		fdata.word0 = 0;
+	// 		fdata.word1 = 0;
+	// 		shapes[i]->setSimulationFilterData(fdata);
+	// 	}
+
+	// 	idx += written;
 	// }
+}
 
-	// default_allocator().deallocate(shapes);
+//-----------------------------------------------------------------------------
+void Actor::disable_collision()
+{
 }
 
 //-----------------------------------------------------------------------------
-void Actor::set_kinematic()
+void Actor::set_collision_filter(const char* name)
 {
-	static_cast<PxRigidDynamic*>(m_actor)->setRigidDynamicFlag(PxRigidDynamicFlag::eKINEMATIC, true);
+	set_collision_filter(string::murmur2_32(name, string::strlen(name)));
 }
 
 //-----------------------------------------------------------------------------
-void Actor::clear_kinematic()
+void Actor::set_collision_filter(StringId32 filter)
 {
-	static_cast<PxRigidDynamic*>(m_actor)->setRigidDynamicFlag(PxRigidDynamicFlag::eKINEMATIC, false);
+	const PhysicsCollisionFilter& pcf = m_world.resource()->filter(filter);
+
+	const PxU32 num_shapes = m_actor->getNbShapes();
+	PxU32 idx = 0;
+
+	while (idx != num_shapes)
+	{
+		PxShape* shapes[8];
+		const PxU32 written = m_actor->getShapes(shapes, 8, idx);
 
-	m_scene_graph.set_world_pose(m_node, get_kinematic_pose());
+		for (PxU32 i = 0; i < written; i++)
+		{
+			PxFilterData fdata;
+			fdata.word0 = pcf.me;
+			fdata.word1 = pcf.mask;
+			shapes[i]->setSimulationFilterData(fdata);
+		}
+
+		idx += written;
+	}
 }
 
 //-----------------------------------------------------------------------------
-void Actor::move(const Vector3& pos)
+void Actor::set_kinematic(bool kinematic)
 {
-	CE_ASSERT(is_kinematic(), "Cannot call 'move' method for non-kinematic actor");
+	if (is_static())
+		return;
 
-	PxVec3 position(pos.x, pos.y, pos.z);
-	static_cast<PxRigidDynamic*>(m_actor)->setKinematicTarget(PxTransform(position));
+	static_cast<PxRigidBody*>(m_actor)->setRigidBodyFlag(PxRigidBodyFlag::eKINEMATIC, kinematic);
 }
 
 //-----------------------------------------------------------------------------
-Matrix4x4 Actor::get_kinematic_pose() const
+void Actor::move(const Vector3& pos)
 {
-	PxTransform transform;
-	static_cast<PxRigidDynamic*>(m_actor)->getKinematicTarget(transform);
+	if (!is_kinematic())
+		return;
 
-	Quaternion rot(transform.q.x, transform.q.y, transform.q.z, transform.q.w);
-	Vector3 pos(transform.p.x, transform.p.y, transform.p.z);
-	
-	return Matrix4x4(rot, pos);
+	const PxVec3 position(pos.x, pos.y, pos.z);
+	static_cast<PxRigidDynamic*>(m_actor)->setKinematicTarget(PxTransform(position));
 }
 
 //-----------------------------------------------------------------------------
@@ -316,118 +391,152 @@ bool Actor::is_dynamic() const
 //-----------------------------------------------------------------------------
 bool Actor::is_kinematic() const
 {
-	if (!is_dynamic()) return false;
+	if (!is_dynamic())
+		return false;
+
 	return static_cast<PxRigidDynamic*>(m_actor)->getRigidDynamicFlags() & PxRigidDynamicFlag::eKINEMATIC;
 }
 
+//-----------------------------------------------------------------------------
+bool Actor::is_nonkinematic() const
+{
+	return is_dynamic() && !is_kinematic();
+}
+
 //-----------------------------------------------------------------------------
 float Actor::linear_damping() const
 {
-	return ((PxRigidDynamic*)m_actor)->getLinearDamping();
+	if (is_static())
+		return 0;
+
+	return static_cast<PxRigidDynamic*>(m_actor)->getLinearDamping();
 }
 
 //-----------------------------------------------------------------------------
 void Actor::set_linear_damping(float rate)
 {
-	((PxRigidDynamic*)m_actor)->setLinearDamping(rate);
+	if (is_static())
+		return;
+
+	static_cast<PxRigidDynamic*>(m_actor)->setLinearDamping(rate);
 }
 
 //-----------------------------------------------------------------------------
 float Actor::angular_damping() const
 {
-	return ((PxRigidDynamic*)m_actor)->getAngularDamping();
+	if (is_static())
+		return 0;
+
+	return static_cast<PxRigidDynamic*>(m_actor)->getAngularDamping();
 }
 
 //-----------------------------------------------------------------------------
 void Actor::set_angular_damping(float rate)
 {
-	((PxRigidDynamic*)m_actor)->setAngularDamping(rate);
+	if (is_static())
+		return;
+
+	static_cast<PxRigidDynamic*>(m_actor)->setAngularDamping(rate);
 }
 
 //-----------------------------------------------------------------------------
 Vector3 Actor::linear_velocity() const
 {
-	PxVec3 vel = ((PxRigidBody*)m_actor)->getLinearVelocity();
-	Vector3 velocity(vel.x, vel.y, vel.z);
-	return velocity;
+	if (is_static())
+		return Vector3(0, 0, 0);
+
+	const PxVec3 vel = static_cast<PxRigidBody*>(m_actor)->getLinearVelocity();
+	return Vector3(vel.x, vel.y, vel.z);
 }
 
 //-----------------------------------------------------------------------------
 void Actor::set_linear_velocity(const Vector3& vel)
 {
-	PxVec3 velocity(vel.x, vel.y, vel.z);
-	((PxRigidBody*)m_actor)->setLinearVelocity(velocity);
+	if (!is_nonkinematic())
+		return;
+
+	const PxVec3 velocity(vel.x, vel.y, vel.z);
+	static_cast<PxRigidBody*>(m_actor)->setLinearVelocity(velocity);
 }
 
 //-----------------------------------------------------------------------------
 Vector3 Actor::angular_velocity() const
 {
-	PxVec3 vel = ((PxRigidBody*)m_actor)->getAngularVelocity();
-	Vector3 velocity(vel.x, vel.y, vel.z);
-	return velocity;
+	if (is_static())
+		return Vector3(0, 0, 0);
+
+	const PxVec3 vel = static_cast<PxRigidBody*>(m_actor)->getAngularVelocity();
+	return Vector3(vel.x, vel.y, vel.z);
 }
 
 //-----------------------------------------------------------------------------
 void Actor::set_angular_velocity(const Vector3& vel)
 {
-	PxVec3 velocity(vel.x, vel.y, vel.z);
-	((PxRigidBody*)m_actor)->setAngularVelocity(velocity);
+	if (!is_nonkinematic())
+		return;
+
+	const PxVec3 velocity(vel.x, vel.y, vel.z);
+	static_cast<PxRigidBody*>(m_actor)->setAngularVelocity(velocity);
 }
 
 //-----------------------------------------------------------------------------
 void Actor::add_impulse(const Vector3& impulse)
 {
-	Vector3 p = m_scene_graph.world_pose(m_node).translation();
+	if (!is_nonkinematic())
+		return;
 
-	PxRigidBodyExt::addForceAtPos(*static_cast<PxRigidDynamic*>(m_actor),
-								  PxVec3(impulse.x, impulse.y, impulse.z),
-								  PxVec3(p.x, p.y, p.z),
-								  PxForceMode::eIMPULSE,
-								  true);
+	static_cast<PxRigidDynamic*>(m_actor)->addForce(PxVec3(impulse.x, impulse.y, impulse.z), PxForceMode::eIMPULSE);
 }
 
 //-----------------------------------------------------------------------------
 void Actor::add_impulse_at(const Vector3& impulse, const Vector3& pos)
 {
-	PxRigidBodyExt::addForceAtLocalPos(*static_cast<PxRigidDynamic*>(m_actor),
+	if (!is_nonkinematic())
+		return;
+
+	PxRigidBodyExt::addForceAtPos(*static_cast<PxRigidDynamic*>(m_actor),
 									   PxVec3(impulse.x, impulse.y, impulse.z),
 									   PxVec3(pos.x, pos.y, pos.z),
-									   PxForceMode::eIMPULSE,
-									   true);
+									   PxForceMode::eIMPULSE);
 }
 
 //-----------------------------------------------------------------------------
-void Actor::push(const Vector3& vel, const float mass)
+void Actor::add_torque_impulse(const Vector3& i)
 {
-	// FIXME FIXME FIXME
-	Vector3 p = m_scene_graph.world_pose(m_node).translation();
-
-	Vector3 mq(vel.x * mass, vel.y * mass, vel.z * mass);
-	Vector3 f(mq.x / 0.017, mq.y / 0.017, mq.z / 0.017);
+	if (!is_nonkinematic())
+		return;
 
-	PxRigidBodyExt::addForceAtPos(*static_cast<PxRigidDynamic*>(m_actor),
-								  PxVec3(f.x, f.y, f.z),
-								  PxVec3(p.x, p.y, p.z));
+	static_cast<PxRigidBody*>(m_actor)->addTorque(PxVec3(i.x, i.y, i.z), PxForceMode::eIMPULSE);
 }
 
+//-----------------------------------------------------------------------------
+void Actor::push(const Vector3& vel, float mass)
+{
+	add_impulse(vel * mass);
+}
 
 //-----------------------------------------------------------------------------
-bool Actor::is_sleeping()
+void Actor::push_at(const Vector3& vel, float mass, const Vector3& pos)
 {
-	return ((PxRigidDynamic*)m_actor)->isSleeping();
+	add_impulse_at(vel * mass, pos);
 }
 
 //-----------------------------------------------------------------------------
-void Actor::wake_up()
+bool Actor::is_sleeping()
 {
-	((PxRigidDynamic*)m_actor)->wakeUp();
+	if (is_static())
+		return true;
+
+	return static_cast<PxRigidDynamic*>(m_actor)->isSleeping();
 }
 
 //-----------------------------------------------------------------------------
-StringId32 Actor::name()
+void Actor::wake_up()
 {
-	const PhysicsActor& a = m_resource->actor(m_index);
-	return a.name;
+	if (is_static())
+		return;
+
+	static_cast<PxRigidDynamic*>(m_actor)->wakeUp();
 }
 
 //-----------------------------------------------------------------------------

+ 61 - 45
engine/physics/Actor.h

@@ -59,6 +59,27 @@ struct Actor
 	Actor(PhysicsWorld& pw, const PhysicsResource* res, uint32_t actor_idx, SceneGraph& sg, int32_t node, UnitId unit_id);
 	~Actor();
 
+	/// Sets the world position of the actor.
+	Vector3 world_position() const;
+
+	/// Sets the world rotation of the actor.
+	Quaternion world_rotation() const;
+
+	/// Sets the world pose of the actor.
+	Matrix4x4 world_pose() const;
+
+	/// Teleports the actor to the given world position.
+	void teleport_world_position(const Vector3& p);
+
+	/// Teleports the actor to the given world rotation.
+	void teleport_world_rotation(const Quaternion& r);
+
+	/// Teleports the actor to the given world pose.
+	void teleport_world_pose(const Matrix4x4& m);
+
+	/// Returns the center of mass of the actor.
+	Vector3 center_of_mass() const;
+
 	/// Makes the actor subject to gravity
 	void enable_gravity();
 
@@ -68,86 +89,82 @@ struct Actor
 	void enable_collision();
 	void disable_collision();
 
-	/// Makes the actor kinematic (keyframed)
-	/// @note
-	/// Works only for dynamic actors
-	void set_kinematic();
+	/// Sets the collision filter of the actor.
+	void set_collision_filter(const char* filter);
+	void set_collision_filter(StringId32 filter);
 
-	/// Makes the actor dynamic
-	/// @note
-	/// Works only for kinematic actors
-	void clear_kinematic();
+	/// Sets whether the actor is kinematic or not.
+	/// @note This call has no effect on static actors.
+	void set_kinematic(bool kinematic);
 
 	/// Moves the actor to @a pos
-	/// @note
-	/// Works only for kinematic actors
+	/// @note This call only affects nonkinematic actors.
 	void move(const Vector3& pos);
 
-	/// Returns whether the actor is static (i.e. immovable).
+	/// Returns whether the actor is static.
 	bool is_static() const;
 
-	/// Returns whether the actor is dynamic (i.e. driven dy physics).
+	/// Returns whether the actor is dynamic.
 	bool is_dynamic() const;
 
-	/// Returns whether the actor is kinematic (i.e. driven by the user).
+	/// Returns whether the actor is kinematic (keyframed).
 	bool is_kinematic() const;
 
-	/// Returns the rate at which rigid bodies dissipate linear momentum
+	/// Returns whether the actor is nonkinematic (i.e. dynamic and not kinematic).
+	bool is_nonkinematic() const;
+
+	/// Returns the linear damping of the actor.
 	float linear_damping() const;
 
-	/// Sets the rate at which rigid bodies dissipate linear momentum
+	/// Sets the linear damping of the actor.
 	void set_linear_damping(float rate);
 
-	/// Returns the rate at which rigid bodies dissipate angular momentum
+	/// Returns the angular damping of the actor.
 	float angular_damping() const;
 
-	/// Sets the rate at which rigid bodies dissipate angular momentum
+	/// Sets the angular damping of the actor.
 	void set_angular_damping(float rate);
  
-	/// Returns linear velocity of the actor
-	/// @note
-	/// If actor is sleeping, linear velocity must be 0
+	/// Returns the linear velocity of the actor.
 	Vector3 linear_velocity() const;
 
-	/// Sets linear velocity of the actor
-	/// @note
-	/// If actor is sleeping, this will wake it up
+	/// Sets the linear velocity of the actor.
+	/// @note This call only affects nonkinematic actors.
 	void set_linear_velocity(const Vector3& vel);
 
-	/// Returns angular velocity of the actor
-	/// @note
-	/// If actor is sleeping, angular velocity must be 0
+	/// Returns the angular velocity of the actor.
 	Vector3 angular_velocity() const;
 
-	/// Sets angular velocity of the actor
-	/// @note
-	/// If actor is sleeping, this will wake it up
+	/// Sets the angular velocity of the actor.
+	/// @note This call only affects nonkinematic actors.
 	void set_angular_velocity(const Vector3& vel);
 
-	/// Applies a force (or impulse) defined in the global coordinate frame, acting at a particular point in global coordinates, to the actor.
-	/// @note
-	/// If the force does not act along the center of mass of the actor, this will also add the corresponding torque.
-	/// Because forces are reset at the end of every timestep, you can maintain a total external force on an object by calling this once every frame.
+	/// Adds a linear impulse (acting along the center of mass) to the actor.
+	/// @note This call only affects nonkinematic actors.
 	void add_impulse(const Vector3& impulse);
 
-	/// Applies a force (or impulse) defined in the global coordinate frame, acting at a particular point in local coordinates, to the actor.
-	/// @note
-	/// If the force does not act along the center of mass of the actor, this will also add the corresponding torque.
-	/// Because forces are reset at the end of every timestep, you can maintain a total external force on an object by calling this once every frame. 
+	/// Adds a linear impulse (acting along the world position @a pos) to the actor.
+	/// @note This call only affects nonkinematic actors.
 	void add_impulse_at(const Vector3& impulse, const Vector3& pos);
 
-	/// Applies a force, evaluated by actor's @a mass and @a velocity that will be achieved, to the actor
-	void push(const Vector3& vel, const float mass);
+	/// Adds a torque impulse to the actor.
+	void add_torque_impulse(const Vector3& i);
+
+	/// Pushes the actor as if it was hit by a point object with the given @a mass
+	/// travelling at the given @a velocity.
+	/// @note This call only affects nonkinematic actors.
+	void push(const Vector3& vel, float mass);
 
-	/// Returns true if tha actor is sleeping, false otherwise
+	/// Like push() but applies the force at the world position @a pos.
+	/// @note This call only affects nonkinematic actors.
+	void push_at(const Vector3& vel, float mass, const Vector3& pos);
+
+	/// Returns whether the actor is sleeping.
 	bool is_sleeping();
 
-	/// Forces the actor to wake up
+	/// Wakes the actor up.
 	void wake_up();
 
-	/// Returns actor's name
-	StringId32 name();
-
 	/// Returns the unit that owns the actor.
 	Unit* unit();
 
@@ -159,7 +176,6 @@ private:
 	void destroy_objects();
 
 	void update(const Matrix4x4& pose);
-	Matrix4x4 get_kinematic_pose() const;
 
 public:
 

+ 2 - 2
engine/physics/PhysicsCallback.h

@@ -102,8 +102,8 @@ public:
 			PxContactPairPoint points[8];
 			const PxU32 num_points = cp.extractContacts(points, 8);
 			
-			PxVec3 where;
-			PxVec3 normal;
+			PxVec3 where(0, 0, 0);
+			PxVec3 normal(0, 0, 0);
 			for (PxU32 i = 0; i < num_points; i++)
 			{
 				where = points[i].position;

+ 7 - 38
engine/physics/PhysicsWorld.cpp

@@ -158,20 +158,18 @@ namespace physics_system
 			return PxFilterFlag::eDEFAULT;
 		}
 
-		// generate contacts for all that were not filtered above
-		pairFlags = PxPairFlag::eCONTACT_DEFAULT;
-
 		// trigger the contact callback for pairs (A,B) where 
 		// the filtermask of A contains the ID of B and vice versa.
-		//if((filterData0.word0 & filterData1.word1) && (filterData1.word0 & filterData0.word1))
+		if((filterData0.word0 & filterData1.word1) && (filterData1.word0 & filterData0.word1))
 		{
-			pairFlags |= PxPairFlag::eNOTIFY_TOUCH_FOUND
-						| PxPairFlag::eNOTIFY_TOUCH_LOST
-						| PxPairFlag::eNOTIFY_CONTACT_POINTS;
+			pairFlags |= PxPairFlag::eCONTACT_DEFAULT
+			 		  | PxPairFlag::eNOTIFY_TOUCH_FOUND
+					  | PxPairFlag::eNOTIFY_TOUCH_LOST
+					  | PxPairFlag::eNOTIFY_CONTACT_POINTS;
 			return PxFilterFlag::eDEFAULT;
 		}
 
-		return PxFilterFlag::eDEFAULT;
+		return PxFilterFlag::eSUPPRESS;
 	}
 
 	// Global PhysX objects
@@ -266,7 +264,6 @@ PhysicsWorld::~PhysicsWorld()
 //-----------------------------------------------------------------------------
 ActorId	PhysicsWorld::create_actor(const PhysicsResource* res, const uint32_t index, SceneGraph& sg, int32_t node, UnitId unit_id)
 {
-	PhysicsConfigResource* config = (PhysicsConfigResource*) device()->resource_manager()->lookup("physics_config", "global");
 	Actor* actor = CE_NEW(m_actors_pool, Actor)(*this, res, index, sg, node, unit_id);
 	return m_actors.create(actor);
 }
@@ -328,20 +325,6 @@ void PhysicsWorld::destroy_raycast(RaycastId id)
 	m_raycasts.destroy(id);
 }
 
-//-----------------------------------------------------------------------------
-Actor* PhysicsWorld::lookup_actor(StringId32 name)
-{
-	for (uint32_t i = 0; i < m_actors.size(); i++)
-	{
-		Actor* actor = m_actors[i];
-
-		if (actor->name() == name)
-		{
-			return actor;
-		}
-	}
-}
-
 //-----------------------------------------------------------------------------
 Actor* PhysicsWorld::lookup_actor(ActorId id)
 {
@@ -376,20 +359,6 @@ void PhysicsWorld::set_gravity(const Vector3& g)
 	m_scene->setGravity(PxVec3(g.x, g.y, g.z));
 }
 
-//-----------------------------------------------------------------------------
-void PhysicsWorld::set_kinematic(ActorId id)
-{
-	Actor* actor = lookup_actor(id);
-	actor->set_kinematic();
-}
-
-//-----------------------------------------------------------------------------
-void PhysicsWorld::clear_kinematic(ActorId id)
-{
-	Actor* actor = lookup_actor(id);
-	actor->clear_kinematic();
-}
-
 //-----------------------------------------------------------------------------
 void PhysicsWorld::overlap_test(CollisionType::Enum filter, ShapeType::Enum type,
 								const Vector3& pos, const Quaternion& rot, const Vector3& size, Array<Actor*>& actors)
@@ -398,7 +367,7 @@ void PhysicsWorld::overlap_test(CollisionType::Enum filter, ShapeType::Enum type
 
 	switch(type)
 	{
-		case ShapeType::SPHERE:	
+		case ShapeType::SPHERE:
 		{
 			PxSphereGeometry geometry(size.x);
 			m_scene->overlap(geometry, transform, m_buffer);

+ 0 - 5
engine/physics/PhysicsWorld.h

@@ -99,20 +99,15 @@ public:
 	RaycastId create_raycast(CollisionMode::Enum mode, CollisionType::Enum filter);
 	void destroy_raycast(RaycastId id);
 
-
 	Vector3 gravity() const;
 	void set_gravity(const Vector3& g);
 
-	void set_kinematic(ActorId id);
-	void clear_kinematic(ActorId id);
-
 	/// Finds all actors in the physics world that are in a particular shape (supported: spheres, capsules and boxes)
 	void overlap_test(CollisionType::Enum filter, ShapeType::Enum type,
 						const Vector3& pos, const Quaternion& rot, const Vector3& size, Array<Actor*>& actors);
 
 	void update(float dt);
 
-	Actor* lookup_actor(StringId32 name);
 	Actor* lookup_actor(ActorId id);
 	Controller* lookup_controller(ControllerId id);
 	Raycast* lookup_raycast(RaycastId id);

+ 0 - 41
engine/renderers/Sprite.cpp

@@ -44,12 +44,6 @@ Sprite::Sprite(RenderWorld& render_world, SceneGraph& sg, int32_t node, const Sp
 	, m_scene_graph(sg)
 	, m_node(node)
 	, m_resource(sr)
-	, m_start_frame(0)
-	, m_cur_frame(0)
-	, m_tot_time(1.0)
-	, m_anim_time(0.0)
-	, m_loop(false)
-	, m_is_playing(false)
 {
 	m_vb = sr->vertex_buffer();
 	m_ib = sr->index_buffer();
@@ -114,29 +108,6 @@ void Sprite::set_local_pose(Unit* unit, const Matrix4x4& pose)
 	unit->set_local_pose(m_node, pose);
 }
 
-//-----------------------------------------------------------------------------
-void Sprite::play_animation(uint32_t start, uint32_t end, float time, bool loop)
-{
-	m_start_frame = start;
-	m_end_frame = end;
-	m_tot_time = time;
-	m_anim_time = 0.0;
-	m_loop = loop;
-}
-
-//-----------------------------------------------------------------------------
-void Sprite::stop_animation()
-{
-	m_cur_frame = 0;
-}
-
-//-----------------------------------------------------------------------------
-void Sprite::set_frame(uint32_t i)
-{
-	CE_ASSERT(i < m_resource->num_frames(), "Frame out of bounds"); 
-	m_cur_frame = i;
-}
-
 //-----------------------------------------------------------------------------
 void Sprite::set_material(MaterialId mat)
 {
@@ -146,11 +117,6 @@ void Sprite::set_material(MaterialId mat)
 //-----------------------------------------------------------------------------
 void Sprite::render(Renderer& r, UniformId uniform, float dt)
 {
-	// Compute current frame
-	uint32_t cur_frame = ((m_end_frame - m_start_frame) / m_tot_time) * m_anim_time;
-	m_cur_frame = cur_frame > m_end_frame ? m_end_frame : cur_frame;
-	m_anim_time += dt;
-
 	Material* material = m_render_world.lookup_material(m_material);
 	material->bind(r, uniform);
 
@@ -161,16 +127,9 @@ void Sprite::render(Renderer& r, UniformId uniform, float dt)
 		| STATE_BLEND_EQUATION_ADD 
 		| STATE_BLEND_FUNC(STATE_BLEND_FUNC_SRC_ALPHA, STATE_BLEND_FUNC_ONE_MINUS_SRC_ALPHA));
 	r.set_vertex_buffer(m_vb);
-	const uint32_t start_index = m_cur_frame * 6;
 	r.set_index_buffer(m_ib, 0, 6);
 	r.set_pose(world_pose());
 	r.commit(0);
-
-	if (m_cur_frame == m_end_frame && m_loop)
-	{
-		m_anim_time = 0.0;
-		m_cur_frame = m_start_frame;
-	}
 }
 
 } // namespace crown

+ 0 - 16
engine/renderers/Sprite.h

@@ -59,14 +59,6 @@ struct Sprite
 	void					set_local_rotation(Unit* unit, const Quaternion& rot);
 	void					set_local_pose(Unit* unit, const Matrix4x4& pose);
 
-	/// Plays the animation from frame @a start to frame @a.
-	/// @a time is for how long the animation has to be played.
-	void					play_animation(uint32_t start, uint32_t end, float time, bool loop);
-
-	/// Stops the current animation.
-	void					stop_animation();
-
-	void					set_frame(uint32_t i);
 	void					set_material(MaterialId mat);
 	void					render(Renderer& r, UniformId uniform, float dt);
 
@@ -77,14 +69,6 @@ public:
 	int32_t					m_node;
 	const SpriteResource*	m_resource;
 
-	uint32_t				m_start_frame;
-	uint32_t				m_cur_frame;
-	uint32_t				m_end_frame;
-	float 					m_tot_time;
-	float					m_anim_time;
-	bool					m_loop;
-	bool					m_is_playing;
-
 	MaterialId				m_material;
 	VertexBufferId			m_vb;
 	IndexBufferId			m_ib;

+ 1 - 1
engine/renderers/backend/gl/GLRenderer.cpp

@@ -35,7 +35,6 @@ OTHER DEALINGS IN THE SOFTWARE.
 #endif
 
 #include <algorithm>
-#include "Allocator.h"
 #include "Assert.h"
 #include "Device.h"
 #include "GLContext.h"
@@ -48,6 +47,7 @@ OTHER DEALINGS IN THE SOFTWARE.
 #include "StringUtils.h"
 #include "Types.h"
 #include "Vector4.h"
+#include "Memory.h"
 #include "VertexFormat.h"
 
 //-----------------------------------------------------------------------------

+ 1 - 1
engine/resource/FileBundle.cpp

@@ -27,7 +27,7 @@ OTHER DEALINGS IN THE SOFTWARE.
 #include <stdio.h>
 #include <inttypes.h>
 
-#include "Allocator.h"
+#include "Memory.h"
 #include "Bundle.h"
 #include "Filesystem.h"
 #include "Resource.h"

+ 1 - 0
engine/resource/FontResource.h

@@ -168,6 +168,7 @@ public:
 		}
 
 		CE_FATAL("Glyph not found");
+		return FontGlyphData();
 	}
 
 private:

+ 52 - 56
engine/resource/PhysicsResource.cpp

@@ -32,6 +32,7 @@ OTHER DEALINGS IN THE SOFTWARE.
 #include "PhysicsResource.h"
 #include "StringUtils.h"
 #include "DynamicString.h"
+#include "Map.h"
 
 namespace crown
 {
@@ -180,11 +181,13 @@ void parse_actors(JSONElement e, Array<PhysicsActor>& actors, Array<PhysicsShape
 		JSONElement node 	= actor.key("node");
 		JSONElement clasz	= actor.key("class");
 		JSONElement shapes	= actor.key("shapes");
+		JSONElement mass	= actor.key("mass");
 
 		PhysicsActor pa;
 		pa.name = keys[k].to_string_id();
 		pa.node = node.to_string_id();
 		pa.actor_class = clasz.to_string_id();
+		pa.mass = mass.to_float();
 		pa.num_shapes = shapes.size();
 
 		array::push_back(actors, pa);
@@ -364,6 +367,8 @@ void compile(Filesystem& fs, const char* resource_path, File* out_file)
 
 namespace physics_config_resource
 {
+	static Map<DynamicString, uint32_t>* s_ftm = NULL;
+
 	struct ObjectName
 	{
 		StringId32 name;
@@ -375,40 +380,6 @@ namespace physics_config_resource
 		}
 	};
 
-	struct NameToMask
-	{
-		StringId32 name;
-		uint32_t mask;
-	};
-
-	uint32_t collides_with_to_mask(Vector<DynamicString>& collides_with, Array<NameToMask>& name_to_mask)
-	{
-		uint32_t mask = 0;
-
-		for (uint32_t i = 0; i < vector::size(collides_with); i++)
-		{
-			StringId32 cur_name = collides_with[i].to_string_id();
-			for (uint32_t j = 0; j < array::size(name_to_mask); j++)
-			{
-				if (cur_name == name_to_mask[j].name) mask |= name_to_mask[j].mask;
-			}
-		}
-
-		return mask;
-	}
-
-	uint32_t collision_filter_to_mask(const char* filter, Array<NameToMask> name_to_mask)
-	{
-		StringId32 filter_hash = string::murmur2_32(filter, string::strlen(filter));
-		for (uint32_t i = 0; i < array::size(name_to_mask); i++)
-		{
-			if (name_to_mask[i].name == filter_hash) return name_to_mask[i].mask;
-		}
-
-		CE_ASSERT(false, "Collision filter '%s' not found", filter);
-		return 0;
-	}
-
 	void parse_materials(JSONElement e, Array<ObjectName>& names, Array<PhysicsMaterial>& objects)
 	{
 		Vector<DynamicString> keys(default_allocator());
@@ -437,7 +408,7 @@ namespace physics_config_resource
 		}
 	}
 
-	void parse_shapes(JSONElement e, Array<NameToMask>& name_to_mask, Array<ObjectName>& names, Array<PhysicsShape2>& objects)
+	void parse_shapes(JSONElement e, Array<ObjectName>& names, Array<PhysicsShape2>& objects)
 	{
 		Vector<DynamicString> keys(default_allocator());
 		e.to_keys(keys);
@@ -456,8 +427,7 @@ namespace physics_config_resource
 			// Read shape object
 			PhysicsShape2 ps2;
 			ps2.trigger = trigger.to_bool();
-			DynamicString cfilter; collision_filter.to_string(cfilter);
-			ps2.collision_filter = collision_filter_to_mask(cfilter.c_str(), name_to_mask);
+			ps2.collision_filter = collision_filter.to_string_id();
 
 			array::push_back(names, shape_name);
 			array::push_back(objects, ps2);
@@ -485,7 +455,6 @@ namespace physics_config_resource
 
 			// Read actor object
 			PhysicsActor2 pa2;
-			//actor.collision_filter = coll_filter.to_string_id();
 			pa2.linear_damping = linear_damping.is_nil() ? 0.0 : linear_damping.to_float();
 			pa2.angular_damping = angular_damping.is_nil() ? 0.05 : angular_damping.to_float();
 			pa2.flags = 0;
@@ -507,20 +476,42 @@ namespace physics_config_resource
 		}
 	}
 
-	void parse_collision_filters(JSONElement e, Array<ObjectName>& names, Array<PhysicsCollisionFilter>& objects, Array<NameToMask>& name_to_mask)
+	uint32_t new_filter_mask()
 	{
-		Vector<DynamicString> keys(default_allocator());
-		e.to_keys(keys);
+		static uint32_t mask = 1;
+		CE_ASSERT(mask != 0x80000000u, "Too many collision filters");
+		uint32_t tmp = mask;
+		mask = mask << 1;
+		return tmp;
+	}
 
-		// Assign a unique mask to each collision filter
-		for (uint32_t i = 0; i < vector::size(keys); i++)
+	uint32_t filter_to_mask(const char* f)
+	{
+		if (map::has(*s_ftm, DynamicString(f)))
+			return map::get(*s_ftm, DynamicString(f), 0u);
+
+		uint32_t new_filter = new_filter_mask();
+		map::set(*s_ftm, DynamicString(f), new_filter);
+		return new_filter;
+	}
+
+	uint32_t collides_with_to_mask(const Vector<DynamicString>& coll_with)
+	{
+		uint32_t mask = 0;
+
+		for (uint32_t i = 0; i < vector::size(coll_with); i++)
 		{
-			NameToMask ntm;
-			ntm.name = keys[i].to_string_id();
-			ntm.mask = 1 << i;
-			array::push_back(name_to_mask, ntm);
+			mask |= filter_to_mask(coll_with[i].c_str());
 		}
 
+		return mask;
+	}
+
+	void parse_collision_filters(JSONElement e, Array<ObjectName>& names, Array<PhysicsCollisionFilter>& objects)
+	{
+		Vector<DynamicString> keys(default_allocator());
+		e.to_keys(keys);
+
 		for (uint32_t i = 0; i < vector::size(keys); i++)
 		{
 			JSONElement filter			= e.key(keys[i].c_str());
@@ -536,9 +527,10 @@ namespace physics_config_resource
 			collides_with.to_array(collides_with_vector);
 
 			PhysicsCollisionFilter pcf;
-			pcf.mask = collides_with_to_mask(collides_with_vector, name_to_mask);
+			pcf.me = filter_to_mask(keys[i].c_str());
+			pcf.mask = collides_with_to_mask(collides_with_vector);
 
-			printf("FILTER: %s, mask = %X\n", keys[i].c_str(), pcf.mask);
+			printf("FILTER: %s (me = %X, mask = %X\n", keys[i].c_str(), pcf.me, pcf.mask);
 
 			array::push_back(names, filter_name);
 			array::push_back(objects, pcf);
@@ -554,6 +546,9 @@ namespace physics_config_resource
 		JSONParser json(buf);
 		JSONElement root = json.root();
 
+		typedef Map<DynamicString, uint32_t> FilterMap;
+		s_ftm = CE_NEW(default_allocator(), FilterMap)(default_allocator());
+
 		Array<ObjectName> material_names(default_allocator());
 		Array<PhysicsMaterial> material_objects(default_allocator());
 		Array<ObjectName> shape_names(default_allocator());
@@ -562,12 +557,11 @@ namespace physics_config_resource
 		Array<PhysicsActor2> actor_objects(default_allocator());
 		Array<ObjectName> filter_names(default_allocator());
 		Array<PhysicsCollisionFilter> filter_objects(default_allocator());
-		Array<NameToMask> name_to_mask(default_allocator());
 
 		// Parse materials
-		if (root.has_key("collision_filters")) parse_collision_filters(root.key("collision_filters"), filter_names, filter_objects, name_to_mask);
+		if (root.has_key("collision_filters")) parse_collision_filters(root.key("collision_filters"), filter_names, filter_objects);
 		if (root.has_key("materials")) parse_materials(root.key("materials"), material_names, material_objects);
-		if (root.has_key("shapes")) parse_shapes(root.key("shapes"), name_to_mask, shape_names, shape_objects);
+		if (root.has_key("shapes")) parse_shapes(root.key("shapes"), shape_names, shape_objects);
 		if (root.has_key("actors")) parse_actors(root.key("actors"), actor_names, actor_objects);
 
 		default_allocator().deallocate(buf);
@@ -638,13 +632,13 @@ namespace physics_config_resource
 
 		if (header.num_actors)
 		{
-			// Write shape names
+			// Write actor names
 			for (uint32_t i = 0; i < array::size(actor_names); i++)
 			{
 				out_file->write((char*) &actor_names[i].name, sizeof(StringId32));
 			}
 
-			// Write material objects
+			// Write actor objects
 			for (uint32_t i = 0; i < array::size(actor_names); i++)
 			{
 				out_file->write((char*) &actor_objects[actor_names[i].index], sizeof(PhysicsActor2));
@@ -653,18 +647,20 @@ namespace physics_config_resource
 
 		if (header.num_filters)
 		{
-			// Write shape names
+			// Write filter names
 			for (uint32_t i = 0; i < array::size(filter_names); i++)
 			{
 				out_file->write((char*) &filter_names[i].name, sizeof(StringId32));
 			}
 
-			// Write material objects
+			// Write filter objects
 			for (uint32_t i = 0; i < array::size(filter_names); i++)
 			{
 				out_file->write((char*) &filter_objects[filter_names[i].index], sizeof(PhysicsCollisionFilter));
 			}
 		}
+
+		CE_DELETE(default_allocator(), s_ftm);
 	}
 
 } // namespace physics_config_resource

+ 25 - 2
engine/resource/PhysicsResource.h

@@ -71,6 +71,7 @@ struct PhysicsActor
 	StringId32 name;			// Name of the actor
 	StringId32 node;			// Node from .unit file
 	StringId32 actor_class;		// Actor from global.physics
+	float mass;					// Mass of the actor
 	uint32_t num_shapes;		// Number of shapes
 };
 
@@ -296,7 +297,7 @@ struct PhysicsCollisionFilter
 
 struct PhysicsShape2
 {
-	uint32_t collision_filter;
+	StringId32 collision_filter;
 	bool trigger;
 };
 
@@ -309,7 +310,6 @@ struct PhysicsActor2
 		DISABLE_GRAVITY	= (1 << 2)
 	};
 
-	uint32_t collision_filter;
 	float linear_damping;
 	float angular_damping;
 	uint8_t flags;
@@ -426,6 +426,29 @@ struct PhysicsConfigResource
 		return base[i];
 	}
 
+	uint32_t num_filters() const
+	{
+		return ((PhysicsConfigHeader*) this)->num_filters;	
+	}
+
+	PhysicsCollisionFilter filter(StringId32 name) const
+	{
+		const PhysicsConfigHeader* h = (PhysicsConfigHeader*) this;
+		StringId32* begin = (StringId32*) (((char*) this) + h->filters_offset);
+		StringId32* end = begin + num_filters();
+		StringId32* id = std::find(begin, end, name);
+		CE_ASSERT(id != end, "Filter not found");
+		return filter_by_index(id - begin);
+	}
+
+	PhysicsCollisionFilter filter_by_index(uint32_t i) const
+	{
+		CE_ASSERT(i < num_filters(), "Index out of bounds");
+		const PhysicsConfigHeader* h = (PhysicsConfigHeader*) this;
+		const PhysicsCollisionFilter* base = (PhysicsCollisionFilter*) (((char*) this) + h->filters_offset + sizeof(StringId32) * num_filters());
+		return base[i];
+	}
+
 private:
 
 	// Disable construction

+ 1 - 0
engine/resource/UnitResource.cpp

@@ -83,6 +83,7 @@ uint32_t compute_link_depth(const GraphNode& node, const Array<GraphNode>& nodes
 	}
 
 	CE_FATAL("Node not found");
+	return 0;
 }
 
 //-----------------------------------------------------------------------------

+ 1 - 0
engine/world/SceneGraph.cpp

@@ -109,6 +109,7 @@ int32_t SceneGraph::node(StringId32 name) const
 	}
 
 	CE_FATAL("Node not found");
+	return 0;
 }
 
 //-----------------------------------------------------------------------------

+ 1 - 0
engine/world/SceneGraphManager.cpp

@@ -27,6 +27,7 @@ OTHER DEALINGS IN THE SOFTWARE.
 #include "SceneGraphManager.h"
 #include "SceneGraph.h"
 #include "Array.h"
+#include "Memory.h"
 
 namespace crown
 {

+ 1 - 1
engine/world/Unit.cpp

@@ -219,7 +219,7 @@ void Unit::create_physics_objects()
 			Actor* a1 = actor_by_index(joint.actor_0);
 			Actor* a2 = actor_by_index(joint.actor_1);
 
-			JointId id = m_world.physics_world()->create_joint(pr, i, *a1, *a2);
+			m_world.physics_world()->create_joint(pr, i, *a1, *a2);
 		}
 	}
 }

+ 2 - 1
engine/world/World.cpp

@@ -24,6 +24,7 @@ FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
 OTHER DEALINGS IN THE SOFTWARE.
 */
 
+#include <new>
 #include "Assert.h"
 #include "World.h"
 #include "Allocator.h"
@@ -341,7 +342,7 @@ void World::process_physics_events()
 			}
 			case physics_world::EventType::TRIGGER:
 			{
-				physics_world::TriggerEvent trigg_ev = *(physics_world::TriggerEvent*) event;
+				// physics_world::TriggerEvent trigg_ev = *(physics_world::TriggerEvent*) event;
 
 				// Log::d("type    = %s", trigg_ev.type == physics_world::TriggerEvent::BEGIN_TOUCH ? "begin" : "end");
 				// Log::d("trigger = (%p)", trigg_ev.trigger);