Browse Source

Fixes in the physics sample

Panagiotis Christopoulos Charitos 2 years ago
parent
commit
041aa06d05

+ 1 - 0
AnKi/Core/App.cpp

@@ -373,6 +373,7 @@ Error App::initInternal(AllocAlignedCallback allocCb, void* allocCbUserData)
 	renderInit.m_gpuScenePool = m_gpuSceneMemPool;
 	renderInit.m_gpuSceneMicroPatcher = m_gpuSceneMicroPatcher;
 	renderInit.m_unifiedGometryMemoryPool = m_unifiedGometryMemPool;
+	renderInit.m_physicsWorld = m_physics;
 	m_renderer = newInstance<MainRenderer>(m_mainPool);
 	ANKI_CHECK(m_renderer->init(renderInit));
 

+ 11 - 12
AnKi/Importer/GltfImporter.cpp

@@ -566,15 +566,17 @@ Error GltfImporter::visitNode(const cgltf_node& node, const Transform& parentTrf
 				gpuParticles = true;
 			}
 
-			ANKI_CHECK(m_sceneFile.writeTextf("\nnode = scene:newSceneNode(\"%s\")\n", getNodeName(node).cstr()));
+			if(!gpuParticles) // TODO Re-enable GPU particles
+			{
+				ANKI_CHECK(m_sceneFile.writeTextf("\nnode = scene:newSceneNode(\"%s\")\n", getNodeName(node).cstr()));
 
-			ANKI_CHECK(
-				m_sceneFile.writeTextf("comp = node:new%sParticleEmitterComponent()\n", (gpuParticles) ? "Gpu" : ""));
-			ANKI_CHECK(m_sceneFile.writeTextf("comp:loadParticleEmitterResource(\"%s\")\n", fname.cstr()));
+				ANKI_CHECK(m_sceneFile.writeTextf("comp = node:newParticleEmitterComponent()\n"));
+				ANKI_CHECK(m_sceneFile.writeTextf("comp:loadParticleEmitterResource(\"%s\")\n", fname.cstr()));
 
-			Transform localTrf;
-			ANKI_CHECK(getNodeTransform(node, localTrf));
-			ANKI_CHECK(writeTransform(parentTrf.combineTransformations(localTrf)));
+				Transform localTrf;
+				ANKI_CHECK(getNodeTransform(node, localTrf));
+				ANKI_CHECK(writeTransform(parentTrf.combineTransformations(localTrf)));
+			}
 		}
 		else if(stringsExist(extras, {"skybox_solid_color", "skybox_image", "fog_min_density", "fog_max_density",
 									  "fog_height_of_min_density", "fog_height_of_max_density"}))
@@ -807,15 +809,12 @@ Error GltfImporter::visitNode(const cgltf_node& node, const Transform& parentTrf
 
 			if(selfCollision)
 			{
-				ANKI_CHECK(m_sceneFile.writeTextf("node = scene:newSceneNode(\"%s_cl\")\n", getNodeName(node).cstr()));
-
 				ANKI_CHECK(m_sceneFile.writeText("comp = node:newBodyComponent()\n"));
 
 				const StringRaii meshFname = computeMeshResourceFilename(*node.mesh);
 
-				ANKI_CHECK(
-					m_sceneFile.writeTextf("comp:loadMeshResource(\"%s%s\")\n", m_rpath.cstr(), meshFname.cstr()));
-				ANKI_CHECK(m_sceneFile.writeText("comp:setWorldTransform(trf)\n"));
+				ANKI_CHECK(m_sceneFile.writeText("comp:setMeshFromModelComponent()\n"));
+				ANKI_CHECK(m_sceneFile.writeText("comp:teleportTo(trf)\n"));
 			}
 		}
 	}

+ 1 - 0
AnKi/Renderer/Common.h

@@ -85,6 +85,7 @@ public:
 	GpuSceneMemoryPool* m_gpuScenePool = nullptr;
 	GpuSceneMicroPatcher* m_gpuSceneMicroPatcher = nullptr;
 	UnifiedGeometryMemoryPool* m_unifiedGometryMemoryPool = nullptr;
+	PhysicsWorld* m_physicsWorld = nullptr; ///< For debug drawing.
 };
 
 /// GPU buffers and textures that the clusterer refers to.

+ 2 - 1
AnKi/Renderer/ConfigVars.defs.h

@@ -25,7 +25,8 @@ ANKI_CONFIG_VAR_F32(RVolumetricLightingAccumulationQualityZ, 4.0f, 1.0f, 16.0f,
 ANKI_CONFIG_VAR_U32(RVolumetricLightingAccumulationFinalZSplit, 26, 1, 256,
 					"Final cluster split that will recieve volumetric lights")
 
-ANKI_CONFIG_VAR_BOOL(RDbgEnabled, false, "Enable or not debugging")
+ANKI_CONFIG_VAR_BOOL(RDbg, false, "Enable or not debug visualization")
+ANKI_CONFIG_VAR_BOOL(RDbgPhysics, false, "Enable or not physics debug visualization")
 
 // VRS
 ANKI_CONFIG_VAR_BOOL(RVrs, true, "Enable VRS in multiple passes")

+ 10 - 2
AnKi/Renderer/Dbg.cpp

@@ -14,6 +14,7 @@
 #include <AnKi/Util/Enum.h>
 #include <AnKi/Core/ConfigSet.h>
 #include <AnKi/Collision/ConvexHullShape.h>
+#include <AnKi/Physics/PhysicsWorld.h>
 
 namespace anki {
 
@@ -56,7 +57,7 @@ Error Dbg::init()
 
 void Dbg::run(RenderPassWorkContext& rgraphCtx, const RenderingContext& ctx)
 {
-	ANKI_ASSERT(getExternalSubsystems().m_config->getRDbgEnabled());
+	ANKI_ASSERT(getExternalSubsystems().m_config->getRDbg());
 
 	CommandBufferPtr& cmdb = rgraphCtx.m_commandBuffer;
 
@@ -228,13 +229,20 @@ void Dbg::run(RenderPassWorkContext& rgraphCtx, const RenderingContext& ctx)
 		}
 	}
 
+	if(threadId == (threadCount - 1) && getExternalSubsystems().m_config->getRDbgPhysics())
+	{
+		m_physicsDrawer.start(ctx.m_matrices.m_viewProjection, cmdb, &rebar);
+		m_physicsDrawer.drawWorld(*getExternalSubsystems().m_physicsWorld);
+		m_physicsDrawer.end();
+	}
+
 	// Restore state
 	cmdb->setDepthCompareOperation(CompareOperation::kLess);
 }
 
 void Dbg::populateRenderGraph(RenderingContext& ctx)
 {
-	if(!getExternalSubsystems().m_config->getRDbgEnabled())
+	if(!getExternalSubsystems().m_config->getRDbg())
 	{
 		return;
 	}

+ 1 - 0
AnKi/Renderer/Dbg.h

@@ -69,6 +69,7 @@ private:
 	FramebufferDescription m_fbDescr;
 
 	DebugDrawer2 m_drawer;
+	PhysicsDebugDrawer m_physicsDrawer{&m_drawer};
 
 	ImageResourcePtr m_giProbeImage;
 	ImageResourcePtr m_pointLightImage;

+ 2 - 2
AnKi/Renderer/FinalComposite.cpp

@@ -102,7 +102,7 @@ void FinalComposite::populateRenderGraph(RenderingContext& ctx)
 
 	pass.newTextureDependency(ctx.m_outRenderTarget, TextureUsageBit::kFramebufferWrite);
 
-	if(getExternalSubsystems().m_config->getRDbgEnabled())
+	if(getExternalSubsystems().m_config->getRDbg())
 	{
 		pass.newTextureDependency(m_r->getDbg().getRt(), TextureUsageBit::kSampledFragment);
 	}
@@ -130,7 +130,7 @@ void FinalComposite::populateRenderGraph(RenderingContext& ctx)
 void FinalComposite::run(RenderingContext& ctx, RenderPassWorkContext& rgraphCtx)
 {
 	CommandBufferPtr& cmdb = rgraphCtx.m_commandBuffer;
-	const Bool dbgEnabled = getExternalSubsystems().m_config->getRDbgEnabled();
+	const Bool dbgEnabled = getExternalSubsystems().m_config->getRDbg();
 
 	Array<RenderTargetHandle, kMaxDebugRenderTargets> dbgRts;
 	ShaderProgramPtr optionalDebugProgram;

+ 58 - 23
AnKi/Scene/Components/BodyComponent.cpp

@@ -4,11 +4,13 @@
 // http://www.anki3d.org/LICENSE
 
 #include <AnKi/Scene/Components/BodyComponent.h>
+#include <AnKi/Scene/Components/ModelComponent.h>
 #include <AnKi/Scene/SceneNode.h>
 #include <AnKi/Scene/SceneGraph.h>
 #include <AnKi/Resource/CpuMeshResource.h>
 #include <AnKi/Resource/ResourceManager.h>
 #include <AnKi/Physics/PhysicsWorld.h>
+#include <AnKi/Resource/ModelResource.h>
 
 namespace anki {
 
@@ -49,6 +51,21 @@ void BodyComponent::loadMeshResource(CString meshFilename)
 	m_dirty = true;
 }
 
+void BodyComponent::setMeshFromModelComponent(U32 patchIndex)
+{
+	if(!ANKI_SCENE_ASSERT(m_modelc))
+	{
+		return;
+	}
+
+	if(!ANKI_SCENE_ASSERT(patchIndex < m_modelc->getModelResource()->getModelPatches().getSize()))
+	{
+		return;
+	}
+
+	loadMeshResource(m_modelc->getModelResource()->getModelPatches()[patchIndex].getMesh()->getFilename());
+}
+
 CString BodyComponent::getMeshResourceFilename() const
 {
 	return (m_mesh.isCreated()) ? m_mesh->getFilename() : CString();
@@ -56,36 +73,37 @@ CString BodyComponent::getMeshResourceFilename() const
 
 void BodyComponent::setMass(F32 mass)
 {
-	if(!ANKI_SCENE_ASSERT(mass >= 0.0f))
+	if(!ANKI_SCENE_ASSERT(mass >= 0.0f && m_body.isCreated()))
 	{
-		mass = 0.0f;
+		return;
 	}
 
-	if(m_body.isCreated())
+	if((m_body->getMass() == 0.0f && mass != 0.0f) || (m_body->getMass() != 0.0f && mass == 0.0f))
 	{
-		if((m_body->getMass() == 0.0f && mass != 0.0f) || (m_body->getMass() != 0.0f && mass == 0.0f))
-		{
-			// Will become from static to dynamic or the opposite, re-create the body
-
-			const Transform& prevTransform = m_body->getTransform();
-			PhysicsBodyInitInfo init;
-			init.m_transform = prevTransform;
-			init.m_mass = mass;
-			init.m_shape = m_mesh->getCollisionShape();
-			m_body = getExternalSubsystems(*m_node).m_physicsWorld->newInstance<PhysicsBody>(init);
-			m_body->setUserData(this);
-			m_body->setTransform(m_node->getWorldTransform());
-
-			m_dirty = true;
-		}
-		else
-		{
-			m_body->setMass(mass);
-		}
+		// Will become from static to dynamic or the opposite, re-create the body
+
+		const Transform& prevTransform = m_body->getTransform();
+		PhysicsBodyInitInfo init;
+		init.m_transform = prevTransform;
+		init.m_mass = mass;
+		init.m_shape = m_mesh->getCollisionShape();
+		m_body = getExternalSubsystems(*m_node).m_physicsWorld->newInstance<PhysicsBody>(init);
+		m_body->setUserData(this);
+
+		m_dirty = true;
 	}
 	else
 	{
-		ANKI_SCENE_LOGW("BodyComponent is not initialized. Ignoring setting of mass");
+		m_body->setMass(mass);
+	}
+}
+
+void BodyComponent::teleportTo(const Transform& trf)
+{
+	if(ANKI_SCENE_ASSERT(m_body.isCreated()))
+	{
+		m_body->setTransform(trf);
+		m_node->setLocalTransform(trf); // Set that just to be sure
 	}
 }
 
@@ -103,4 +121,21 @@ Error BodyComponent::update(SceneComponentUpdateInfo& info, Bool& updated)
 	return Error::kNone;
 }
 
+void BodyComponent::onOtherComponentRemovedOrAdded(SceneComponent* other, Bool added)
+{
+	if(other->getClassId() != ModelComponent::getStaticClassId())
+	{
+		return;
+	}
+
+	if(added && m_modelc == nullptr)
+	{
+		m_modelc = static_cast<ModelComponent*>(other);
+	}
+	else if(!added && m_modelc == other)
+	{
+		m_modelc = nullptr;
+	}
+}
+
 } // end namespace anki

+ 6 - 4
AnKi/Scene/Components/BodyComponent.h

@@ -26,6 +26,8 @@ public:
 
 	void loadMeshResource(CString meshFilename);
 
+	void setMeshFromModelComponent(U32 patchIndex = 0);
+
 	CString getMeshResourceFilename() const;
 
 	void setMass(F32 mass);
@@ -45,18 +47,18 @@ public:
 		return m_mesh.isCreated();
 	}
 
-	void teleportTo(const Transform& trf)
-	{
-		m_body->setTransform(trf);
-	}
+	void teleportTo(const Transform& trf);
 
 private:
 	SceneNode* m_node = nullptr;
+	ModelComponent* m_modelc = nullptr;
 	CpuMeshResourcePtr m_mesh;
 	PhysicsBodyPtr m_body;
 	Bool m_dirty = true;
 
 	Error update(SceneComponentUpdateInfo& info, Bool& updated);
+
+	void onOtherComponentRemovedOrAdded(SceneComponent* other, Bool added);
 };
 /// @}
 

+ 2 - 1
AnKi/Scene/Components/ModelComponent.cpp

@@ -197,7 +197,8 @@ Error ModelComponent::update(SceneComponentUpdateInfo& info, Bool& updated)
 		}
 		else
 		{
-			aabbLocal = m_skinComponent->getBoneBoundingVolumeLocalSpace();
+			aabbLocal =
+				m_skinComponent->getBoneBoundingVolumeLocalSpace().getCompoundShape(m_model->getBoundingVolume());
 		}
 
 		const Aabb aabbWorld = aabbLocal.getTransformed(info.m_node->getWorldTransform());

+ 4 - 4
AnKi/Scene/Components/PlayerControllerComponent.cpp

@@ -23,13 +23,13 @@ PlayerControllerComponent::PlayerControllerComponent(SceneNode* node)
 
 Error PlayerControllerComponent::update(SceneComponentUpdateInfo& info, Bool& updated)
 {
-	const Transform newTrf = m_player->getTransform();
-	updated = newTrf != m_trf;
+	const Vec3 newPos = m_player->getTransform().getOrigin().xyz();
+	updated = newPos != m_worldPos;
 
 	if(updated)
 	{
-		m_trf = newTrf;
-		info.m_node->setLocalTransform(newTrf);
+		m_worldPos = newPos;
+		info.m_node->setLocalOrigin(newPos.xyz0());
 	}
 
 	return Error::kNone;

+ 1 - 1
AnKi/Scene/Components/PlayerControllerComponent.h

@@ -38,7 +38,7 @@ public:
 
 private:
 	PhysicsPlayerControllerPtr m_player;
-	Transform m_trf = Transform::getIdentity();
+	Vec3 m_worldPos = Vec3(0.0f);
 
 	Error update([[maybe_unused]] SceneComponentUpdateInfo& info, Bool& updated);
 };

File diff suppressed because it is too large
+ 1116 - 200
AnKi/Script/Scene.cpp


+ 67 - 0
AnKi/Script/Scene.xml

@@ -207,6 +207,7 @@ using WeakArrayBodyComponentPtr = WeakArray<BodyComponent*>;
 						<arg>CString</arg>
 					</args>
 				</method>
+				<method name="setMeshFromModelComponent"></method>
 				<method name="teleportTo">
 					<args>
 						<arg>const Transform&amp;</arg>
@@ -393,6 +394,31 @@ using WeakArrayBodyComponentPtr = WeakArray<BodyComponent*>;
 					</args>
 				</method>
 				<method name="setMarkedForDeletion"></method>
+
+				<method name="setLocalOrigin">
+					<args>
+						<arg>const Vec4&amp;</arg>
+					</args>
+				</method>
+				<method name="getLocalOrigin">
+					<return>const Vec4&amp;</return>
+				</method>
+				<method name="setLocalRotation">
+					<args>
+						<arg>const Mat3x4&amp;</arg>
+					</args>
+				</method>
+				<method name="getLocalRotation">
+					<return>const Mat3x4&amp;</return>
+				</method>
+				<method name="setLocalScale">
+					<args>
+						<arg>F32</arg>
+					</args>
+				</method>
+				<method name="getLocalScale">
+					<return>F32</return>
+				</method>
 				<method name="setLocalTransform">
 					<args>
 						<arg>const Transform&amp;</arg>
@@ -401,6 +427,7 @@ using WeakArrayBodyComponentPtr = WeakArray<BodyComponent*>;
 				<method name="getLocalTransform">
 					<return>const Transform&amp;</return>
 				</method>
+				
 				<method name="newComponent&lt;LightComponent&gt;" alias="newLightComponent">
 					<return>LightComponent*</return>
 				</method>
@@ -440,6 +467,46 @@ using WeakArrayBodyComponentPtr = WeakArray<BodyComponent*>;
 				<method name="newComponent&lt;SkyboxComponent&gt;" alias="newSkyboxComponent">
 					<return>SkyboxComponent*</return>
 				</method>
+
+				<method name="getFirstComponentOfType&lt;LightComponent&gt;" alias="getFirstLightComponent">
+					<return>LightComponent&amp;</return>
+				</method>
+				<method name="getFirstComponentOfType&lt;LensFlareComponent&gt;" alias="getFirstLensFlareComponent">
+					<return>LensFlareComponent&amp;</return>
+				</method>
+				<method name="getFirstComponentOfType&lt;DecalComponent&gt;" alias="getFirstDecalComponent">
+					<return>DecalComponent&amp;</return>
+				</method>
+				<method name="getFirstComponentOfType&lt;TriggerComponent&gt;" alias="getFirstTriggerComponent">
+					<return>TriggerComponent&amp;</return>
+				</method>
+				<method name="getFirstComponentOfType&lt;FogDensityComponent&gt;" alias="getFirstFogDensityComponent">
+					<return>FogDensityComponent&amp;</return>
+				</method>
+				<method name="getFirstComponentOfType&lt;CameraComponent&gt;" alias="getFirstCameraComponent">
+					<return>CameraComponent&amp;</return>
+				</method>
+				<method name="getFirstComponentOfType&lt;GlobalIlluminationProbeComponent&gt;" alias="getFirstGlobalIlluminationProbeComponent">
+					<return>GlobalIlluminationProbeComponent&amp;</return>
+				</method>
+				<method name="getFirstComponentOfType&lt;ReflectionProbeComponent&gt;" alias="getFirstReflectionProbeComponent">
+					<return>ReflectionProbeComponent&amp;</return>
+				</method>
+				<method name="getFirstComponentOfType&lt;BodyComponent&gt;" alias="getFirstBodyComponent">
+					<return>BodyComponent&amp;</return>
+				</method>
+				<method name="getFirstComponentOfType&lt;ParticleEmitterComponent&gt;" alias="getFirstParticleEmitterComponent">
+					<return>ParticleEmitterComponent&amp;</return>
+				</method>
+				<method name="getFirstComponentOfType&lt;ModelComponent&gt;" alias="getFirstModelComponent">
+					<return>ModelComponent&amp;</return>
+				</method>
+				<method name="getFirstComponentOfType&lt;SkinComponent&gt;" alias="getFirstSkinComponent">
+					<return>SkinComponent&amp;</return>
+				</method>
+				<method name="getFirstComponentOfType&lt;SkyboxComponent&gt;" alias="getFirstSkyboxComponent">
+					<return>SkyboxComponent&amp;</return>
+				</method>
 			</methods>
 		</class>
 		<class name="SceneGraph">

+ 3 - 3
Samples/Common/SampleApp.cpp

@@ -154,17 +154,17 @@ Error SampleApp::userMainLoop(Bool& quit, Second elapsedTime)
 		mode = (mode + 1) % 3;
 		if(mode == 0)
 		{
-			getConfig().setRDbgEnabled(false);
+			getConfig().setRDbg(false);
 		}
 		else if(mode == 1)
 		{
-			getConfig().setRDbgEnabled(true);
+			getConfig().setRDbg(true);
 			renderer.getDbg().setDepthTestEnabled(true);
 			renderer.getDbg().setDitheredDepthTestEnabled(false);
 		}
 		else
 		{
-			getConfig().setRDbgEnabled(true);
+			getConfig().setRDbg(true);
 			renderer.getDbg().setDepthTestEnabled(false);
 			renderer.getDbg().setDitheredDepthTestEnabled(true);
 		}

BIN
Samples/PhysicsPlayground/Assets/Icosphere_834d64c142beaa13.ankimesh


File diff suppressed because it is too large
+ 294 - 350
Samples/PhysicsPlayground/Assets/Scene.lua


BIN
Samples/PhysicsPlayground/Assets/Suzanne_e3526e1428c0763c.ankimesh


BIN
Samples/PhysicsPlayground/Assets/floor_71cbd2644e53ab8c.ankimesh


BIN
Samples/PhysicsPlayground/Assets/wall_87565b500719f7c4.ankimesh


+ 70 - 11
Samples/PhysicsPlayground/Main.cpp

@@ -38,15 +38,15 @@ radius = 3.5
 function update(event, prevTime, crntTime)
 	node = event:getAssociatedSceneNodes():getAt(0)
 	-- logi(string.format("Will fade fog for %s", node:getName()))
-	fogComponent = node:getFogDensityComponent()
+	fogComponent = node:getFirstFogDensityComponent()
 
 	dt = crntTime - prevTime
 	density = density - 4.0 * dt
 	radius = radius + 0.5 * dt
 
-	pos = node:getMoveComponent():getLocalOrigin()
+	pos = node:getLocalOrigin()
 	pos:setY(pos:getY() - 1.1 * dt)
-	node:getMoveComponent():setLocalOrigin(pos)
+	node:setLocalOrigin(pos)
 
 	if density <= 0.0 or radius <= 0.0 then
 		event:getAssociatedSceneNodes():getAt(0):setMarkedForDeletion()
@@ -116,7 +116,7 @@ Error MyApp::sampleExtraInit()
 	if(1)
 	{
 		SceneNode& cam = getSceneGraph().getActiveCameraNode();
-		cam.setLocalTransform(Transform(Vec4(0.0, 0.0, 5.0, 0.0), Mat3x4::getIdentity(), 1.0));
+		cam.setLocalTransform(Transform(Vec4(0.0, 2.0, 5.0, 0.0), Mat3x4::getIdentity(), 1.0));
 
 		SceneNode* player;
 		ANKI_CHECK(getSceneGraph().newSceneNode("player", player));
@@ -163,6 +163,7 @@ Error MyApp::sampleExtraInit()
 			// monkey->getFirstComponentOfType<MoveComponent>().setLocalTransform(trf);
 
 			BodyComponent* bodyc = monkey->newComponent<BodyComponent>();
+			bodyc->setMeshFromModelComponent();
 			bodyc->teleportTo(trf);
 			bodyc->setMass(1.0f);
 
@@ -253,26 +254,84 @@ Error MyApp::userMainLoop(Bool& quit, [[maybe_unused]] Second elapsedTime)
 		mode = (mode + 1) % 3;
 		if(mode == 0)
 		{
-			getConfig().setRDbgEnabled(false);
+			getConfig().setRDbg(false);
 		}
 		else if(mode == 1)
 		{
-			getConfig().setRDbgEnabled(true);
+			getConfig().setRDbg(true);
 			getMainRenderer().getDbg().setDepthTestEnabled(true);
 			getMainRenderer().getDbg().setDitheredDepthTestEnabled(false);
 		}
 		else
 		{
-			getConfig().setRDbgEnabled(true);
+			getConfig().setRDbg(true);
 			getMainRenderer().getDbg().setDepthTestEnabled(false);
 			getMainRenderer().getDbg().setDitheredDepthTestEnabled(true);
 		}
 	}
 
-	if(getInput().getKey(KeyCode::kR))
+	// Move player
 	{
 		SceneNode& player = getSceneGraph().findSceneNode("player");
-		player.getFirstComponentOfType<PlayerControllerComponent>().moveToPosition(Vec3(0.0f, 2.0f, 0.0f));
+		PlayerControllerComponent& playerc = player.getFirstComponentOfType<PlayerControllerComponent>();
+
+		if(getInput().getKey(KeyCode::kR))
+		{
+			player.getFirstComponentOfType<PlayerControllerComponent>().moveToPosition(Vec3(0.0f, 2.0f, 0.0f));
+		}
+
+		constexpr F32 ang = toRad(7.0f);
+
+		F32 y = getInput().getMousePosition().y();
+		F32 x = getInput().getMousePosition().x();
+		if(y != 0.0 || x != 0.0)
+		{
+			// Set origin
+			Vec4 origin = player.getWorldTransform().getOrigin();
+			// origin.y() += 1.9f;
+
+			// Set rotation
+			Mat3x4 rot(Vec3(0.0f), Euler(ang * y * 11.25f, ang * x * -20.0f, 0.0f));
+
+			rot = player.getLocalRotation().combineTransformations(rot);
+
+			Vec3 newz = rot.getColumn(2).getNormalized();
+			Vec3 newx = Vec3(0.0, 1.0, 0.0).cross(newz);
+			Vec3 newy = newz.cross(newx);
+			rot.setColumns(newx, newy, newz, Vec3(0.0));
+			rot.reorthogonalize();
+
+			// Update move
+			player.setLocalTransform(Transform(origin, rot, 1.0));
+		}
+
+		const F32 speed = 0.5;
+		Vec4 moveVec(0.0);
+		if(getInput().getKey(KeyCode::kW))
+		{
+			moveVec.z() += 1.0f;
+		}
+
+		if(getInput().getKey(KeyCode::kA))
+		{
+			moveVec.x() -= 1.0f;
+		}
+
+		if(getInput().getKey(KeyCode::kS))
+		{
+			moveVec.z() -= 1.0f;
+		}
+
+		if(getInput().getKey(KeyCode::kD))
+		{
+			moveVec.x() += 1.0f;
+		}
+
+		Vec4 dir = -player.getLocalRotation().getZAxis().xyz0();
+		dir.y() = 0.0f;
+		dir.normalize();
+
+		playerc.setVelocity(moveVec.z() * speed, moveVec.x() * speed, 0.0, dir);
 	}
 
 	if(getInput().getMouseButton(MouseButton::kLeft) == 1)
@@ -285,13 +344,13 @@ Error MyApp::userMainLoop(Bool& quit, [[maybe_unused]] Second elapsedTime)
 
 		SceneNode* monkey;
 		ANKI_CHECK(getSceneGraph().newSceneNode(
-			StringRaii(&getMemoryPool()).sprintf("monkey%u", instance++).toCString(), monkey));
+			StringRaii(&getMemoryPool()).sprintf("FireMonkey%u", instance++).toCString(), monkey));
 		ModelComponent* modelc = monkey->newComponent<ModelComponent>();
 		modelc->loadModelResource("Assets/Suzanne_dynamic_36043dae41fe12d5.ankimdl");
 		// monkey->getFirstComponentOfType<MoveComponent>().setLocalTransform(camTrf);
 
 		BodyComponent* bodyc = monkey->newComponent<BodyComponent>();
-		bodyc->loadMeshResource("Assets/Suzanne_e3526e1428c0763c.ankimesh");
+		bodyc->setMeshFromModelComponent();
 		bodyc->teleportTo(camTrf);
 		bodyc->setMass(1.0f);
 

+ 6 - 6
Sandbox/Main.cpp

@@ -125,17 +125,17 @@ Error MyApp::userMainLoop(Bool& quit, Second elapsedTime)
 		mode = (mode + 1) % 3;
 		if(mode == 0)
 		{
-			getConfig().setRDbgEnabled(false);
+			getConfig().setRDbg(false);
 		}
 		else if(mode == 1)
 		{
-			getConfig().setRDbgEnabled(true);
+			getConfig().setRDbg(true);
 			renderer.getDbg().setDepthTestEnabled(true);
 			renderer.getDbg().setDitheredDepthTestEnabled(false);
 		}
 		else
 		{
-			getConfig().setRDbgEnabled(true);
+			getConfig().setRDbg(true);
 			renderer.getDbg().setDepthTestEnabled(false);
 			renderer.getDbg().setDitheredDepthTestEnabled(true);
 		}
@@ -188,17 +188,17 @@ Error MyApp::userMainLoop(Bool& quit, Second elapsedTime)
 			mode = (mode + 1) % 3;
 			if(mode == 0)
 			{
-				getConfig().setRDbgEnabled(false);
+				getConfig().setRDbg(false);
 			}
 			else if(mode == 1)
 			{
-				getConfig().setRDbgEnabled(true);
+				getConfig().setRDbg(true);
 				renderer.getDbg().setDepthTestEnabled(true);
 				renderer.getDbg().setDitheredDepthTestEnabled(false);
 			}
 			else
 			{
-				getConfig().setRDbgEnabled(true);
+				getConfig().setRDbg(true);
 				renderer.getDbg().setDepthTestEnabled(false);
 				renderer.getDbg().setDitheredDepthTestEnabled(true);
 			}

Some files were not shown because too many files changed in this diff