i posted this topic also in the bullet 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;
}