Initial import
Initial import

file:b/App.cpp (new)
--- /dev/null
+++ b/App.cpp
@@ -1,1 +1,156 @@
+#include "App.h"
 
+#include "CrateObject.h"
+
+App::App()
+  : _device(0),_cannon(0),_cannonControl(0)
+{
+  _device=createDevice(video::EDT_OPENGL,dimension2d<u32>(640,480),16,
+		       false,false,false,this);
+
+  _device->setWindowCaption(L"Bullet Test");
+
+  _smgr=_device->getSceneManager();
+
+  _bullet=createIrrBulletWorld(_device,true,true);
+  _bullet->setGravity(vector3df(0,-5,0));
+
+  init();
+}
+
+App::~App()
+{
+  _device->drop();
+  //delete _bullet;
+}
+
+bool App::run()
+{
+  u32 TimeStamp = _device->getTimer()->getTime();
+  u32 DeltaTime = 0;
+  while(_device->run())
+    {
+      // Run physics
+      DeltaTime = _device->getTimer()->getTime()-TimeStamp;
+      TimeStamp = _device->getTimer()->getTime();
+      _bullet->stepSimulation(DeltaTime*0.001f,120);
+
+      handleCollisions();
+
+      // Render everything
+      _device->getVideoDriver()->beginScene(true,true,SColor(255,0,0,255));
+      _device->getGUIEnvironment()->drawAll();
+      _device->getSceneManager()->drawAll();
+      _device->getVideoDriver()->endScene();
+    }
+
+  return true;
+}
+
+void App::init()
+{
+  SKeyMap keyMap[4];
+  keyMap[0].Action = EKA_MOVE_FORWARD;
+  keyMap[0].KeyCode = KEY_KEY_W;
+  keyMap[1].Action = EKA_MOVE_BACKWARD;
+  keyMap[1].KeyCode = KEY_KEY_S;
+  keyMap[2].Action = EKA_STRAFE_LEFT;
+  keyMap[2].KeyCode = KEY_KEY_A;
+  keyMap[3].Action = EKA_STRAFE_RIGHT;
+  keyMap[3].KeyCode = KEY_KEY_D;
+
+  _fpsCam=_smgr->addCameraSceneNodeFPS(0,25,0.003,-1,keyMap,4);
+  //ICameraSceneNode *cam=_smgr->addCameraSceneNode();
+  _fpsCam->setPosition(vector3df(2,1.5,12));
+  _fpsCam->setTarget(vector3df(-1.5,-0.1,0.3));
+
+  _smgr->addLightSceneNode(0, vector3df(20, 40, -50), SColorf(1.0f, 1.0f, 1.0f), 4000.0f);
+
+  IMeshSceneNode *cube=_smgr->addCubeSceneNode(1.f);
+  cube->setScale(vector3df(50,0.1,50));
+  cube->setMaterialFlag(video::EMF_LIGHTING, true);
+  cube->setMaterialFlag(video::EMF_NORMALIZE_NORMALS, true);
+  cube->setMaterialTexture(0, _device->getVideoDriver()->getTexture("rockwall.jpg"));
+
+  ICollisionShape *cubeShape=new IBoxShape(cube,0,false);
+  IRigidBody *cubeBody=_bullet->addRigidBody(cubeShape);
+
+  for(s32 i=-10;i<10;i++)
+    for(s32 k=0;k<10;k++)
+      addCube(vector3df(i*0.5,0.35+k*0.5,-6));
+
+
+  s32 pyramidHeight=5;
+  for(s32 k=0;k<pyramidHeight;k++)
+    for(s32 i=-pyramidHeight+k;i<pyramidHeight-k;i++)
+      for(s32 j=-pyramidHeight+k;j<pyramidHeight-k;j++)
+	addCube(vector3df(-pyramidHeight-5+i*0.5,0.35+k*0.5,-6+j*0.5));
+  
+  _cannon=new CannonSceneNode(_smgr->getRootSceneNode(),_smgr,_bullet);
+  _cannon->setPosition(vector3df(0,0.15,10));
+
+  _cannonControl=new CannonSceneNodeAnimator();
+  _cannon->addAnimator(_cannonControl);
+}
+
+bool App::OnEvent(const SEvent &event)
+{
+  switch(event.EventType)
+    {
+    case EET_KEY_INPUT_EVENT:
+      if(event.KeyInput.Key==KEY_ESCAPE && !event.KeyInput.PressedDown)
+	{
+	  _device->closeDevice();
+	  return true;
+	}
+      if(event.KeyInput.Key==KEY_SPACE && !event.KeyInput.PressedDown)
+	{
+	  _fpsCam->setInputReceiverEnabled(!_fpsCam->isInputReceiverEnabled());
+	}
+      if(event.KeyInput.Key==KEY_KEY_C && !event.KeyInput.PressedDown)
+	{
+	  _cannon->fire();
+	}
+      break;
+    default:
+      break;
+    }
+
+  if(_cannonControl && _cannonControl->isEventReceiverEnabled())
+    return _cannonControl->OnEvent(event);
+  else
+    return false;
+}
+
+void App::addCube(vector3df pos)
+{
+  CrateObject *crate=new CrateObject(pos,_smgr,_bullet);
+}
+
+void App::handleCollisions()
+{
+  for(int i=0;i<_bullet->getNumManifolds();i++)
+    {
+      ICollisionCallbackInformation *info=_bullet->getCollisionCallback(i);
+      performCollisionOnCube(info->getBody0(),info);
+      performCollisionOnCube(info->getBody1(),info);
+    }
+}
+
+void App::performCollisionOnCube(ICollisionObject *obj,ICollisionCallbackInformation *collisionInfo)
+{
+  if(obj->getAttributes()->getAttributeAsBool("destroyable"))
+    {
+      for(u32 i=0;i<collisionInfo->getNumContactPoints();i++)
+	{
+	  SManifoldPoint &manifold=collisionInfo->getContactPoint(i);
+	  if(manifold.getAppliedImpulse()>3)
+	    {
+	      DestroyableObject *destroyable=(DestroyableObject*)obj->getAttributes()->getAttributeAsUserPointer("control");
+
+	      destroyable->setLife(destroyable->life()-manifold.getAppliedImpulse());
+	    }
+	}
+    }
+}
+

file:b/App.h (new)
--- /dev/null
+++ b/App.h
@@ -1,1 +1,42 @@
+#ifndef APP_H_
+#define APP_H_
 
+#include <irrlicht.h>
+#include <irrbullet.h>
+
+using namespace irr;
+using namespace irr::core;
+using namespace irr::video;
+using namespace irr::scene;
+
+#include "CannonSceneNode.h"
+#include "CannonSceneNodeAnimator.h"
+
+class App : public IEventReceiver
+{
+public:
+  App();
+  ~App();
+
+  bool run();
+
+  bool OnEvent(const SEvent &event);
+
+private:
+  IrrlichtDevice *_device;
+  ISceneManager *_smgr;
+  ICameraSceneNode *_fpsCam;
+  irrBulletWorld *_bullet;
+  CannonSceneNode *_cannon;
+  CannonSceneNodeAnimator *_cannonControl;
+
+  void init();
+
+  void addCube(vector3df pos);
+
+  void handleCollisions();
+  void performCollisionOnCube(ICollisionObject *obj,ICollisionCallbackInformation *collisionInfo);
+};
+
+#endif // APP_H_
+

--- /dev/null
+++ b/CannonSceneNode.cpp
@@ -1,1 +1,85 @@
+#include "CannonSceneNode.h"
 
+CannonSceneNode::CannonSceneNode(ISceneNode *parent,ISceneManager *smgr,irrBulletWorld *bullet)
+  : ISceneNode(parent,smgr,-1),_smgr(smgr),_bullet(bullet),_power(9)
+{
+  ISceneNode *base=_smgr->addCubeSceneNode(1.f,this);
+  base->setScale(vector3df(1,0.2,1));
+
+  _barrel=_smgr->addCubeSceneNode(1.f,this);
+  _barrel->setScale(vector3df(0.2,0.2,2));
+  setYRotation(0);
+  setXRotation(45);
+}
+
+CannonSceneNode::~CannonSceneNode()
+{ }
+
+void CannonSceneNode::render()
+{ }
+
+const aabbox3d<f32>& CannonSceneNode::getBoundingBox() const
+{
+  return Box;
+}
+
+double CannonSceneNode::power()
+{
+  return _power;
+}
+
+void CannonSceneNode::setPower(double power)
+{
+  _power=power;
+  if(_power<0) _power=0;
+  if(_power>10) _power=10;
+}
+
+double CannonSceneNode::xRotation()
+{
+  return _xRotation;
+}
+
+void CannonSceneNode::setXRotation(double xRotation)
+{
+  if(xRotation<0) xRotation=0;
+  if(xRotation>90) xRotation=90;
+  _xRotation=xRotation;
+
+  fixRotation();
+}
+
+double CannonSceneNode::yRotation()
+{
+  return _yRotation;
+}
+
+void CannonSceneNode::setYRotation(double yRotation)
+{
+  if(yRotation<-90) yRotation=-90;
+  if(yRotation>90) yRotation=90;
+  _yRotation=yRotation;
+
+  fixRotation();
+}
+
+void CannonSceneNode::fixRotation()
+{
+  _barrel->setPosition(vector3df(-sin(_yRotation*M_PI/180)*cos(_xRotation*M_PI/180),sin(_xRotation*M_PI/180),-cos(_yRotation*M_PI/180)*cos(_xRotation*M_PI/180)));
+  _barrel->setRotation(vector3df(_xRotation,_yRotation,0));
+}
+
+void CannonSceneNode::fire()
+{
+  vector3df dir=vector3df(-sin(_yRotation*M_PI/180)*cos(_xRotation*M_PI/180),sin(_xRotation*M_PI/180),-cos(_yRotation*M_PI/180)*cos(_xRotation*M_PI/180));
+
+  IMeshSceneNode *bullet=_smgr->addSphereSceneNode(0.1f);
+  bullet->setPosition(getPosition()+2*dir);
+  bullet->setMaterialFlag(video::EMF_LIGHTING, true);
+  bullet->setMaterialFlag(video::EMF_NORMALIZE_NORMALS, true);
+ 
+  ICollisionShape *bulletShape=new ISphereShape(bullet,20,false);
+  IRigidBody *bulletBody=_bullet->addRigidBody(bulletShape);
+  bulletBody->setLinearVelocity(_power*dir);
+}
+

file:b/CannonSceneNode.h (new)
--- /dev/null
+++ b/CannonSceneNode.h
@@ -1,1 +1,45 @@
+#ifndef CANNONSCENENODE_H_
+#define CANNONSCENENODE_H_
 
+#include <irrlicht.h>
+#include <irrbullet.h>
+
+using namespace irr;
+using namespace irr::core;
+using namespace irr::video;
+using namespace irr::scene;
+
+class CannonSceneNode : public ISceneNode
+{
+public:
+  CannonSceneNode(ISceneNode *parent,ISceneManager *smgr,irrBulletWorld *bullet);
+  ~CannonSceneNode();
+
+  void render();
+  const aabbox3d<f32>& getBoundingBox() const;
+
+  double power();
+  void setPower(double power);
+  double xRotation();
+  void setXRotation(double xRotation);
+  double yRotation();
+  void setYRotation(double yRotation);
+
+  void fire();
+
+private:
+  ISceneManager *_smgr;
+  irrBulletWorld *_bullet;
+
+  ISceneNode *_barrel;
+
+  double _power;
+  double _xRotation,_yRotation;
+
+  aabbox3d<f32> Box;
+
+  void fixRotation();
+};
+
+#endif // CANNONSCENENODE_H_
+

--- /dev/null
+++ b/CannonSceneNodeAnimator.cpp
@@ -1,1 +1,89 @@
+#include "CannonSceneNodeAnimator.h"
 
+#include "CannonSceneNode.h"
+
+CannonSceneNodeAnimator::CannonSceneNodeAnimator()
+  : _lastUpdate(0),_moveUp(false),_moveDown(false),_moveLeft(false),_moveRight(false),_powerDown(false),_powerUp(false)
+{ }
+
+CannonSceneNodeAnimator::~CannonSceneNodeAnimator()
+{ }
+
+void CannonSceneNodeAnimator::animateNode(ISceneNode *node,u32 timeMs)
+{ 
+  if(_lastUpdate==0)
+    _lastUpdate=timeMs;
+
+  u32 timeDelta=timeMs-_lastUpdate;
+  CannonSceneNode *cannon=(CannonSceneNode*)node;
+
+  if(_moveUp)
+    cannon->setXRotation(cannon->xRotation()-timeDelta*0.01);
+
+  if(_moveDown)
+    cannon->setXRotation(cannon->xRotation()+timeDelta*0.01);
+
+  if(_moveLeft)
+    cannon->setYRotation(cannon->yRotation()-timeDelta*0.01);
+
+  if(_moveRight)
+    cannon->setYRotation(cannon->yRotation()+timeDelta*0.01);
+
+  if(_powerDown)
+    cannon->setPower(cannon->power()-0.001*timeDelta);
+  if(_powerUp)
+    cannon->setPower(cannon->power()+0.001*timeDelta);
+
+  _lastUpdate=timeMs;
+}
+
+ISceneNodeAnimator* CannonSceneNodeAnimator::createClone(ISceneNode *node, ISceneManager *smgr)
+{ return 0; }
+
+bool CannonSceneNodeAnimator::OnEvent(const SEvent &event)
+{
+  switch(event.EventType)
+    {
+    case EET_KEY_INPUT_EVENT:
+      if(event.KeyInput.Key==KEY_UP)
+	{
+	  _moveUp=event.KeyInput.PressedDown;
+	  return true;
+	}
+      if(event.KeyInput.Key==KEY_DOWN)
+	{
+	  _moveDown=event.KeyInput.PressedDown;
+	  return true;
+	}
+      if(event.KeyInput.Key==KEY_LEFT)
+	{
+	  _moveLeft=event.KeyInput.PressedDown;
+	  return true;
+	}
+      if(event.KeyInput.Key==KEY_RIGHT)
+	{
+	  _moveRight=event.KeyInput.PressedDown;
+	  return true;
+	}
+      if(event.KeyInput.Key==KEY_NEXT)
+	{
+	  _powerDown=event.KeyInput.PressedDown;
+	  return true;
+	}
+      if(event.KeyInput.Key==KEY_PRIOR)
+	{
+	  _powerUp=event.KeyInput.PressedDown;
+	  return true;
+	}
+      break;
+    default:
+      break;
+    }
+  return false;
+}
+
+bool CannonSceneNodeAnimator::isEventReceiverEnabled() const
+{
+  return true;
+}
+

--- /dev/null
+++ b/CannonSceneNodeAnimator.h
@@ -1,1 +1,28 @@
+#ifndef CANNONSCENENODEANIMATOR_H_
+#define CANNONSCENENODEANIMATOR_H_
 
+#include <irrlicht.h>
+
+using namespace irr;
+using namespace irr::scene;
+
+class CannonSceneNodeAnimator : public ISceneNodeAnimator
+{
+public:
+  CannonSceneNodeAnimator();
+  ~CannonSceneNodeAnimator();
+  void animateNode(ISceneNode *node,u32 timeMs);
+
+  ISceneNodeAnimator* createClone(ISceneNode *node, ISceneManager *smgr=0);
+
+  bool OnEvent(const SEvent &event);
+  bool isEventReceiverEnabled() const;
+
+private:
+  u32 _lastUpdate;
+  bool _moveUp,_moveDown,_moveLeft,_moveRight;
+  bool _powerUp,_powerDown;
+};
+
+#endif // CANNONSCENENODEANIMATOR_H_
+

file:b/CrateObject.cpp (new)
--- /dev/null
+++ b/CrateObject.cpp
@@ -1,1 +1,26 @@
+#include "CrateObject.h"
 
+CrateObject::CrateObject(vector3df pos,ISceneManager *smgr,irrBulletWorld *bullet)
+  : DestroyableObject()
+{
+  IMeshSceneNode *cube=smgr->addCubeSceneNode(0.5f);
+  cube->setPosition(pos);
+  cube->setMaterialFlag(video::EMF_LIGHTING, true);
+  cube->setMaterialFlag(video::EMF_NORMALIZE_NORMALS, true);
+  cube->setMaterialTexture(0,smgr->getVideoDriver()->getTexture("crate.jpg"));
+  setSceneNode(cube);
+
+  ICollisionShape *cubeShape=new IBoxShape(cube,3,false);
+  IRigidBody *cubeBody=bullet->addRigidBody(cubeShape);
+  setRigidBody(cubeBody);
+
+ }
+
+CrateObject::~CrateObject()
+{ }
+
+void CrateObject::setLife(double life)
+{
+  DestroyableObject::setLife(life);
+}
+

file:b/CrateObject.h (new)
--- /dev/null
+++ b/CrateObject.h
@@ -1,1 +1,16 @@
+#ifndef CRATEOBJECT_H_
+#define CRATEOBJECT_H_
 
+#include "DestroyableObject.h"
+
+class CrateObject : public DestroyableObject
+{
+public:
+  CrateObject(vector3df pos,ISceneManager *smgr,irrBulletWorld *bullet);
+  ~CrateObject();
+
+  void setLife(double life);
+};
+
+#endif // CRATEOBJECT_H_
+

--- /dev/null
+++ b/DestroyableObject.cpp
@@ -1,1 +1,48 @@
+#include "DestroyableObject.h"
 
+DestroyableObject::DestroyableObject()
+  : _life(100),_sceneNode(0),_rigidBody(0)
+{ }
+
+DestroyableObject::~DestroyableObject()
+{
+  _rigidBody->remove();
+}
+
+void DestroyableObject::setLife(double life)
+{ 
+  if(life<0)
+    {
+      life=0;
+      _rigidBody->remove();
+    }
+  _life=life;
+}
+double DestroyableObject::life()
+{
+  return _life;
+}
+
+ISceneNode* DestroyableObject::sceneNode()
+{
+  return _sceneNode;
+}
+
+IRigidBody* DestroyableObject::rigidBody()
+{
+  return _rigidBody;
+}
+
+void DestroyableObject::setSceneNode(ISceneNode *sceneNode)
+{
+  _sceneNode=sceneNode;
+}
+
+void DestroyableObject::setRigidBody(IRigidBody *rigidBody)
+{
+  _rigidBody=rigidBody;
+
+  _rigidBody->getAttributes()->setAttribute("destroyable",true);
+  _rigidBody->getAttributes()->setAttribute("control",this);
+}
+

--- /dev/null
+++ b/DestroyableObject.h
@@ -1,1 +1,35 @@
+#ifndef DESTROYABLEOBJECT_H_
+#define DESTROYABLEOBJECT_H_
 
+#include <irrlicht.h>
+#include <irrbullet.h>
+
+using namespace irr;
+using namespace irr::core;
+using namespace irr::video;
+using namespace irr::scene;
+
+class DestroyableObject
+{
+public:
+  DestroyableObject();
+  ~DestroyableObject();
+
+  virtual void setLife(double life);
+  double life();
+
+  ISceneNode *sceneNode();
+  IRigidBody *rigidBody();
+
+protected:
+  void setSceneNode(ISceneNode *sceneNode);
+  void setRigidBody(IRigidBody *rigidBody);
+
+private:
+  double _life;
+  ISceneNode *_sceneNode;
+  IRigidBody *_rigidBody;
+};
+
+#endif // DESTROYABLEOBJECT_H_
+

file:b/Makefile (new)
--- /dev/null
+++ b/Makefile
@@ -1,1 +1,13 @@
+OBJS=main.o App.o CannonSceneNode.o CannonSceneNodeAnimator.o DestroyableObject.o CrateObject.o
+APP=bullet
 
+CFLAGS=-I/home/kkrizka/dev/irrlicht-svn/include/irrlicht -I/home/kkrizka/dev/irrbullet-svn/include/irrBullet -g `pkg-config bullet --cflags`
+CXXFLAGS=${CFLAGS}
+LDFLAGS= -g `pkg-config bullet --libs` -lIrrlicht -L/home/kkrizka/dev/irrlicht-svn/lib -lIrrBullet -L/home/kkrizka/dev/irrbullet-svn/lib -lbz2
+
+all: ${OBJS}
+	g++ ${LDFLAGS} -o ${APP} ${OBJS}
+
+clean:
+	rm ${OBJS}
+	rm ${APP}

file:b/crate.jpg (new)
Binary files /dev/null and b/crate.jpg differ

file:b/main.cpp (new)
--- /dev/null
+++ b/main.cpp
@@ -1,1 +1,9 @@
+#include "App.h"
 
+int main(int argc,char *argv[])
+{
+  App app;
+  
+  return app.run();
+}
+

file:b/rockwall.jpg (new)
Binary files /dev/null and b/rockwall.jpg differ