Raycasting with Irrbullet
Raycasting with Irrbullet
Hi, I'm trying to create a charachter that is able to shoot. Now I want to know if the bullet is going to hit a prop/building or enemy.
So I thought about casting a ray and there are topics talking about it but I can't find any code that casts a ray.
So how do I cast a ray and maybe find wich Object I hit?
Maybe I overlooked something but I searched for about an hour.
So I thought about casting a ray and there are topics talking about it but I can't find any code that casts a ray.
So how do I cast a ray and maybe find wich Object I hit?
Maybe I overlooked something but I searched for about an hour.
-
- Posts: 1186
- Joined: Fri Dec 29, 2006 12:04 am
Re: Raycasting with Irrbullet
I'd use Bullets native methods for this. There's btCollisionWorld::rayTest().
"Whoops..."
Re: Raycasting with Irrbullet
Ok thanks.
But I'm having a little trouble with adding a collision box to an animated model. I just want a cilinder (I got a box now but how do I get a cilinder?) but the program crashes.
Also I tryd that code and it gives me this error:
C:\Users\blurblurblur\Documents\Irrlicht\irrlicht-1.7.2\examples\04.Movement\main.cpp|134|error: missing template arguments before '(' token
With this code:
But I'm having a little trouble with adding a collision box to an animated model. I just want a cilinder (I got a box now but how do I get a cilinder?) but the program crashes.
Code: Select all
scene::IAnimatedMeshSceneNode* player = smgr->addAnimatedMeshSceneNode(smgr->getMesh("media/soldier.x"));
if (player) {
player->setMaterialFlag(video::EMF_LIGHTING, false);
player->setMaterialTexture( 0, driver->getTexture("media/Soldier.png") );
player->setPosition(core::vector3df(10,0,0));
player->setScale(core::vector3df(0.027,0.027,0.027));
ICollisionShape *playershape = new IBoxShape(player, 1, false);
IRigidBody *playerbody;
playerbody = world->addRigidBody(playershape);
}
C:\Users\blurblurblur\Documents\Irrlicht\irrlicht-1.7.2\examples\04.Movement\main.cpp|134|error: missing template arguments before '(' token
With this code:
Code: Select all
btCollisionWorld::rayTest (core::vector3d(playerPosition), core::vector3df(playerPosition),0);
-
- Posts: 1186
- Joined: Fri Dec 29, 2006 12:04 am
Re: Raycasting with Irrbullet
core::vector3d is not a Bullet class.
and
is totally wrong. How can Bullet know what an IAnimatedMeshSceneNode is?
and
Code: Select all
scene::IAnimatedMeshSceneNode* player = smgr->addAnimatedMeshSceneNode(smgr->getMesh("media/soldier.x"));
ICollisionShape *playershape = new IBoxShape(player, 1, false);
"Whoops..."
Re: Raycasting with Irrbullet
So I knew it was wrong so how do I fix it?randomMesh wrote:core::vector3d is not a Bullet class.
andis totally wrong. How can Bullet know what an IAnimatedMeshSceneNode is?Code: Select all
scene::IAnimatedMeshSceneNode* player = smgr->addAnimatedMeshSceneNode(smgr->getMesh("media/soldier.x")); ICollisionShape *playershape = new IBoxShape(player, 1, false);
EDIT:
I got it to this:
Code: Select all
btCollisionWorld::ClosestRayResultCallback result(btVector3(playerPosition.X,playerPosition.Y,playerPosition.Z), btVector3(0,0,0));
btCollisionWorld::rayTest (btVector3(playerPosition.X,playerPosition.Y,playerPosition.Z), btVector3(0,0,0),result);
C:\Users\blurblarblie\Documents\Irrlicht\irrlicht-1.7.2\examples\04.Movement\main.cpp|132|error: cannot call member function 'virtual void btCollisionWorld::rayTest(const btVector3&, const btVector3&, btCollisionWorld::RayResultCallback&) const' without object
So I figured it would have to be something like this but I dont understand the parameters:
Code: Select all
btCollisionWorld::addCollisionObject (btCollisionObject * collisionObject, short int collisionFilterGroup = btBroadphaseProxy::DefaultFilter, short int collisionFilterMask = btBroadphaseProxy::AllFilter)
Last edited by eejin on Fri Jun 29, 2012 9:17 pm, edited 1 time in total.
-
- Posts: 1186
- Joined: Fri Dec 29, 2006 12:04 am
Re: Raycasting with Irrbullet
Fix it by using the mighty search function. I wrote a simple Hello World programm using plain Bullet, which you can find easily. (Sorry, no raycasting, but there are examples in the Bullet Forum, the Wiki and the source folder of Bullet.
"Whoops..."
Re: Raycasting with Irrbullet
I wouldn't have posted before searching and I'm trying to get it to work.
I got this now but it still crashes when it started
Nevermind the player I managed to fix this but I can't get the ray to work.
I got this now but it still crashes when it started
Code: Select all
scene::IAnimatedMeshSceneNode* player = smgr->addAnimatedMeshSceneNode(smgr->getMesh("media/soldier.x"));
if (player) {
player->setMaterialFlag(video::EMF_LIGHTING, false);
player->setMaterialTexture( 0, driver->getTexture("media/Soldier.png") );
player->setPosition(core::vector3df(10,0,0));
player->setScale(core::vector3df(0.027,0.027,0.027));
ICollisionShape *playershape = new IGImpactMeshShape(player,smgr->getMesh("media/soldier.x"),1);
IRigidBody *playerbody;
playerbody = world->addRigidBody(playershape);
}
-
- Posts: 1186
- Joined: Fri Dec 29, 2006 12:04 am
Re: Raycasting with Irrbullet
Since you didn't post a full compilable program i can't tell. Maybe wrong paths. Have a look at the console output.
For the records: Here's the Hello World program i was talking about.
For the records: Here's the Hello World program i was talking about.
"Whoops..."
Re: Raycasting with Irrbullet
I used raycasting in bullet a while ago when I made a function to select a unit on screen by clicking on it. Maybe you can get some ideas from it.
The Obj3d class is just all the things needed to describe a unit, for both irrlicht and bullet in a big mess: scenenode, collisionshape, rigidbody and so on. It's very ugly, so I won't post that. But I will mention that Obj3d.isMyCollision is just a test for (collisionObject->getCollisionShape() == mybtCollisionShape).
Note that you can use collisionMask and collisionGroup if you want to exclude some objects from the raycast. Also, looping through all units and seeing if they are hit worked for me, since I only ran it on user input, but it's not really the best solution.
The Obj3d class is just all the things needed to describe a unit, for both irrlicht and bullet in a big mess: scenenode, collisionshape, rigidbody and so on. It's very ugly, so I won't post that. But I will mention that Obj3d.isMyCollision is just a test for (collisionObject->getCollisionShape() == mybtCollisionShape).
Note that you can use collisionMask and collisionGroup if you want to exclude some objects from the raycast. Also, looping through all units and seeing if they are hit worked for me, since I only ran it on user input, but it's not really the best solution.
Code: Select all
Obj3d* clickSelect(irr::scene::ISceneManager* smgr,
irr::scene::ICameraSceneNode* camera,
MyEventReceiver* receiver,
btDiscreteDynamicsWorld* dynWorld,
std::vector<Obj3d*> units)
{
Obj3d* result = 0;
// Use irrlicht to get a ray from mouse cursor position.
irr::core::line3df ray =
smgr->getSceneCollisionManager()->getRayFromScreenCoordinates(
receiver->GetMouseState().Position, camera);
// Convert ray to bullet vectors.
btVector3 start(ray.start.X, ray.start.Y, ray.start.Z);
btVector3 end(ray.end.X, ray.end.Y, ray.end.Z);
// Do a raycast
btCollisionWorld::ClosestRayResultCallback RayCallback(start, end);
RayCallback.m_collisionFilterGroup = 1;
RayCallback.m_collisionFilterMask = 1;
dynWorld->getCollisionWorld()->rayTest(start, end, RayCallback);
if (RayCallback.hasHit())
{
for (std::vector<Obj3d*>::iterator i=units.begin();i!=units.end();++i)
{
if ( (*i)->isMyCollision(RayCallback.m_collisionObject) )
result = *i;
}
}
return result;
}
Re: Raycasting with Irrbullet
You could just store pointers to your Obj3d objects in the bullet objects' userdata
Re: Raycasting with Irrbullet
What is a btDiscreteDynamicsWorld?
I got an irrBulletWorld *world;.
I got an irrBulletWorld *world;.
-
- Posts: 1186
- Joined: Fri Dec 29, 2006 12:04 am
Re: Raycasting with Irrbullet
It belongs to Bullet.
I don't know if irrBullet supports ray casting. Never used it.randomMesh wrote: I'd use Bullets native methods for this. There's btCollisionWorld::rayTest().
"Whoops..."
Re: Raycasting with Irrbullet
I can figure out it belongs to bullet -_-. I wonder why I can't use Irrbulletworld for it.randomMesh wrote:It belongs to Bullet.I don't know if irrBullet supports ray casting. Never used it.randomMesh wrote: I'd use Bullets native methods for this. There's btCollisionWorld::rayTest().
Re: Raycasting with Irrbullet
I'm still having trouble with the character. I want it to have a cilinder like shape facing upright.
Irrbullet doesn't seem to have a cilinder shape built in so I tried the boxshape first but It doesn't seem to move after it stood still for a couple of seconds. I also want a cilinder shape. How would I achieve that?
Here is a small example:
It's about the player node that doesnt move after receiving a force impulse when it stood still for a few seconds.
Irrbullet doesn't seem to have a cilinder shape built in so I tried the boxshape first but It doesn't seem to move after it stood still for a couple of seconds. I also want a cilinder shape. How would I achieve that?
Here is a small example:
Code: Select all
#include <irrlicht.h>
#include <irrBullet.h>
using namespace irr;
irrBulletWorld *world;
class MyEventReceiver : public IEventReceiver
{
public:
virtual bool OnEvent(const SEvent& event)
{
if (event.EventType == irr::EET_KEY_INPUT_EVENT)
KeyIsDown[event.KeyInput.Key] = event.KeyInput.PressedDown;
return false;
}
virtual bool IsKeyDown(EKEY_CODE keyCode) const
{
return KeyIsDown[keyCode];
}
MyEventReceiver()
{
for (u32 i=0; i<KEY_KEY_CODES_COUNT; ++i)
KeyIsDown[i] = false;
}
private:
bool KeyIsDown[KEY_KEY_CODES_COUNT];
};
int main()
{
MyEventReceiver receiver;
IrrlichtDevice* device = createDevice(video::EDT_OPENGL,
core::dimension2d<u32>(1280, 720), 16, false, false, false, &receiver);
video::IVideoDriver* driver = device->getVideoDriver();
scene::ISceneManager* smgr = device->getSceneManager();
world = createIrrBulletWorld(device, true, true);
world->setDebugMode(EPDM_DrawAabb |EPDM_DrawContactPoints);
world->setGravity(core::vector3df(0,-10,0));
scene::IAnimatedMeshSceneNode* player = smgr->addAnimatedMeshSceneNode(smgr->getMesh("../../media/sydney.md2"));
if (player)
player->setMaterialFlag(video::EMF_LIGHTING, false);
player->setMaterialTexture( 0, driver->getTexture("../../media/sydney.bmp"));
player->setScale(core::vector3df(0.027,0.027,0.027));
ICollisionShape *playershape = new IBoxShape(player, 10, false);
IRigidBody *playerbody;
playerbody = world->addRigidBody(playershape);
scene::ISceneNode *Floor = device->getSceneManager()->addCubeSceneNode(1.0);
if (Floor)
{
Floor->setScale(core::vector3df(25,1,20)); // 400, 3, 400
Floor->setPosition(core::vector3df(0,-1,0));
Floor->setMaterialFlag(video::EMF_LIGHTING, false);
Floor->setMaterialTexture(0, driver->getTexture("../../media/wall.bmp"));
ICollisionShape *Floorshape = new IBoxShape(Floor, 0, false);
IRigidBody *Floorbody;
Floorbody = world->addRigidBody(Floorshape);
}
scene::ISceneNode *Node = device->getSceneManager()->addCubeSceneNode(1.0);
if (Node)
{
Node->setScale(core::vector3df(2,2,2)); // 400, 3, 400
Node->setPosition(core::vector3df(2,0,1));
Node->setMaterialFlag(video::EMF_LIGHTING, false);
Node->setMaterialTexture(0, driver->getTexture("../../media/wall.bmp"));
ICollisionShape *shape = new IBoxShape(Node, 10, false);
IRigidBody *body;
body = world->addRigidBody(shape);
}
smgr->addCameraSceneNode(0, core::vector3df(0,8,-2), core::vector3df(0,0,0));
int lastFPS = -1;
u32 then = device->getTimer()->getTime();
const f32 MOVEMENT_SPEED = 1.f;
while(device->run())
{
const u32 now = device->getTimer()->getTime();
const f32 frameDeltaTime = (f32)(now - then) / 1000.f; // Time in seconds
then = now;
world->stepSimulation(frameDeltaTime, 120);
if(receiver.IsKeyDown(irr::KEY_KEY_W))
playerbody->applyCentralForce(core::vector3df(0,0,5), ERBTS_WORLD);
else if(receiver.IsKeyDown(irr::KEY_KEY_S))
playerbody->applyCentralForce(core::vector3df(0,0,-5), ERBTS_WORLD);
if(receiver.IsKeyDown(irr::KEY_KEY_A))
playerbody->applyCentralForce(core::vector3df(-5,0,0), ERBTS_WORLD);
else if(receiver.IsKeyDown(irr::KEY_KEY_D))
playerbody->applyCentralForce(core::vector3df(+5,0,0), ERBTS_WORLD);
driver->beginScene(true, true, video::SColor(255,113,113,133));
smgr->drawAll(); // draw the 3d scene
device->getGUIEnvironment()->drawAll();
driver->endScene();
int fps = driver->getFPS();
if (lastFPS != fps)
{
core::stringw tmp(L"[");
tmp += driver->getName();
tmp += L"] fps: ";
tmp += fps;
device->setWindowCaption(tmp.c_str());
lastFPS = fps;
}
}
device->drop();
return 0;
}
Re: Raycasting with Irrbullet
hi,
bullet obj deactivate after a few seconds so you must active them explicit or disable the deactivation
eg
bullet obj deactivate after a few seconds so you must active them explicit or disable the deactivation
eg
Code: Select all
body->setActivationState(EAS_DISABLE_DEACTIVATION)