Sorry to bother again, but I'm still having problems and I don't know where to begin.
When compiling this with that line commented, it doesn't check for collisions (Of course, as there is no terrain collision object).
Code: Select all
#pragma comment(lib, "Irrlicht.lib")
#pragma comment(lib, "libbulletdynamics.lib")
#pragma comment(lib, "libbulletcollision.lib")
#pragma comment(lib, "libbulletmath.lib")
#include <irrlicht.h>
#include <btBulletDynamicsCommon.h>
#include <iostream>
using namespace std;
using namespace irr;
using namespace core;
using namespace scene;
using namespace video;
using namespace io;
using namespace gui;
class MyEventReceiver : public IEventReceiver
{
public:
MyEventReceiver(ISceneNode* terrain)
{
Terrain = terrain;
}
bool OnEvent(const SEvent& event)
{
if (event.EventType == EET_KEY_INPUT_EVENT && !event.KeyInput.PressedDown)
{
switch (event.KeyInput.Key)
{
case KEY_KEY_W:
Terrain->setMaterialFlag( EMF_WIREFRAME,
!Terrain->getMaterial(0).Wireframe);
return true;
}
}
return false;
}
private:
ISceneNode* Terrain;
};
void QuaternionToEulerXYZ(const btQuaternion &quat,btVector3 &euler)
{
f32 w=quat.getW(); f32 x=quat.getX(); f32 y=quat.getY(); f32 z=quat.getZ();
double sqw = w*w; double sqx = x*x; double sqy = y*y; double sqz = z*z;
euler.setZ((btScalar)((atan2(2.0 * (x*y + z*w),(sqx - sqy - sqz + sqw)))));
euler.setX((btScalar)((atan2(2.0 * (y*z + x*w),(-sqx - sqy + sqz + sqw)))));
euler.setY((btScalar)((asin(-2.0 * (x*z - y*w)))));
}
vector3df GetPosition(btRigidBody *m_pRigidBody)
{
if (m_pRigidBody == NULL)
return vector3df(0,0,0);
btPoint3 p = m_pRigidBody->getCenterOfMassPosition();
return vector3df(p.getX(), p.getY(), p.getZ());
}
vector3df GetRotation(btRigidBody *m_pRigidBody)
{
if (m_pRigidBody == NULL)
return vector3df(0,0,0);
btVector3 btv;
btQuaternion btq=m_pRigidBody->getOrientation();
QuaternionToEulerXYZ(btq, btv);
vector3df v(btv.getX(), btv.getY(), btv.getZ());
v *= 57.29577951f;
return v;
}
int main()
{
IrrlichtDevice* device = createDevice( EDT_OPENGL,
dimension2d<s32>( 640,
480));
if (device == 0)
return 1;
IVideoDriver* driver = device->getVideoDriver();
ISceneManager* smgr = device->getSceneManager();
IGUIEnvironment* env = device->getGUIEnvironment();
btDefaultCollisionConfiguration* collisionConfiguration = new btDefaultCollisionConfiguration();
btCollisionDispatcher* dispatcher = new btCollisionDispatcher(collisionConfiguration);
btVector3 worldAabbMin(-15000,-15000,-15000);
btVector3 worldAabbMax(15000,15000,15000);
int maxProxies = 1024;
btAxisSweep3* overlappingPairCache = new btAxisSweep3(worldAabbMin,worldAabbMax,maxProxies);
btSequentialImpulseConstraintSolver* solver = new btSequentialImpulseConstraintSolver;
btDiscreteDynamicsWorld* dynamicsWorld = new btDiscreteDynamicsWorld(dispatcher, overlappingPairCache, solver, collisionConfiguration);
dynamicsWorld->setGravity(btVector3(0, -9.81f, 0));
driver->setTextureCreationFlag( ETCF_ALWAYS_32_BIT,
true);
ICameraSceneNode* camera = smgr->addCameraSceneNodeFPS( 0,
100.0f,
1200.f);
camera->setPosition(vector3df( 0,
1000,
0));
camera->setTarget(vector3df( 1500,
0,
1500));
camera->setFarValue(12000.0f);
device->getCursorControl()->setVisible(false);
ITerrainSceneNode* terrain = smgr->addTerrainSceneNode(
".\\heightmap.bmp",
0,
-1,
vector3df( 0.f,
0.f,
0.f),
vector3df( 0.f,
0.f,
0.f),
vector3df( 40.f,
4.4f,
40.f),
SColor ( 255,
255,
255,
255 ),
5,
ETPS_17,
4
);
IMesh *terrainMesh = terrain->getMesh();
IMeshBuffer* mb = terrainMesh->getMeshBuffer(0);
S3DVertex2TCoords* mb_vertices=(S3DVertex2TCoords*)mb->getVertices();
u16* mb_indices = mb->getIndices();
s32 numVertices = mb->getVertexCount();
btVector3 vertices[3];
btTriangleMesh *pTriMesh = new btTriangleMesh();
for(u16 j = 0; j < mb->getIndexCount(); j += 3)
{
for (s16 k = 0; k < 3; k++)
{
s32 index = mb_indices[j+k];
if (index > numVertices)
continue;
vertices[k] = btVector3(mb_vertices[index].Pos.X,mb_vertices[index].Pos.Y,mb_vertices[index].Pos.Z);
}
pTriMesh->addTriangle(vertices[0], vertices[1], vertices[2]);
}
btCollisionShape* terrainShape = new btBvhTriangleMeshShape(pTriMesh, true, false);
btAlignedObjectArray<btCollisionShape*> collisionShapes;
collisionShapes.push_back(terrainShape);
btTransform terrainTransform;
terrainTransform.setIdentity();
terrainTransform.setOrigin(btVector3(0, 0, 0));
{
btScalar mass(0.);
bool isDynamic = (mass != 0.f);
btVector3 localInertia(0, 0, 0);
if (isDynamic)
terrainShape->calculateLocalInertia(mass,localInertia);
btDefaultMotionState* myMotionState = new btDefaultMotionState(terrainTransform);
btRigidBody::btRigidBodyConstructionInfo rbInfo(mass,myMotionState,terrainShape,localInertia);
btRigidBody* body = new btRigidBody(rbInfo);
dynamicsWorld->addRigidBody(body);
btCollisionObject * collisionTerrain = new btCollisionObject();
collisionTerrain->setCollisionShape(terrainShape);
// dynamicsWorld->addCollisionObject(collisionTerrain);
}
terrain->setMaterialTexture(0,
driver->getTexture(".\\grass.bmp"));
terrain->scaleTexture(20);
terrain->setMaterialType(EMT_SOLID);
terrain->setMaterialFlag( EMF_LIGHTING,
false);
ITriangleSelector* selector = smgr->createTerrainTriangleSelector( terrain,
0);
terrain->setTriangleSelector(selector);
ISceneNodeAnimator* anim = smgr->createCollisionResponseAnimator(
selector,
camera,
vector3df( 60,
100,
60),
vector3df( 0,
0,
0),
vector3df( 0,
50,
0));
selector->drop();
camera->addAnimator(anim);
anim->drop();
MyEventReceiver receiver(terrain);
device->setEventReceiver(&receiver);
int lastFPS = -1;
btRigidBody* sphereBody;
btCollisionShape* colShape = new btSphereShape(btScalar(100.));
collisionShapes.push_back(colShape);
btTransform startTransform;
startTransform.setIdentity();
btScalar mass(1.f);
bool isDynamic = (mass != 0.f);
btVector3 localInertia(0,0,0);
if (isDynamic)
colShape->calculateLocalInertia(mass,localInertia);
startTransform.setOrigin(btVector3(2000, 1000, 2000));
btDefaultMotionState* myMotionState = new btDefaultMotionState(startTransform);
btRigidBody::btRigidBodyConstructionInfo rbInfo(mass,myMotionState,colShape,localInertia);
sphereBody = new btRigidBody(rbInfo);
dynamicsWorld->addRigidBody(sphereBody);
btCollisionObject * collisionSphere = new btCollisionObject();
collisionSphere->setCollisionShape(colShape);
dynamicsWorld->addCollisionObject(collisionSphere, 1, 1);
ISceneNode *sphere = smgr->addSphereSceneNode(100, 64, 0, -1, vector3df(0, 0, 0), vector3df(0, 0, 0));
sphere->setMaterialTexture(0,
driver->getTexture(".\\grass.bmp"));
sphere->setMaterialType(EMT_SPHERE_MAP);
sphere->setMaterialFlag( EMF_LIGHTING,
false);
while(device->run())
if (device->isWindowActive())
{
dynamicsWorld->stepSimulation(.166666f, 2);
sphere->setPosition(GetPosition(sphereBody));
sphere->setRotation(GetRotation(sphereBody));
driver->beginScene( true,
true,
0 );
smgr->drawAll();
env->drawAll();
driver->endScene();
int fps = driver->getFPS();
if (lastFPS != fps)
{
stringw str = L"Virtual Sarasa [";
str += driver->getName();
str += "] FPS:";
str += fps;
str += " Height: ";
str += terrain->getHeight(camera->getAbsolutePosition().X, camera->getAbsolutePosition().Z);
device->setWindowCaption(str.c_str());
lastFPS = fps;
}
}
for (s8 i=dynamicsWorld->getNumCollisionObjects()-1; i>=0 ;i--)
{
btCollisionObject* obj = dynamicsWorld->getCollisionObjectArray()[i];
btRigidBody* body = btRigidBody::upcast(obj);
if (body && body->getMotionState())
{
delete body->getMotionState();
}
dynamicsWorld->removeCollisionObject( obj );
delete obj;
}
for (int j=0;j<collisionShapes.size();j++)
{
btCollisionShape* shape = collisionShapes[j];
collisionShapes[j] = 0;
delete shape;
}
delete dynamicsWorld;
delete solver;
delete overlappingPairCache;
delete dispatcher;
delete collisionConfiguration;
collisionShapes.clear();
device->drop();
return 0;
}