Update BulletMeshbody and add it to Irrlicht

Post Reply
Mishaaa
Posts: 1
Joined: Sat Oct 03, 2015 10:02 am

Update BulletMeshbody and add it to Irrlicht

Post by Mishaaa »

Hi,

i posted this topic also in the Irrlicht forum, but maybe someone can help me here as well. What i am trying to do is load a .obj file, create a BulletMeshbody and add this Meshbody to Irrlicht. So far so good, all of this works. Now i want to manually add (for the beginning) one triangle to the (already loaded) btTriangleMesh. I can add the triangle, i can create the new BulletMeshbody but now i don't know how to load the new BulletMeshbody to Irrlicht, since the function getMesh() only loads filepaths. See my code below, i created a new project only for trying that out thats why there is no classes etc, thanks for helping.

Code: Select all

#include <iostream>
#include <string>
#include "btBulletDynamicsCommon.h"
#include "irrlicht.h"
#include "BulletCollision/Gimpact/btGImpactCollisionAlgorithm.h"
#include "btGImpactShape.h"
#include <Windows.h>

using namespace std;
using namespace irr;
using namespace core;
using namespace scene;
using namespace video;
using namespace io;
using namespace gui;

btRigidBody* CreateBulletBox(btVector3 &TPosition, btVector3 &TScale, btScalar TMass, btDiscreteDynamicsWorld *World);
scene::ISceneNode* IrrlichtCubeBody(btRigidBody* RigidBody, core::vector3df &TScale, scene::ISceneManager *irrScene, video::IVideoDriver *irrDriver);
void RunSimulation(u32 DeltaTime, u32 TimeStamp);
void CreateKinematicPart();
void createBulletMeshbody(btDiscreteDynamicsWorld *World, scene::ISceneManager* irrScene, IrrlichtDevice *irrDev);
btTriangleMesh* ConvertIrrMeshToBulletTriangleMesh(scene::IMesh* pMesh, const core::vector3df& scaling);
void IrrlichtMeshBody(scene::ISceneManager *irrScene, video::IVideoDriver *irrDriver);
void NewIrrlichtMeshBody(scene::ISceneManager *irrScene, video::IVideoDriver *irrDriver);
void UpdateKinematicPart();
void updateBulletMeshbody(btDiscreteDynamicsWorld *World, scene::ISceneManager* irrScene, IrrlichtDevice *irrDev);

//Definitions
static btDiscreteDynamicsWorld *World;
static IrrlichtDevice *irrDevice;
static IVideoDriver *irrDriver;
static ISceneManager *irrScene;
static IGUIEnvironment *irrGUI;
static ITimer *irrTimer;
btRigidBody *StatBody;
ISceneNode* StatNode;
btRigidBody *KinBody;
ISceneNode* KinNode;
btTriangleMesh* TrimeshData;
btTriangleMesh* NewTrimeshData;
btCollisionShape* KinMeshShape;
btCollisionShape* NewKinMeshShape;
btRigidBody *MovingRigidMeshBody;
btRigidBody *NewMovingRigidMeshBody;
btScalar friction;
btScalar restitution;
scene::ISceneNode* BodyNode;
scene::ISceneNode* NewBodyNode;
btTransform startTrans;
btVector3 startposition = { 15, 15, 0 };
btDefaultMotionState *MotionState = new btDefaultMotionState(startTrans);
btTransform temp_trans;
btVector3 act_position;

int main()
{

	//Init Bullet
	btDefaultCollisionConfiguration *CollisionConfiguration = new btDefaultCollisionConfiguration();
	btBroadphaseInterface *BroadPhase = new btDbvtBroadphase();
	btCollisionDispatcher *Dispatcher = new btCollisionDispatcher(CollisionConfiguration);
	btSequentialImpulseConstraintSolver *Solver = new btSequentialImpulseConstraintSolver;
	btGImpactCollisionAlgorithm::registerAlgorithm(Dispatcher);
	World = new btDiscreteDynamicsWorld(Dispatcher, BroadPhase, Solver, CollisionConfiguration);
	World->setGravity(btVector3(0, -9.81f, 0));

	//Init Irrlicht
	irrDevice = createDevice(video::EDT_OPENGL, dimension2d<u32>(800, 600), 32, false, false, false, 0);
	irrGUI = irrDevice->getGUIEnvironment();
	irrTimer = irrDevice->getTimer();
	irrScene = irrDevice->getSceneManager();
	irrDriver = irrDevice->getVideoDriver();
	irrDevice->getCursorControl()->setVisible(0);

	/** Add camera. */
	ICameraSceneNode *Camera = irrScene->addCameraSceneNodeFPS(0, 100, 10);
	Camera->setPosition(vector3df(5, 5, 5));
	Camera->setTarget(vector3df(0, 0, 0));

	/** Preload textures.*/
	irrDriver->getTexture("C:/Users/Michael/Documents/Masterarbeit/GitLab/VBF_Simulation_v2.0/irrlicht-1.8.1/media/terrain-texture.jpg");

	irrScene->addLightSceneNode(0, core::vector3df(2, 5, -2), SColorf(4, 4, 4, 1));
	irrScene->setAmbientLight(video::SColorf(0.3, 0.3, 0.3, 1));

	CreateKinematicPart();

	cout << "#################################" << endl;
	cout << "###" << "Simulation loop" << "###" << endl;
	cout << "#################################" << endl << endl << endl;
	Sleep(1000);
	u32 TimeStamp = irrTimer->getTime();
	u32 DeltaTime = 0;

	cout << "Number Triangles Before: " << TrimeshData->getNumTriangles() << endl;

	TrimeshData->addTriangle(btVector3(5.f, 5.f, 5.f), btVector3(4.f, 4.f, 4.f), btVector3(3.f, 3.f, 3.f), false);

	NewTrimeshData = TrimeshData;

	cout << "Number Triangles After: " << NewTrimeshData->getNumTriangles() << endl;

	//Comment this out for the regular BulletMeshBody
	UpdateKinematicPart();

	while (true)
	{
		RunSimulation(DeltaTime, TimeStamp);
	}

	return 0;
}

btRigidBody* CreateBulletBox(btVector3 &TPosition, btVector3 &TScale, btScalar TMass, btDiscreteDynamicsWorld *World) {

	// Set the initial position of the object
	btTransform Transform;
	Transform.setIdentity();
	Transform.setOrigin(TPosition);

	btDefaultMotionState *MotionState = new btDefaultMotionState(Transform);

	// Create the shape
	btVector3 HalfExtents(TScale[0] * 0.5f, TScale[1] * 0.5f, TScale[2] * 0.5f);
	btCollisionShape *Shape = new btBoxShape(HalfExtents);
	//std::cout << "Bullet Box: " << *TPosition << std::endl;

	// Add mass
	btVector3 LocalInertia;
	Shape->calculateLocalInertia(TMass, LocalInertia);

	// Create the rigid body object
	btRigidBody *RigidBody = new btRigidBody(TMass, MotionState, Shape, LocalInertia);

	// Set friction and restitution to Bullet Object
	RigidBody->setFriction(0.5);
	RigidBody->setRestitution(0.5);

	// Add it to the world
	World->addRigidBody(RigidBody);

	return RigidBody;
}

scene::ISceneNode* IrrlichtCubeBody(btRigidBody* RigidBody, core::vector3df &TScale, scene::ISceneManager *irrScene, video::IVideoDriver *irrDriver) {

	scene::ISceneNode *Node = irrScene->addCubeSceneNode(1.0f);
	Node->setMaterialFlag(video::EMF_LIGHTING, false);
	Node->setMaterialFlag(video::EMF_NORMALIZE_NORMALS, true);
	Node->setDebugDataVisible((scene::E_DEBUG_SCENE_TYPE) (Node->isDebugDataVisible() ^ scene::EDS_BBOX));
	Node->setScale(TScale);

	Node->setMaterialTexture(0, irrDriver->getTexture("C:/Users/Michael/Documents/Masterarbeit/GitLab/VBF_Simulation_v2.0/irrlicht-1.8.1/media/terrain-texture.jpg"));

	// Store a pointer to the irrlicht node so we can update it later
	RigidBody->setUserPointer((void *)(Node));

	return Node;

}

void RunSimulation(u32 DeltaTime, u32 TimeStamp) {

	DeltaTime = irrTimer->getTime() - TimeStamp;
	TimeStamp = irrTimer->getTime();

	/// Visualization
	irrDriver->beginScene(true, true, SColor(255, 20, 0, 0));
	irrScene->drawAll();
	irrGUI->drawAll();
	irrDriver->endScene();
	irrDevice->run();
	
}

void CreateKinematicPart() {

	createBulletMeshbody(World, irrScene, irrDevice);
	IrrlichtMeshBody(irrScene, irrDriver);
}

void createBulletMeshbody(btDiscreteDynamicsWorld *World, scene::ISceneManager* irrScene, IrrlichtDevice *irrDev) {


	// Set the initial position, scaling and motion state of the object
	startTrans.setIdentity();
	startTrans.setOrigin(startposition);
	
	cout << "Creating new Kinematic MeshBody!" << endl;
	// Read body from meshfile
	TrimeshData = new btTriangleMesh();

	scene::IMesh* IMeshObj = irrScene->getMesh("C:/Users/Michael/Documents/Masterarbeit/GitLab/VBF_Simulation_input/CAD_Daten/1_2x0_8x0_8.obj");
	if (IMeshObj)
	{
		TrimeshData = ConvertIrrMeshToBulletTriangleMesh(IMeshObj, vector3df(1,1,1));
		KinMeshShape = new btBvhTriangleMeshShape(TrimeshData, true);
		KinMeshShape->setLocalScaling(btVector3(1.f, 1.f, 1.f));

		btRigidBody::btRigidBodyConstructionInfo RigidMeshBodyCI(0, MotionState, KinMeshShape, btVector3(0, 0, 0));
		MovingRigidMeshBody = new btRigidBody(RigidMeshBodyCI);

		// Add it to the world (me)
		World->addRigidBody(MovingRigidMeshBody);

		irrScene->getMeshCache()->removeMesh(IMeshObj);

	}
	
	else
	{
		std::cout << std::endl << "Error: Mesh path not found: " << IMeshObj << std::endl;
	}
	
	return;
}

btTriangleMesh* ConvertIrrMeshToBulletTriangleMesh(scene::IMesh* pMesh, const core::vector3df& scaling)
{
	btVector3 vertices[3];
	u32 i, j, k, index, numVertices, numIndices;
	u16* mb_indices;
	btTriangleMesh *pTriMesh = new btTriangleMesh();

	for (i = 0; i<pMesh->getMeshBufferCount(); i++)
	{
		scene::IMeshBuffer* mb = pMesh->getMeshBuffer(i);
		if (mb->getVertexType() == video::EVT_STANDARD)
		{
			video::S3DVertex* mb_vertices = (video::S3DVertex*)mb->getVertices();
			mb_indices = mb->getIndices();
			numVertices = mb->getVertexCount();
			numIndices = mb->getIndexCount();
			for (j = 0; j<numIndices; j += 3)
			{
				for (k = 0; k<3; k++)
				{
					index = mb_indices[j + k];
					vertices[k] = btVector3(mb_vertices[index].Pos.X*scaling.X, mb_vertices[index].Pos.Y*scaling.Y, mb_vertices[index].Pos.Z*scaling.Z);
				}
				pTriMesh->addTriangle(vertices[0], vertices[1], vertices[2]);
			}
		}
		else if (mb->getVertexType() == irr::video::EVT_2TCOORDS)
		{
			video::S3DVertex2TCoords* mb_vertices = (video::S3DVertex2TCoords*)mb->getVertices();
			mb_indices = mb->getIndices();
			numVertices = mb->getVertexCount();
			numIndices = mb->getIndexCount();
			for (j = 0; j<numIndices; j += 3)
			{
				for (k = 0; k<3; k++)
				{
					index = mb_indices[j + k];
					vertices[k] = btVector3(mb_vertices[index].Pos.X*scaling.X, mb_vertices[index].Pos.Y*scaling.Y, mb_vertices[index].Pos.Z*scaling.Z);
				}
				pTriMesh->addTriangle(vertices[0], vertices[1], vertices[2]);
			}
		}
	}
	return pTriMesh;
}

void IrrlichtMeshBody(scene::ISceneManager *irrScene, video::IVideoDriver *irrDriver){

	scene::IAnimatedMesh* IMeshPath = irrScene->getMesh("C:/Users/Michael/Documents/Masterarbeit/GitLab/VBF_Simulation_input/CAD_Daten/1_2x0_8x0_8.obj");

	if (IMeshPath)
	{
		//Irrlicht
		BodyNode = irrScene->addAnimatedMeshSceneNode(IMeshPath);
		if (BodyNode)
		{
			BodyNode->setMaterialFlag(irr::video::EMF_LIGHTING, true);
			BodyNode->setDebugDataVisible((irr::scene::E_DEBUG_SCENE_TYPE) (BodyNode->isDebugDataVisible() ^ irr::scene::EDS_MESH_WIRE_OVERLAY));
			BodyNode->setMaterialTexture(0, irrDriver->getTexture("C:/Users/Michael/Documents/Masterarbeit/GitLab/VBF_Simulation_v2.0/irrlicht-1.8.1/media/rockwall.jpg"));
			BodyNode->setScale(vector3df(1,1,1));
		}
	}
	else
	{
		cout << std::endl << "Error: No Mesh File for visualization" << endl;
	}

	irrScene->getMeshCache()->removeMesh(IMeshPath);
	
	return;

}

void UpdateKinematicPart() {

	updateBulletMeshbody(World, irrScene, irrDevice);
	//What to do here??? Add NewMovingRigidMeshBody to Irrlicht

	return;
}

void updateBulletMeshbody(btDiscreteDynamicsWorld *World, scene::ISceneManager* irrScene, IrrlichtDevice *irrDev) {

	World->removeRigidBody(MovingRigidMeshBody);
	BodyNode->remove();
	
	NewKinMeshShape = new btBvhTriangleMeshShape(NewTrimeshData, true);
	NewKinMeshShape->setLocalScaling(btVector3(1.f, 1.f, 1.f));

	btRigidBody::btRigidBodyConstructionInfo RigidMeshBodyCI(0, MotionState, KinMeshShape, btVector3(0, 0, 0));
	NewMovingRigidMeshBody = new btRigidBody(RigidMeshBodyCI);

	// Add it to the world (me)
	World->addRigidBody(NewMovingRigidMeshBody);

	return;
}
Post Reply