Browse Source

Physics work

Panagiotis Christopoulos Charitos 11 years ago
parent
commit
e25c4cdb0f

+ 1 - 0
include/anki/Scene.h

@@ -8,6 +8,7 @@
 
 
 #include "anki/scene/SceneGraph.h"
 #include "anki/scene/SceneGraph.h"
 #include "anki/scene/LensFlareComponent.h"
 #include "anki/scene/LensFlareComponent.h"
+#include "anki/scene/BodyComponent.h"
 #include "anki/scene/ModelNode.h"
 #include "anki/scene/ModelNode.h"
 #include "anki/scene/SkinNode.h"
 #include "anki/scene/SkinNode.h"
 #include "anki/scene/StaticGeometryNode.h"
 #include "anki/scene/StaticGeometryNode.h"

+ 2 - 0
include/anki/physics/PhysicsBody.h

@@ -42,6 +42,8 @@ public:
 		return m_trf;
 		return m_trf;
 	}
 	}
 
 
+	void setTransform(const Transform& trf);
+
 private:
 private:
 	NewtonBody* m_body = nullptr;
 	NewtonBody* m_body = nullptr;
 	Transform m_trf = Transform::getIdentity();
 	Transform m_trf = Transform::getIdentity();

+ 5 - 3
include/anki/physics/PhysicsCollisionShape.h

@@ -22,7 +22,8 @@ public:
 	{
 	{
 		NONE,
 		NONE,
 		SPHERE,
 		SPHERE,
-		BOX
+		BOX,
+		STATIC_TRIANGLE_SOUP
 	};
 	};
 
 
 	/// Standard initializer for all collision shapes.
 	/// Standard initializer for all collision shapes.
@@ -105,8 +106,9 @@ public:
 	~PhysicsTriangleSoup()
 	~PhysicsTriangleSoup()
 	{}
 	{}
 
 
-	ANKI_USE_RESULT Error createStaticTriangleSoup(Initializer& init,
-		const Vec3* positions, U32 positionsStride, U16* indices);
+	ANKI_USE_RESULT Error create(Initializer& init,
+		const Vec3* positions, U32 positionsStride, 
+		const U16* indices, U32 indicesCount);
 };
 };
 /// @}
 /// @}
 
 

+ 15 - 0
include/anki/physics/PhysicsDrawer.h

@@ -39,10 +39,25 @@ public:
 		return m_drawAabbs;
 		return m_drawAabbs;
 	}
 	}
 
 
+	void setDrawCollision(Bool draw)
+	{
+		m_drawCollision = draw;
+	}
+
+	Bool getDrawCollision() const
+	{
+		return m_drawCollision;
+	}
+
 private:
 private:
 	Bool8 m_drawAabbs = true;
 	Bool8 m_drawAabbs = true;
+	Bool8 m_drawCollision = true;
 
 
 	void drawAabb(const NewtonBody* body);
 	void drawAabb(const NewtonBody* body);
+	void drawCollision(const NewtonBody* body);
+
+	static void drawGeometryCallback(void* userData, 
+		int vertexCount, const dFloat* const faceVertec, int id);
 };
 };
 /// @}
 /// @}
 
 

+ 1 - 0
include/anki/resource/Mesh.h

@@ -28,6 +28,7 @@ enum class VertexAttribute: U8
 	INDICES,
 	INDICES,
 	COUNT
 	COUNT
 };
 };
+ANKI_ENUM_ALLOW_NUMERIC_OPERATIONS(VertexAttribute, inline)
 
 
 /// Mesh Resource. It contains the geometry packed in VBOs
 /// Mesh Resource. It contains the geometry packed in VBOs
 class Mesh
 class Mesh

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

@@ -31,6 +31,11 @@ public:
 		return m_trf;
 		return m_trf;
 	}
 	}
 
 
+	void setTransform(const Transform& trf)
+	{
+		m_body->setTransform(trf);
+	}
+
 	/// @name SceneComponent overrides
 	/// @name SceneComponent overrides
 	/// @{
 	/// @{
 	ANKI_USE_RESULT Error update(SceneNode&, F32, F32, Bool& updated) override
 	ANKI_USE_RESULT Error update(SceneNode&, F32, F32, Bool& updated) override

+ 10 - 0
src/physics/PhysicsBody.cpp

@@ -28,6 +28,8 @@ Error PhysicsBody::create(const Initializer& init)
 {
 {
 	ANKI_ASSERT(init.m_shape);
 	ANKI_ASSERT(init.m_shape);
 
 
+	//I collisionType = NewtonCollisionGetType(init.m_shape->_getNewtonShape());
+
 	// Create
 	// Create
 	Mat4 trf = Mat4(init.m_startTrf);
 	Mat4 trf = Mat4(init.m_startTrf);
 	trf.transpose();
 	trf.transpose();
@@ -67,6 +69,14 @@ Error PhysicsBody::create(const Initializer& init)
 	return ErrorCode::NONE;
 	return ErrorCode::NONE;
 }
 }
 
 
+//==============================================================================
+void PhysicsBody::setTransform(const Transform& trf)
+{
+	Mat4 mat(trf);
+	mat.transpose();
+	NewtonBodySetMatrix(m_body, &mat(0, 0));
+}
+
 //==============================================================================
 //==============================================================================
 void PhysicsBody::onTransform(
 void PhysicsBody::onTransform(
 	const NewtonBody* const body, 
 	const NewtonBody* const body, 

+ 42 - 0
src/physics/PhysicsCollisionShape.cpp

@@ -65,5 +65,47 @@ Error PhysicsBox::create(Initializer& init, const Vec3& extend)
 	return err;
 	return err;
 }
 }
 
 
+//==============================================================================
+// PhysicsTriangleSoup                                                         =
+//==============================================================================
+
+//==============================================================================
+Error PhysicsTriangleSoup::create(Initializer& init,
+	const Vec3* positions, U32 positionsStride, 
+	const U16* indices, U32 indicesCount)
+{
+	m_shape = NewtonCreateTreeCollision(m_world->_getNewtonWorld(), 0);
+	if(!m_shape)
+	{
+		ANKI_LOGE("NewtonCreateBox() failed");
+		return ErrorCode::FUNCTION_FAILED;
+	}
+
+	NewtonTreeCollisionBeginBuild(m_shape);
+
+	// Iterate index array
+	const U16* indicesEnd = indices + indicesCount;
+	for(; indices != indicesEnd; indices += 3)
+	{
+		Array<Vec3, 3> facePos;
+
+		for(U i = 0; i < 3; ++i)
+		{
+			U idx = indices[i];
+			const U8* ptr = 
+				reinterpret_cast<const U8*>(positions) + positionsStride * idx;
+
+			facePos[i] = *reinterpret_cast<const Vec3*>(ptr);
+		}
+
+		NewtonTreeCollisionAddFace(m_shape, 3, &facePos[0][0], sizeof(Vec3), 0);
+	}
+
+	const I optimize = 1;
+	NewtonTreeCollisionEndBuild(m_shape, optimize);
+
+	return ErrorCode::NONE;
+}
+
 } // end namespace anki
 } // end namespace anki
 
 

+ 65 - 0
src/physics/PhysicsDrawer.cpp

@@ -8,6 +8,13 @@
 
 
 namespace anki {
 namespace anki {
 
 
+//==============================================================================
+struct CallbackData
+{
+	const NewtonBody* m_body;
+	PhysicsDrawer* m_drawer;
+};
+
 //==============================================================================
 //==============================================================================
 void PhysicsDrawer::drawWorld(const PhysicsWorld& world)
 void PhysicsDrawer::drawWorld(const PhysicsWorld& world)
 {
 {
@@ -20,6 +27,11 @@ void PhysicsDrawer::drawWorld(const PhysicsWorld& world)
 		{
 		{
 			drawAabb(body);
 			drawAabb(body);
 		}
 		}
+
+		if(m_drawCollision)
+		{
+			drawCollision(body);
+		}
 	}
 	}
 }
 }
 
 
@@ -64,5 +76,58 @@ void PhysicsDrawer::drawAabb(const NewtonBody* body)
 	drawLines(lines, linesCount, Vec4(0.0, 0.0, 1.0, 0.5));
 	drawLines(lines, linesCount, Vec4(0.0, 0.0, 1.0, 0.5));
 }
 }
 
 
+//==============================================================================
+void PhysicsDrawer::drawCollision(const NewtonBody* body)
+{
+	Mat4 matrix;
+	NewtonBodyGetMatrix(body, &matrix[0]);
+
+	CallbackData data;
+	data.m_body = body;
+	data.m_drawer = this;
+
+	NewtonCollisionForEachPolygonDo(NewtonBodyGetCollision(body), 
+		&matrix[0], drawGeometryCallback, static_cast<void*>(&data));
+}
+
+//==============================================================================
+void PhysicsDrawer::drawGeometryCallback(void* userData, 
+	int vertexCount, const dFloat* const faceVertec, int id)
+{
+	CallbackData* data = static_cast<CallbackData*>(userData);
+	const NewtonBody* body = data->m_body;
+
+	Vec4 color(1.0);
+	if(NewtonBodyGetType(body) == NEWTON_DYNAMIC_BODY)
+	{
+		I sleepState = NewtonBodyGetSleepState(body);
+		if(sleepState == 1)
+		{
+			// Sleeping
+			color = Vec4(0.3, 0.3, 0.3, 1.0);
+		}
+	}
+
+	U i = vertexCount - 1;
+
+	Array<Vec3, 2> points;
+	points[0] = Vec3(
+		faceVertec[i * 3 + 0], 
+		faceVertec[i * 3 + 1], 
+		faceVertec[i * 3 + 2]);
+
+	for (I i = 0; i < vertexCount; i ++) 
+	{
+		points[1] = Vec3(
+			faceVertec[i * 3 + 0], 
+			faceVertec[i * 3 + 1], 
+			faceVertec[i * 3 + 2]);
+
+		data->m_drawer->drawLines(&points[0], 1, color);
+
+		points[0] = points[1];
+	}
+}
+
 } // end namespace anki
 } // end namespace anki
 
 

+ 1 - 1
src/physics/PhysicsWorld.cpp

@@ -44,7 +44,7 @@ Error PhysicsWorld::create(AllocAlignedCallback allocCb, void* allocCbData)
 	m_alloc = ChainAllocator<U8>(
 	m_alloc = ChainAllocator<U8>(
 		allocCb, allocCbData, 
 		allocCb, allocCbData, 
 		1024 * 10,
 		1024 * 10,
-		1024 * 1024,
+		1024 * 1024 * 10,
 		ChainMemoryPool::ChunkGrowMethod::MULTIPLY,
 		ChainMemoryPool::ChunkGrowMethod::MULTIPLY,
 		2);
 		2);
 	
 	

+ 42 - 25
src/resource/Model.cpp

@@ -6,6 +6,7 @@
 #include "anki/resource/Model.h"
 #include "anki/resource/Model.h"
 #include "anki/resource/Material.h"
 #include "anki/resource/Material.h"
 #include "anki/resource/Mesh.h"
 #include "anki/resource/Mesh.h"
+#include "anki/resource/MeshLoader.h"
 #include "anki/resource/ProgramResource.h"
 #include "anki/resource/ProgramResource.h"
 #include "anki/misc/Xml.h"
 #include "anki/misc/Xml.h"
 #include "anki/util/Logger.h"
 #include "anki/util/Logger.h"
@@ -17,24 +18,6 @@ namespace anki {
 // ModelPatchBase                                                              =
 // ModelPatchBase                                                              =
 //==============================================================================
 //==============================================================================
 
 
-class Attrib
-{
-public:
-	const char* m_name;
-	VertexAttribute m_location;
-};
-
-static const Array<Attrib, static_cast<U>(VertexAttribute::COUNT) - 1> 
-	attribs = {{
-	{"inPosition", VertexAttribute::POSITION},
-	{"inNormal", VertexAttribute::NORMAL},
-	{"inTangent", VertexAttribute::TANGENT},
-	{"inTexCoord", VertexAttribute::TEXTURE_COORD},
-	{"inTexCoord1", VertexAttribute::TEXTURE_COORD_1},
-	{"inBoneIds", VertexAttribute::BONE_IDS},
-	{"inBoneWeights", VertexAttribute::BONE_WEIGHTS}
-}};
-
 //==============================================================================
 //==============================================================================
 ModelPatchBase::~ModelPatchBase()
 ModelPatchBase::~ModelPatchBase()
 {
 {
@@ -57,9 +40,10 @@ Error ModelPatchBase::createVertexDesc(
 	Bool normalized;
 	Bool normalized;
 
 
 	U count = 0;
 	U count = 0;
-	for(const Attrib& attrib : attribs)
+	for(VertexAttribute attrib = VertexAttribute::POSITION;
+		attrib < VertexAttribute::INDICES; ++attrib)
 	{
 	{
-		mesh.getBufferInfo(attrib.m_location, vbo, size, type,
+		mesh.getBufferInfo(attrib, vbo, size, type,
 			stride, offset, normalized);
 			stride, offset, normalized);
 
 
 		if(!vbo.isCreated())
 		if(!vbo.isCreated())
@@ -68,14 +52,14 @@ Error ModelPatchBase::createVertexDesc(
 		}
 		}
 		
 		
 		vbo.bindVertexBuffer(vertexJobs, size, type, normalized, stride,
 		vbo.bindVertexBuffer(vertexJobs, size, type, normalized, stride,
-			offset, static_cast<U>(attrib.m_location));
+			offset, static_cast<U>(attrib));
 
 
 		++count;
 		++count;
 	}
 	}
 
 
 	if(count < 1)
 	if(count < 1)
 	{
 	{
-		ANKI_LOGE("The program doesn't have any attributes");
+		ANKI_LOGE("The mesh doesn't have any attributes");
 		return ErrorCode::USER_DATA;
 		return ErrorCode::USER_DATA;
 	}
 	}
 
 
@@ -340,11 +324,44 @@ Error Model::load(const CString& filename, ResourceInitializer& init)
 		}
 		}
 		else if(type == "box")
 		else if(type == "box")
 		{
 		{
-			ANKI_LOGW("TODO");
+			Vec3 extend;
+			if(err = valEl.getVec3(extend))
+			{
+				return err;
+			}
+			m_physicsShape = physics.newCollisionShape<PhysicsBox>(
+				csInit, extend);
 		}
 		}
-		else if(type == "mesh")
+		else if(type == "staticMesh")
 		{
 		{
-			ANKI_LOGW("TODO");
+			CString filename;
+			if(err = valEl.getText(filename))
+			{
+				return err;
+			}
+	
+			TempResourceString fixedFilename;
+			if(err = init.m_resources.fixResourceFilename(
+				filename, fixedFilename))
+			{
+				return err;
+			}
+
+			MeshLoader loader;
+			if(err = loader.load(init.m_tempAlloc, fixedFilename.toCString()))
+			{
+				fixedFilename.destroy(init.m_tempAlloc);
+				return err;
+			}
+
+			fixedFilename.destroy(init.m_tempAlloc);
+
+			m_physicsShape = physics.newCollisionShape<PhysicsTriangleSoup>(
+				csInit, 
+				reinterpret_cast<const Vec3*>(loader.getVertexData()), 
+				loader.getVertexSize(),
+				reinterpret_cast<const U16*>(loader.getIndexData()),
+				loader.getHeader().m_totalIndicesCount);
 		}
 		}
 		else
 		else
 		{
 		{

+ 21 - 11
testapp/Main.cpp

@@ -224,8 +224,15 @@ Error init()
 	err = scene.newSceneNode<ModelNode>("horse", horse, 
 	err = scene.newSceneNode<ModelNode>("horse", horse, 
 		"models/crate0/crate0.ankimdl");
 		"models/crate0/crate0.ankimdl");
 	if(err) return err;
 	if(err) return err;
-	horse->getComponent<MoveComponent>().setLocalTransform(
-		Transform(Vec4(-2, 0, 0, 0.0), Mat3x4::getIdentity(), 0.7));
+	//horse->getComponent<MoveComponent>().setLocalTransform(
+	//	Transform(Vec4(-2, 0, 0, 0.0), Mat3x4::getIdentity(), 0.7));
+
+	BodyComponent* bodyc = horse->tryGetComponent<BodyComponent>();
+	if(bodyc)
+	{
+		bodyc->setTransform(
+			Transform(Vec4(10, 10, 4, 0), Mat3x4::getIdentity(), 1.0));
+	}
 #endif
 #endif
 
 
 	if(0)
 	if(0)
@@ -242,7 +249,7 @@ Error init()
 		move->setLocalOrigin(Vec4(0.0, 1.4, 0.6, 0.0));
 		move->setLocalOrigin(Vec4(0.0, 1.4, 0.6, 0.0));
 	}
 	}
 
 
-#if 0
+#if 1
 	{
 	{
 		ScriptResourcePointer script;
 		ScriptResourcePointer script;
 
 
@@ -385,16 +392,19 @@ Error mainLoopExtra(App& app, void*, Bool& quit)
 		mover = &scene.findSceneNode("shape1").getComponent<MoveComponent>();
 		mover = &scene.findSceneNode("shape1").getComponent<MoveComponent>();
 	}
 	}
 
 
-	/*if(in.getKey(KeyCode::L) == 1)
+	if(in.getKey(KeyCode::L) == 1)
 	{
 	{
-		SceneNode& l = 
-			SceneGraphSingleton::get().findSceneNode("crate");
+		SceneNode& l = scene.findSceneNode("horse");
 		
 		
-		Transform trf;
-		trf.setIdentity();
-		trf.getOrigin().y() = 20.0;
-		l.getComponent<MoveComponent>().setLocalTransform(trf);
-	}*/
+		BodyComponent* bodyc = l.tryGetComponent<BodyComponent>();
+		if(bodyc)
+		{
+			Vec4 pos(randRange(0, 10), 10, randRange(-4, 4), 0);
+
+			bodyc->setTransform(
+				Transform(pos, Mat3x4::getIdentity(), 1.0));
+		}
+	}
 
 
 	if(in.getKey(KeyCode::F1) == 1)
 	if(in.getKey(KeyCode::F1) == 1)
 	{
 	{

+ 2 - 0
tools/scene/Exporter.cpp

@@ -835,6 +835,8 @@ void Exporter::load()
 {
 {
 	LOGI("Loading file %s", &m_inputFilename[0]);
 	LOGI("Loading file %s", &m_inputFilename[0]);
 
 
+	//Assimp::DefaultLogger::create("", Logger::VERBOSE);
+
 	m_importer.SetPropertyFloat(AI_CONFIG_PP_CT_MAX_SMOOTHING_ANGLE, 170);
 	m_importer.SetPropertyFloat(AI_CONFIG_PP_CT_MAX_SMOOTHING_ANGLE, 170);
 
 
 	const aiScene* scene = m_importer.ReadFile(m_inputFilename, 0
 	const aiScene* scene = m_importer.ReadFile(m_inputFilename, 0

+ 4 - 2
tools/scene/ExporterMesh.cpp

@@ -219,7 +219,7 @@ void Exporter::exportMesh(
 	{
 	{
 		ERROR("Missing attribute");
 		ERROR("Missing attribute");
 	}
 	}
-	
+
 	// Write header
 	// Write header
 	static const char* magic = "ANKIMES2";
 	static const char* magic = "ANKIMES2";
 	memcpy(&header.m_magic, magic, 8);
 	memcpy(&header.m_magic, magic, 8);
@@ -259,7 +259,9 @@ void Exporter::exportMesh(
 		
 		
 		if(face.mNumIndices != 3)
 		if(face.mNumIndices != 3)
 		{
 		{
-			ERROR("For some reason the assimp didn't triangulate");
+			ERROR("For some reason the assimp returned wrong number of verts "
+				"for a face (face.mNumIndices=%d). Probably degenerates in "
+				"input file", face.mNumIndices);
 		}
 		}
 
 
 		for(unsigned j = 0; j < 3; j++)
 		for(unsigned j = 0; j < 3; j++)