Browse Source

Port the character controller

Panagiotis Christopoulos Charitos 7 years ago
parent
commit
8312d3151b

+ 53 - 9
samples/physics_playground/Main.cpp

@@ -11,20 +11,64 @@ using namespace anki;
 class MyApp : public SampleApp
 {
 public:
-	Error sampleExtraInit() override
-	{
-		ScriptResourcePtr script;
-		ANKI_CHECK(getResourceManager().loadResource("assets/scene.lua", script));
-		ANKI_CHECK(getScriptManager().evalString(script->getSource()));
-		return Error::NONE;
-	}
-
+	Error sampleExtraInit() override;
 	Error userMainLoop(Bool& quit) override;
 };
 
+Error MyApp::sampleExtraInit()
+{
+	ScriptResourcePtr script;
+	ANKI_CHECK(getResourceManager().loadResource("assets/scene.lua", script));
+	ANKI_CHECK(getScriptManager().evalString(script->getSource()));
+
+	SceneNode& cam = getSceneGraph().getActiveCameraNode();
+	cam.getComponent<MoveComponent>().setLocalTransform(
+		Transform(Vec4(0.0, 0.0, 5.0, 0.0), Mat3x4::getIdentity(), 1.0));
+
+	PlayerNode* player;
+	ANKI_CHECK(getSceneGraph().newSceneNode("player", player, Vec4(0.0f, 2.5f, 0.0f, 0.0f)));
+
+	player->addChild(&cam);
+
+	return Error::NONE;
+}
+
 Error MyApp::userMainLoop(Bool& quit)
 {
-	ANKI_CHECK(SampleApp::userMainLoop(quit));
+	// ANKI_CHECK(SampleApp::userMainLoop(quit));
+
+	if(getInput().getKey(KeyCode::ESCAPE))
+	{
+		quit = true;
+	}
+
+	if(getInput().getKey(KeyCode::F1) == 1)
+	{
+		static U mode = 0;
+		mode = (mode + 1) % 3;
+		if(mode == 0)
+		{
+			getMainRenderer().getDbg().setEnabled(false);
+		}
+		else if(mode == 1)
+		{
+			getMainRenderer().getDbg().setEnabled(true);
+			getMainRenderer().getDbg().setDepthTestEnabled(true);
+			getMainRenderer().getDbg().setDitheredDepthTestEnabled(false);
+		}
+		else
+		{
+			getMainRenderer().getDbg().setEnabled(true);
+			getMainRenderer().getDbg().setDepthTestEnabled(false);
+			getMainRenderer().getDbg().setDitheredDepthTestEnabled(true);
+		}
+	}
+
+	if(getInput().getKey(KeyCode::R))
+	{
+		SceneNode& player = getSceneGraph().findSceneNode("player");
+		player.getComponent<PlayerControllerComponent>().moveToPosition(Vec4(0.0f, 2.0f, 0.0f, 0.0f));
+	}
 
 	if(getInput().getMouseButton(MouseButton::LEFT) == 1)
 	{

+ 1 - 0
src/anki/physics/PhysicsBody.cpp

@@ -46,6 +46,7 @@ PhysicsBody::PhysicsBody(PhysicsWorld* world, const PhysicsBodyInitInfo& init)
 
 	// Create body
 	btRigidBody::btRigidBodyConstructionInfo cInfo(init.m_mass, m_motionState, shape, localInertia);
+	cInfo.m_friction = init.m_friction;
 	m_body = getAllocator().newInstance<btRigidBody>(cInfo);
 
 	getWorld().getBtWorld()->addRigidBody(m_body);

+ 1 - 0
src/anki/physics/PhysicsBody.h

@@ -22,6 +22,7 @@ public:
 	Transform m_startTrf = Transform::getIdentity();
 	Bool m_kinematic = false;
 	Bool m_gravity = true;
+	F32 m_friction = 0.5f;
 };
 
 /// Rigid body.

+ 1 - 1
src/anki/physics/PhysicsObject.h

@@ -64,7 +64,7 @@ protected:
 	PhysicsWorld* m_world = nullptr;
 
 private:
-	Atomic<I32> m_refcount = {};
+	Atomic<I32> m_refcount = {0};
 	PhysicsObjectType m_type;
 };
 /// @}

+ 19 - 3
src/anki/physics/PhysicsPlayerController.cpp

@@ -12,21 +12,37 @@ namespace anki
 PhysicsPlayerController::PhysicsPlayerController(PhysicsWorld* world, const PhysicsPlayerControllerInitInfo& init)
 	: PhysicsObject(PhysicsObjectType::PLAYER_CONTROLLER, world)
 {
+	btTransform trf = toBt(Transform(init.m_position.xyz0(), Mat3x4::getIdentity(), 1.0f));
+
+	m_convexShape = getAllocator().newInstance<btCapsuleShapeZ>(init.m_outerRadius, init.m_height);
+
 	m_ghostObject = getAllocator().newInstance<btPairCachingGhostObject>();
-	m_convexShape = getAllocator().newInstance<btCapsuleShape>(init.m_outerRadius, init.m_height);
+	m_ghostObject->setWorldTransform(trf);
+	m_ghostObject->setCollisionShape(m_convexShape);
+	m_ghostObject->setCollisionFlags(btCollisionObject::CF_CHARACTER_OBJECT);
 
 	m_controller = getAllocator().newInstance<btKinematicCharacterController>(
 		m_ghostObject, m_convexShape, init.m_stepHeight, btVector3(0, 1, 0));
+
+	getWorld().getBtWorld()->addCollisionObject(m_ghostObject,
+		btBroadphaseProxy::CharacterFilter,
+		btBroadphaseProxy::StaticFilter | btBroadphaseProxy::DefaultFilter);
+	getWorld().getBtWorld()->addAction(m_controller);
 }
 
 PhysicsPlayerController::~PhysicsPlayerController()
 {
-	// TODO
+	getWorld().getBtWorld()->removeAction(m_controller);
+	getWorld().getBtWorld()->removeCollisionObject(m_ghostObject);
+
+	getAllocator().deleteInstance(m_controller);
+	getAllocator().deleteInstance(m_ghostObject);
+	getAllocator().deleteInstance(m_convexShape);
 }
 
 void PhysicsPlayerController::moveToPosition(const Vec4& position)
 {
-	ANKI_ASSERT(!"TODO");
+	m_ghostObject->setWorldTransform(toBt(Transform(position, Mat3x4::getIdentity(), 1.0f)));
 }
 
 } // end namespace anki

+ 6 - 2
src/anki/physics/PhysicsPlayerController.h

@@ -36,20 +36,24 @@ public:
 	// Update the state machine
 	void setVelocity(F32 forwardSpeed, F32 strafeSpeed, F32 jumpSpeed, const Vec4& forwardDir)
 	{
-		// TODO
+		m_controller->setWalkDirection(toBt((forwardDir * forwardSpeed).xyz()));
 	}
 
 	void moveToPosition(const Vec4& position);
 
 	Transform getTransform(Bool& updated)
 	{
-		return Transform();
+		Transform out = toAnki(m_ghostObject->getWorldTransform());
+		updated = m_prevTrf != out;
+		return out;
 	}
 
 private:
 	btPairCachingGhostObject* m_ghostObject = nullptr;
 	btCapsuleShape* m_convexShape = nullptr;
 	btKinematicCharacterController* m_controller = nullptr;
+
+	Transform m_prevTrf = Transform::getIdentity();
 };
 /// @}
 

+ 5 - 1
src/anki/physics/PhysicsWorld.cpp

@@ -39,6 +39,7 @@ PhysicsWorld::~PhysicsWorld()
 	m_alloc.deleteInstance(m_dispatcher);
 	m_alloc.deleteInstance(m_collisionConfig);
 	m_alloc.deleteInstance(m_broadphase);
+	m_alloc.deleteInstance(m_gpc);
 
 	gAlloc = nullptr;
 }
@@ -53,14 +54,17 @@ Error PhysicsWorld::create(AllocAlignedCallback allocCb, void* allocCbData)
 
 	// Create objects
 	m_broadphase = m_alloc.newInstance<btDbvtBroadphase>();
+	m_gpc = m_alloc.newInstance<btGhostPairCallback>();
+	m_broadphase->getOverlappingPairCache()->setInternalGhostPairCallback(m_gpc);
+
 	m_collisionConfig = m_alloc.newInstance<btDefaultCollisionConfiguration>();
 
 	m_dispatcher = m_alloc.newInstance<btCollisionDispatcher>(m_collisionConfig);
 	btGImpactCollisionAlgorithm::registerAlgorithm(m_dispatcher);
 
 	m_solver = m_alloc.newInstance<btSequentialImpulseConstraintSolver>();
-	m_world = m_alloc.newInstance<btDiscreteDynamicsWorld>(m_dispatcher, m_broadphase, m_solver, m_collisionConfig);
 
+	m_world = m_alloc.newInstance<btDiscreteDynamicsWorld>(m_dispatcher, m_broadphase, m_solver, m_collisionConfig);
 	m_world->setGravity(btVector3(0.0f, -9.8f, 0.0f));
 
 	return Error::NONE;

+ 2 - 0
src/anki/physics/PhysicsWorld.h

@@ -62,6 +62,8 @@ private:
 	HeapAllocator<U8> m_alloc;
 
 	btBroadphaseInterface* m_broadphase = nullptr;
+	btGhostPairCallback* m_gpc = nullptr;
+
 	btDefaultCollisionConfiguration* m_collisionConfig = nullptr;
 	btCollisionDispatcher* m_dispatcher = nullptr;
 	btSequentialImpulseConstraintSolver* m_solver = nullptr;

+ 1 - 0
src/anki/resource/ShaderProgramResource.cpp

@@ -30,6 +30,7 @@ Bool ShaderProgramResourceInputVariable::evalPreproc(ConstWeakArray<te_variable>
 		ANKI_RESOURCE_LOGF("Wrong result of the expression: %s", m_preprocExpr.cstr());
 	}
 
+	te_free(n);
 	return evalOut != 0.0;
 }
 

+ 1 - 1
src/anki/scene/PlayerNode.cpp

@@ -77,7 +77,7 @@ public:
 		MoveComponent& move = node.getComponent<MoveComponent>();
 		const Input& in = node.getSceneGraph().getInput();
 
-		const F32 speed = 3.5;
+		const F32 speed = 0.5;
 
 		Vec4 moveVec(0.0);
 		if(in.getKey(KeyCode::W))

+ 5 - 0
src/anki/scene/components/PlayerControllerComponent.h

@@ -43,6 +43,11 @@ public:
 		m_player->setVelocity(forwardSpeed, strafeSpeed, jumpSpeed, forwardDir);
 	}
 
+	void moveToPosition(Vec4 pos)
+	{
+		m_player->moveToPosition(pos);
+	}
+
 	ANKI_USE_RESULT Error update(SceneNode&, Second, Second, Bool& updated) override
 	{
 		m_trf = m_player->getTransform(updated);