Browse Source

Some JOLT integration

Panagiotis Christopoulos Charitos 11 months ago
parent
commit
e1dc3c0120

+ 1 - 1
AnKi/CMakeLists.txt

@@ -1,5 +1,5 @@
 set(ANKI_SUB_DIRS Importer Core Script Renderer Scene Ui Window Physics Resource Gr Collision Math Util ShaderCompiler
 set(ANKI_SUB_DIRS Importer Core Script Renderer Scene Ui Window Physics Resource Gr Collision Math Util ShaderCompiler
-	Shaders)
+	Shaders Physics2)
 foreach(TMP ${ANKI_SUB_DIRS})
 foreach(TMP ${ANKI_SUB_DIRS})
 	add_subdirectory(${TMP})
 	add_subdirectory(${TMP})
 endforeach()
 endforeach()

+ 1 - 1
AnKi/Physics/PhysicsBody.cpp

@@ -32,7 +32,7 @@ PhysicsBody::PhysicsBody(const PhysicsBodyInitInfo& init)
 	// Create body
 	// Create body
 	btRigidBody::btRigidBodyConstructionInfo cInfo(init.m_mass, &m_motionState, shape, localInertia);
 	btRigidBody::btRigidBodyConstructionInfo cInfo(init.m_mass, &m_motionState, shape, localInertia);
 	cInfo.m_friction = init.m_friction;
 	cInfo.m_friction = init.m_friction;
-	m_body.init(cInfo);
+	m_body.construct(cInfo);
 
 
 	// User pointer
 	// User pointer
 	m_body->setUserPointer(static_cast<PhysicsObject*>(this));
 	m_body->setUserPointer(static_cast<PhysicsObject*>(this));

+ 6 - 6
AnKi/Physics/PhysicsCollisionShape.cpp

@@ -11,7 +11,7 @@ namespace anki {
 PhysicsSphere::PhysicsSphere(F32 radius)
 PhysicsSphere::PhysicsSphere(F32 radius)
 	: PhysicsCollisionShape(ShapeType::kSphere)
 	: PhysicsCollisionShape(ShapeType::kSphere)
 {
 {
-	m_sphere.init(radius);
+	m_sphere.construct(radius);
 	m_sphere->setMargin(PhysicsWorld::getSingleton().getCollisionMargin());
 	m_sphere->setMargin(PhysicsWorld::getSingleton().getCollisionMargin());
 	m_sphere->setUserPointer(static_cast<PhysicsObject*>(this));
 	m_sphere->setUserPointer(static_cast<PhysicsObject*>(this));
 }
 }
@@ -24,7 +24,7 @@ PhysicsSphere::~PhysicsSphere()
 PhysicsBox::PhysicsBox(const Vec3& extend)
 PhysicsBox::PhysicsBox(const Vec3& extend)
 	: PhysicsCollisionShape(ShapeType::kBox)
 	: PhysicsCollisionShape(ShapeType::kBox)
 {
 {
-	m_box.init(toBt(extend));
+	m_box.construct(toBt(extend));
 	m_box->setMargin(PhysicsWorld::getSingleton().getCollisionMargin());
 	m_box->setMargin(PhysicsWorld::getSingleton().getCollisionMargin());
 	m_box->setUserPointer(static_cast<PhysicsObject*>(this));
 	m_box->setUserPointer(static_cast<PhysicsObject*>(this));
 }
 }
@@ -41,7 +41,7 @@ PhysicsTriangleSoup::PhysicsTriangleSoup(ConstWeakArray<Vec3> positions, ConstWe
 	{
 	{
 		ANKI_ASSERT((indices.getSize() % 3) == 0);
 		ANKI_ASSERT((indices.getSize() % 3) == 0);
 
 
-		m_mesh.init();
+		m_mesh.construct();
 
 
 		for(U32 i = 0; i < indices.getSize(); i += 3)
 		for(U32 i = 0; i < indices.getSize(); i += 3)
 		{
 		{
@@ -49,13 +49,13 @@ PhysicsTriangleSoup::PhysicsTriangleSoup(ConstWeakArray<Vec3> positions, ConstWe
 		}
 		}
 
 
 		// Create the dynamic shape
 		// Create the dynamic shape
-		m_triMesh.m_dynamic.init(m_mesh.get());
+		m_triMesh.m_dynamic.construct(m_mesh.get());
 		m_triMesh.m_dynamic->setMargin(PhysicsWorld::getSingleton().getCollisionMargin());
 		m_triMesh.m_dynamic->setMargin(PhysicsWorld::getSingleton().getCollisionMargin());
 		m_triMesh.m_dynamic->updateBound();
 		m_triMesh.m_dynamic->updateBound();
 		m_triMesh.m_dynamic->setUserPointer(static_cast<PhysicsObject*>(this));
 		m_triMesh.m_dynamic->setUserPointer(static_cast<PhysicsObject*>(this));
 
 
 		// And the static one
 		// And the static one
-		m_triMesh.m_static.init(m_mesh.get(), true);
+		m_triMesh.m_static.construct(m_mesh.get(), true);
 		m_triMesh.m_static->setMargin(PhysicsWorld::getSingleton().getCollisionMargin());
 		m_triMesh.m_static->setMargin(PhysicsWorld::getSingleton().getCollisionMargin());
 		m_triMesh.m_static->setUserPointer(static_cast<PhysicsObject*>(this));
 		m_triMesh.m_static->setUserPointer(static_cast<PhysicsObject*>(this));
 	}
 	}
@@ -63,7 +63,7 @@ PhysicsTriangleSoup::PhysicsTriangleSoup(ConstWeakArray<Vec3> positions, ConstWe
 	{
 	{
 		m_type = ShapeType::kConvex; // Fake the type
 		m_type = ShapeType::kConvex; // Fake the type
 
 
-		m_convex.init(&positions[0][0], I32(positions.getSize()), U32(sizeof(Vec3)));
+		m_convex.construct(&positions[0][0], I32(positions.getSize()), U32(sizeof(Vec3)));
 		m_convex->setMargin(PhysicsWorld::getSingleton().getCollisionMargin());
 		m_convex->setMargin(PhysicsWorld::getSingleton().getCollisionMargin());
 		m_convex->setUserPointer(static_cast<PhysicsObject*>(this));
 		m_convex->setUserPointer(static_cast<PhysicsObject*>(this));
 	}
 	}

+ 3 - 3
AnKi/Physics/PhysicsJoint.cpp

@@ -29,7 +29,7 @@ PhysicsPoint2PointJoint::PhysicsPoint2PointJoint(PhysicsBodyPtr bodyA, const Vec
 	: PhysicsJoint(JointType::kP2P)
 	: PhysicsJoint(JointType::kP2P)
 {
 {
 	m_bodyA = std::move(bodyA);
 	m_bodyA = std::move(bodyA);
-	m_p2p.init(*m_bodyA->getBtBody(), toBt(relPos));
+	m_p2p.construct(*m_bodyA->getBtBody(), toBt(relPos));
 	getJoint()->setUserConstraintPtr(static_cast<PhysicsObject*>(this));
 	getJoint()->setUserConstraintPtr(static_cast<PhysicsObject*>(this));
 }
 }
 
 
@@ -40,7 +40,7 @@ PhysicsPoint2PointJoint::PhysicsPoint2PointJoint(PhysicsBodyPtr bodyA, const Vec
 	m_bodyA = std::move(bodyA);
 	m_bodyA = std::move(bodyA);
 	m_bodyB = std::move(bodyB);
 	m_bodyB = std::move(bodyB);
 
 
-	m_p2p.init(*m_bodyA->getBtBody(), *m_bodyB->getBtBody(), toBt(relPosA), toBt(relPosB));
+	m_p2p.construct(*m_bodyA->getBtBody(), *m_bodyB->getBtBody(), toBt(relPosA), toBt(relPosB));
 	getJoint()->setUserConstraintPtr(static_cast<PhysicsObject*>(this));
 	getJoint()->setUserConstraintPtr(static_cast<PhysicsObject*>(this));
 }
 }
 
 
@@ -53,7 +53,7 @@ PhysicsHingeJoint::PhysicsHingeJoint(PhysicsBodyPtr bodyA, const Vec3& relPos, c
 	: PhysicsJoint(JointType::kHinge)
 	: PhysicsJoint(JointType::kHinge)
 {
 {
 	m_bodyA = std::move(bodyA);
 	m_bodyA = std::move(bodyA);
-	m_hinge.init(*m_bodyA->getBtBody(), toBt(relPos), toBt(axis));
+	m_hinge.construct(*m_bodyA->getBtBody(), toBt(relPos), toBt(axis));
 	getJoint()->setUserConstraintPtr(static_cast<PhysicsObject*>(this));
 	getJoint()->setUserConstraintPtr(static_cast<PhysicsObject*>(this));
 }
 }
 
 

+ 3 - 3
AnKi/Physics/PhysicsPlayerController.cpp

@@ -13,16 +13,16 @@ PhysicsPlayerController::PhysicsPlayerController(const PhysicsPlayerControllerIn
 {
 {
 	const btTransform trf = toBt(Transform(init.m_position.xyz0(), Mat3x4::getIdentity(), Vec4(1.0f, 1.0f, 1.0f, 0.0f)));
 	const btTransform trf = toBt(Transform(init.m_position.xyz0(), Mat3x4::getIdentity(), Vec4(1.0f, 1.0f, 1.0f, 0.0f)));
 
 
-	m_convexShape.init(init.m_outerRadius, init.m_height);
+	m_convexShape.construct(init.m_outerRadius, init.m_height);
 
 
-	m_ghostObject.init();
+	m_ghostObject.construct();
 	m_ghostObject->setWorldTransform(trf);
 	m_ghostObject->setWorldTransform(trf);
 	m_ghostObject->setCollisionShape(m_convexShape.get());
 	m_ghostObject->setCollisionShape(m_convexShape.get());
 	m_ghostObject->setUserPointer(static_cast<PhysicsObject*>(this));
 	m_ghostObject->setUserPointer(static_cast<PhysicsObject*>(this));
 	setMaterialGroup(PhysicsMaterialBit::kPlayer);
 	setMaterialGroup(PhysicsMaterialBit::kPlayer);
 	setMaterialMask(PhysicsMaterialBit::kAll);
 	setMaterialMask(PhysicsMaterialBit::kAll);
 
 
-	m_controller.init(m_ghostObject.get(), m_convexShape.get(), init.m_stepHeight, btVector3(0, 1, 0));
+	m_controller.construct(m_ghostObject.get(), m_convexShape.get(), init.m_stepHeight, btVector3(0, 1, 0));
 
 
 	// Need to call this else the player is upside down
 	// Need to call this else the player is upside down
 	moveToPosition(init.m_position);
 	moveToPosition(init.m_position);

+ 1 - 1
AnKi/Physics/PhysicsTrigger.cpp

@@ -15,7 +15,7 @@ PhysicsTrigger::PhysicsTrigger(PhysicsCollisionShapePtr shape)
 {
 {
 	m_shape = shape;
 	m_shape = shape;
 
 
-	m_ghostShape.init();
+	m_ghostShape.construct();
 	m_ghostShape->setWorldTransform(btTransform::getIdentity());
 	m_ghostShape->setWorldTransform(btTransform::getIdentity());
 	m_ghostShape->setCollisionShape(shape->getBtShape(true));
 	m_ghostShape->setCollisionShape(shape->getBtShape(true));
 
 

+ 6 - 6
AnKi/Physics/PhysicsWorld.cpp

@@ -165,20 +165,20 @@ Error PhysicsWorld::init(AllocAlignedCallback allocCb, void* allocCbData)
 	btAlignedAllocSetCustom(btAlloc, btFree);
 	btAlignedAllocSetCustom(btAlloc, btFree);
 
 
 	// Create objects
 	// Create objects
-	m_broadphase.init();
-	m_gpc.init();
+	m_broadphase.construct();
+	m_gpc.construct();
 	m_broadphase->getOverlappingPairCache()->setInternalGhostPairCallback(m_gpc.get());
 	m_broadphase->getOverlappingPairCache()->setInternalGhostPairCallback(m_gpc.get());
 	m_filterCallback = anki::newInstance<MyOverlapFilterCallback>(PhysicsMemoryPool::getSingleton());
 	m_filterCallback = anki::newInstance<MyOverlapFilterCallback>(PhysicsMemoryPool::getSingleton());
 	m_broadphase->getOverlappingPairCache()->setOverlapFilterCallback(m_filterCallback);
 	m_broadphase->getOverlappingPairCache()->setOverlapFilterCallback(m_filterCallback);
 
 
-	m_collisionConfig.init();
+	m_collisionConfig.construct();
 
 
-	m_dispatcher.init(m_collisionConfig.get());
+	m_dispatcher.construct(m_collisionConfig.get());
 	btGImpactCollisionAlgorithm::registerAlgorithm(m_dispatcher.get());
 	btGImpactCollisionAlgorithm::registerAlgorithm(m_dispatcher.get());
 
 
-	m_solver.init();
+	m_solver.construct();
 
 
-	m_world.init(m_dispatcher.get(), m_broadphase.get(), m_solver.get(), m_collisionConfig.get());
+	m_world.construct(m_dispatcher.get(), m_broadphase.get(), m_solver.get(), m_collisionConfig.get());
 	m_world->setGravity(btVector3(0.0f, -9.8f, 0.0f));
 	m_world->setGravity(btVector3(0.0f, -9.8f, 0.0f));
 
 
 	return Error::kNone;
 	return Error::kNone;

+ 5 - 0
AnKi/Physics2/CMakeLists.txt

@@ -0,0 +1,5 @@
+file(GLOB_RECURSE sources *.cpp)
+file(GLOB_RECURSE headers *.h)
+add_library(AnKiPhysics2 ${sources} ${headers})
+target_compile_definitions(AnKiPhysics2 PRIVATE -DANKI_SOURCE_FILE)
+target_link_libraries(AnKiPhysics2 AnKiUtil)

+ 56 - 0
AnKi/Physics2/Common.h

@@ -0,0 +1,56 @@
+// Copyright (C) 2009-present, Panagiotis Christopoulos Charitos and contributors.
+// All rights reserved.
+// Code licensed under the BSD License.
+// http://www.anki3d.org/LICENSE
+
+#pragma once
+
+#include <AnKi/Util/StdTypes.h>
+#include <AnKi/Util/Enum.h>
+#include <AnKi/Util/Ptr.h>
+#include <AnKi/Util/MemoryPool.h>
+#include <AnKi/Math.h>
+
+#include <Jolt/Jolt.h>
+
+namespace anki {
+
+#define ANKI_PHYS_LOGI(...) ANKI_LOG("PHYS", kNormal, __VA_ARGS__)
+#define ANKI_PHYS_LOGE(...) ANKI_LOG("PHYS", kError, __VA_ARGS__)
+#define ANKI_PHYS_LOGW(...) ANKI_LOG("PHYS", kWarning, __VA_ARGS__)
+#define ANKI_PHYS_LOGF(...) ANKI_LOG("PHYS", kFatal, __VA_ARGS__)
+
+class Physics2MemoryPool : public HeapMemoryPool, public MakeSingleton<Physics2MemoryPool>
+{
+	template<typename>
+	friend class MakeSingleton;
+
+private:
+	Physics2MemoryPool(AllocAlignedCallback allocCb, void* allocCbUserData)
+		: HeapMemoryPool(allocCb, allocCbUserData, "PhysicsMemPool")
+	{
+	}
+
+	~Physics2MemoryPool() = default;
+};
+
+ANKI_DEFINE_SUBMODULE_UTIL_CONTAINERS(Physics2, Physics2MemoryPool)
+
+// Forward
+class Physics2CollisionShape;
+
+/// Custom deleter.
+class Physics2CollisionShapePtrDeleter
+{
+public:
+	void operator()(Physics2CollisionShape* ptr);
+};
+
+using Physics2CollisionShapePtr = IntrusivePtr<Physics2CollisionShape, Physics2CollisionShapePtrDeleter>;
+
+inline JPH::RVec3 toJPH(Vec3 ak)
+{
+	return JPH::RVec3(ak.x(), ak.y(), ak.z());
+}
+
+} // end namespace anki

+ 104 - 0
AnKi/Physics2/PhysicsBody.h

@@ -0,0 +1,104 @@
+// Copyright (C) 2009-present, Panagiotis Christopoulos Charitos and contributors.
+// All rights reserved.
+// Code licensed under the BSD License.
+// http://www.anki3d.org/LICENSE
+
+#pragma once
+
+#include <AnKi/Physics2/Common.h>
+#include <AnKi/Util/ClassWrapper.h>
+#include <Jolt/Physics/Body/Body.h>
+
+namespace anki {
+
+/// @addtogroup physics
+/// @{
+
+/// Init info for PhysicsBody.
+class PhysicsBodyInitInfo
+{
+public:
+	Physics2CollisionShape* m_shape = nullptr;
+	F32 m_mass = 0.0f;
+	Transform m_transform = Transform::getIdentity();
+	F32 m_friction = 0.5f;
+};
+
+/// Rigid body.
+class PhysicsBody
+{
+public:
+	const Transform& getTransform() const
+	{
+		return m_trf;
+	}
+
+	void setTransform(const Transform& trf)
+	{
+		// TODO
+	}
+
+	void applyForce(const Vec3& force, const Vec3& relPos)
+	{
+		// TODO
+	}
+
+	void setMass(F32 mass);
+
+	F32 getMass() const
+	{
+		return m_mass;
+	}
+
+	void activate(Bool activate)
+	{
+		// TODO
+	}
+
+	void clearForces()
+	{
+		// TODO
+	}
+
+	void setLinearVelocity(const Vec3& velocity)
+	{
+		// TODO
+	}
+
+	void setAngularVelocity(const Vec3& velocity)
+	{
+		// TODO
+	}
+
+	void setGravity(const Vec3& gravity)
+	{
+		// TODO
+	}
+
+	void setAngularFactor(const Vec3& factor)
+	{
+		// TODO
+	}
+
+private:
+	/// Store the data of the btRigidBody in place to avoid additional allocations.
+	ClassWrapper<btRigidBody> m_body;
+
+	Transform m_trf = Transform::getIdentity();
+	MotionState m_motionState;
+
+	PhysicsCollisionShapePtr m_shape;
+
+	F32 m_mass = 1.0f;
+
+	PhysicsBody(const PhysicsBodyInitInfo& init);
+
+	~PhysicsBody();
+
+	void registerToWorld() override;
+
+	void unregisterFromWorld() override;
+};
+/// @}
+
+} // end namespace anki

+ 6 - 0
AnKi/Physics2/PhysicsCollisionShape.cpp

@@ -0,0 +1,6 @@
+// Copyright (C) 2009-present, Panagiotis Christopoulos Charitos and contributors.
+// All rights reserved.
+// Code licensed under the BSD License.
+// http://www.anki3d.org/LICENSE
+
+#include <AnKi/Physics2/PhysicsCollisionShape.h>

+ 75 - 0
AnKi/Physics2/PhysicsCollisionShape.h

@@ -0,0 +1,75 @@
+// Copyright (C) 2009-present, Panagiotis Christopoulos Charitos and contributors.
+// All rights reserved.
+// Code licensed under the BSD License.
+// http://www.anki3d.org/LICENSE
+
+#pragma once
+
+#include <AnKi/Physics2/Common.h>
+#include <AnKi/Util/WeakArray.h>
+#include <AnKi/Util/ClassWrapper.h>
+#include <Jolt/Physics/Collision/Shape/BoxShape.h>
+#include <Jolt/Physics/Collision/Shape/SphereShape.h>
+
+namespace anki {
+
+/// Wrapper on top of JPH collision shapes.
+class Physics2CollisionShape
+{
+	friend class Physics2World;
+	template<typename, typename>
+	friend class IntrusivePtr;
+	template<typename, typename, typename>
+	friend class BlockArray;
+
+protected:
+	enum ShapeType : U8
+	{
+		kBox,
+		kSphere,
+		kConvex,
+		kTrimesh
+	};
+
+	union
+	{
+		ClassWrapper<JPH::BoxShape> m_box;
+		ClassWrapper<JPH::SphereShape> m_sphere;
+	};
+
+	mutable Atomic<U32> m_refcount = {0};
+	U32 m_arrayIndex : 24 = 0b111111111111111111111111;
+	U32 m_type : 8;
+
+	Physics2CollisionShape(ShapeType type)
+		: m_type(type)
+	{
+	}
+
+	~Physics2CollisionShape()
+	{
+		switch(m_type)
+		{
+		case ShapeType::kBox:
+			m_box.destroy();
+			break;
+		case ShapeType::kSphere:
+			m_sphere.destroy();
+			break;
+		default:
+			ANKI_ASSERT(0);
+		}
+	}
+
+	void retain() const
+	{
+		m_refcount.fetchAdd(1);
+	}
+
+	U32 release() const
+	{
+		return m_refcount.fetchSub(1);
+	}
+};
+
+} // end namespace anki

+ 19 - 0
AnKi/Physics2/PhysicsJoint.h

@@ -0,0 +1,19 @@
+// Copyright (C) 2009-present, Panagiotis Christopoulos Charitos and contributors.
+// All rights reserved.
+// Code licensed under the BSD License.
+// http://www.anki3d.org/LICENSE
+
+#pragma once
+
+#include <AnKi/Physics2/Common.h>
+#include <AnKi/Physics2/PhysicsCollisionShape.h>
+#include <AnKi/Util/BlockArray.h>
+
+namespace anki {
+
+/// @addtogroup physics
+/// @{
+
+/// @}
+
+} // end namespace anki

+ 39 - 0
AnKi/Physics2/PhysicsWorld.cpp

@@ -0,0 +1,39 @@
+// Copyright (C) 2009-present, Panagiotis Christopoulos Charitos and contributors.
+// All rights reserved.
+// Code licensed under the BSD License.
+// http://www.anki3d.org/LICENSE
+
+#include <AnKi/Physics2/PhysicsWorld.h>
+#include <AnKi/Physics2/PhysicsCollisionShape.h>
+
+namespace anki {
+
+void Physics2CollisionShapePtrDeleter::operator()(Physics2CollisionShape* ptr)
+{
+	Physics2World::getSingleton().destroyCollisionShape(ptr);
+}
+
+Physics2CollisionShapePtr Physics2World::newSphereCollisionShape(F32 radius)
+{
+	auto it = m_collisionShapes.emplace(Physics2CollisionShape::ShapeType::kSphere);
+	it->m_sphere.construct(radius);
+	it->m_sphere->SetEmbedded();
+	it->m_arrayIndex = it.getArrayIndex();
+	return Physics2CollisionShapePtr(&(*it));
+}
+
+Physics2CollisionShapePtr Physics2World::newBoxCollisionShape(Vec3 extend)
+{
+	auto it = m_collisionShapes.emplace(Physics2CollisionShape::ShapeType::kBox);
+	it->m_box.construct(toJPH(extend));
+	it->m_box->SetEmbedded();
+	it->m_arrayIndex = it.getArrayIndex();
+	return Physics2CollisionShapePtr(&(*it));
+}
+
+void Physics2World::destroyCollisionShape(Physics2CollisionShape* ptr)
+{
+	m_collisionShapes.erase(ptr->m_arrayIndex);
+}
+
+} // end namespace anki

+ 44 - 0
AnKi/Physics2/PhysicsWorld.h

@@ -0,0 +1,44 @@
+// Copyright (C) 2009-present, Panagiotis Christopoulos Charitos and contributors.
+// All rights reserved.
+// Code licensed under the BSD License.
+// http://www.anki3d.org/LICENSE
+
+#pragma once
+
+#include <AnKi/Physics2/Common.h>
+#include <AnKi/Physics2/PhysicsCollisionShape.h>
+#include <AnKi/Util/BlockArray.h>
+#include <Jolt/Physics/PhysicsSystem.h>
+
+namespace anki {
+
+/// @addtogroup physics
+/// @{
+
+/// The master container for all physics related stuff.
+class Physics2World : public MakeSingleton<Physics2World>
+{
+	template<typename>
+	friend class MakeSingleton;
+	friend class Physics2CollisionShapePtrDeleter;
+
+public:
+	Error init(AllocAlignedCallback allocCb, void* allocCbData);
+
+	Physics2CollisionShapePtr newSphereCollisionShape(F32 radius);
+	Physics2CollisionShapePtr newBoxCollisionShape(Vec3 extend);
+
+private:
+	BlockArray<Physics2CollisionShape, SingletonMemoryPoolWrapper<Physics2MemoryPool>> m_collisionShapes;
+
+	JPH::PhysicsSystem m_jphPhysicsSystem;
+
+	Physics2World();
+
+	~Physics2World();
+
+	void destroyCollisionShape(Physics2CollisionShape* ptr);
+};
+/// @}
+
+} // end namespace anki

+ 1 - 1
AnKi/Ui/Font.cpp

@@ -22,7 +22,7 @@ Font::~Font()
 
 
 Error Font::init(const CString& filename, ConstWeakArray<U32> fontHeights)
 Error Font::init(const CString& filename, ConstWeakArray<U32> fontHeights)
 {
 {
-	m_imFontAtlas.init();
+	m_imFontAtlas.construct();
 
 
 	// Load font in memory
 	// Load font in memory
 	ResourceFilePtr file;
 	ResourceFilePtr file;

+ 1 - 1
AnKi/Util/ClassWrapper.h

@@ -25,7 +25,7 @@ public:
 
 
 	/// Call the constructor of the TClass.
 	/// Call the constructor of the TClass.
 	template<typename... TArgs>
 	template<typename... TArgs>
-	void init(TArgs&&... args)
+	void construct(TArgs&&... args)
 	{
 	{
 		::new(&m_data[0]) TClass(std::forward<TArgs>(args)...);
 		::new(&m_data[0]) TClass(std::forward<TArgs>(args)...);
 	}
 	}

+ 1 - 0
CMakeLists.txt

@@ -452,6 +452,7 @@ include_directories(
 	"${CMAKE_CURRENT_SOURCE_DIR}/ThirdParty/Bullet/src"
 	"${CMAKE_CURRENT_SOURCE_DIR}/ThirdParty/Bullet/src"
 	"ThirdParty"
 	"ThirdParty"
 	"ThirdParty/ZLib"
 	"ThirdParty/ZLib"
+	"ThirdParty/Jolt"
 	${CMAKE_CURRENT_SOURCE_DIR})
 	${CMAKE_CURRENT_SOURCE_DIR})
 
 
 if(SDL2_INCLUDE_DIRS)
 if(SDL2_INCLUDE_DIRS)