object collision help
object collision help
hi
so far ive tried to start with the very basics , but now im a little stuck.
ive created a simple 3D object in blender just the one object iv exported and saved it as a .3ds file.
now ive imported that object into irredit as an octree , nice an easy !! then save the project as a .irr file ok.
ive used the .irrload tutorial to load my new .irr file containing the simple object. this works fine as i can see the object and move around it , but now i have two prolems ?
1> how do i stop the screen from going straight through the object ??
2> is there anyway of making the cameras movements less irratic ie when you press the up key it doesnt move as far
any help would be great
cheers
andy
so far ive tried to start with the very basics , but now im a little stuck.
ive created a simple 3D object in blender just the one object iv exported and saved it as a .3ds file.
now ive imported that object into irredit as an octree , nice an easy !! then save the project as a .irr file ok.
ive used the .irrload tutorial to load my new .irr file containing the simple object. this works fine as i can see the object and move around it , but now i have two prolems ?
1> how do i stop the screen from going straight through the object ??
2> is there anyway of making the cameras movements less irratic ie when you press the up key it doesnt move as far
any help would be great
cheers
andy
just a heads up
managed to fix question 2
virtual ICameraSceneNode* addCameraSceneNodeFPS(ISceneNode* parent = 0,
f32 rotateSpeed = 100.0f, f32 moveSpeed = 5.0f, s32 id=-1,
SKeyMap* keyMapArray=0, s32 keyMapSize=0, bool noVerticalMovement=false,
f32 jumpSpeed = 0.f) = 0;
changed movespeed from = 500.0f to = 5.0f . which makes it alot better
still no solution for question 1 ?
andy
managed to fix question 2
virtual ICameraSceneNode* addCameraSceneNodeFPS(ISceneNode* parent = 0,
f32 rotateSpeed = 100.0f, f32 moveSpeed = 5.0f, s32 id=-1,
SKeyMap* keyMapArray=0, s32 keyMapSize=0, bool noVerticalMovement=false,
f32 jumpSpeed = 0.f) = 0;
changed movespeed from = 500.0f to = 5.0f . which makes it alot better
still no solution for question 1 ?
andy
iv tried looking not alot about
my code looks like this , but still the object can be travelled through
/*
Since version 1.1, Irrlicht is able to save and load
the full scene graph into an .irr file, an xml based
format. There is an editor available to edit
those files, named irrEdit on http://www.ambiera.com/irredit,
which can also be used as world and particle editor.
This tutorial shows how to use .irr files.
Lets start: Create an Irrlicht device and setup the window.
*/
#include <irrlicht.h>
#include <iostream>
using namespace irr;
#pragma comment(lib, "Irrlicht.lib")
int main()
{
// ask user for driver
video::E_DRIVER_TYPE driverType;
printf("Please select the driver you want for this example:\n"\
" (a) Direct3D 9.0c\n (b) Direct3D 8.1\n (c) OpenGL 1.5\n"\
" (d) Software Renderer\n (e) Burning's Software Renderer\n"\
" (f) NullDevice\n (otherKey) exit\n\n");
char i;
std::cin >> i;
switch(i)
{
case 'a': driverType = video::EDT_DIRECT3D9;break;
case 'b': driverType = video::EDT_DIRECT3D8;break;
case 'c': driverType = video::EDT_OPENGL; break;
case 'd': driverType = video::EDT_SOFTWARE; break;
case 'e': driverType = video::EDT_BURNINGSVIDEO;break;
case 'f': driverType = video::EDT_NULL; break;
default: return 1;
}
// create device and exit if creation failed
IrrlichtDevice* device =
createDevice(driverType, core::dimension2d<s32>(640, 480));
if (device == 0)
return 1; // could not create selected driver.
device->setWindowCaption(L"Load .irr file example");
video::IVideoDriver* driver = device->getVideoDriver();
scene::ISceneManager* smgr = device->getSceneManager();
/* Now load our .irr file.
.irr files can store the whole scene graph including animators, materials
and particle systems. And there is also the possibility to store arbitrary
user data for every scene node in that file. To keep this
example simple, we are simply loading the scene here. See the documentation
at ISceneManager::loadScene and ISceneManager::saveScene for more information.
So to load and display a complicated huge scene, we only need a single call
to loadScene().
*/
// load the scene
smgr->loadScene("hunt.irr");
/*
That was it already. Now add a camera and draw the scene
*/
// add a user controlled camera
scene::ITriangleSelector* selector = 0;
scene::ICameraSceneNode* camera =
camera = smgr->addCameraSceneNodeFPS(0,100.0f,300.0f);
camera->setPosition(core::vector3df(-100,50,-150));
scene::ISceneNodeAnimator* anim =
smgr->createCollisionResponseAnimator(
selector, camera, core::vector3df(30,50,30),
core::vector3df(0,-3,0),
core::vector3df(0,50,0));
//selector->drop();
camera->addAnimator(anim);
anim->drop();
scene::ISceneNode* selectedSceneNode = 0;
scene::ISceneNode* lastSelectedSceneNode = 0;
int lastFPS = -1;
while(device->run())
if (device->isWindowActive())
{
driver->beginScene(true, true, 0);
smgr->drawAll();
core::line3d<f32> line;
line.start = camera->getPosition();
line.end = line.start +
(camera->getTarget() - line.start).normalize() * 1000.0f;
core::vector3df intersection;
core::triangle3df tri;
if (smgr->getSceneCollisionManager()->getCollisionPoint(
line, selector, intersection, tri))
{
driver->setTransform(video::ETS_WORLD, core::matrix4());
driver->draw3DTriangle(tri, video::SColor(0,255,0,0));
}
selectedSceneNode = smgr->getSceneCollisionManager()->
getSceneNodeFromCameraBB(camera);
if (lastSelectedSceneNode)
lastSelectedSceneNode->setMaterialFlag(
video::EMF_LIGHTING, true);
// if (selectedSceneNode == q3node ||
// selectedSceneNode == bill)
// selectedSceneNode = 0;
if (selectedSceneNode)
selectedSceneNode->setMaterialFlag(
video::EMF_LIGHTING, false);
lastSelectedSceneNode = selectedSceneNode;
driver->endScene();
int fps = driver->getFPS();
if (lastFPS != fps)
{
core::stringw str = L"Collision detection example - Irrlicht Engine [";
str += driver->getName();
str += "] FPS:";
str += fps;
device->setWindowCaption(str.c_str());
lastFPS = fps;
}
}
device->drop();
return 0;
}
my code looks like this , but still the object can be travelled through
/*
Since version 1.1, Irrlicht is able to save and load
the full scene graph into an .irr file, an xml based
format. There is an editor available to edit
those files, named irrEdit on http://www.ambiera.com/irredit,
which can also be used as world and particle editor.
This tutorial shows how to use .irr files.
Lets start: Create an Irrlicht device and setup the window.
*/
#include <irrlicht.h>
#include <iostream>
using namespace irr;
#pragma comment(lib, "Irrlicht.lib")
int main()
{
// ask user for driver
video::E_DRIVER_TYPE driverType;
printf("Please select the driver you want for this example:\n"\
" (a) Direct3D 9.0c\n (b) Direct3D 8.1\n (c) OpenGL 1.5\n"\
" (d) Software Renderer\n (e) Burning's Software Renderer\n"\
" (f) NullDevice\n (otherKey) exit\n\n");
char i;
std::cin >> i;
switch(i)
{
case 'a': driverType = video::EDT_DIRECT3D9;break;
case 'b': driverType = video::EDT_DIRECT3D8;break;
case 'c': driverType = video::EDT_OPENGL; break;
case 'd': driverType = video::EDT_SOFTWARE; break;
case 'e': driverType = video::EDT_BURNINGSVIDEO;break;
case 'f': driverType = video::EDT_NULL; break;
default: return 1;
}
// create device and exit if creation failed
IrrlichtDevice* device =
createDevice(driverType, core::dimension2d<s32>(640, 480));
if (device == 0)
return 1; // could not create selected driver.
device->setWindowCaption(L"Load .irr file example");
video::IVideoDriver* driver = device->getVideoDriver();
scene::ISceneManager* smgr = device->getSceneManager();
/* Now load our .irr file.
.irr files can store the whole scene graph including animators, materials
and particle systems. And there is also the possibility to store arbitrary
user data for every scene node in that file. To keep this
example simple, we are simply loading the scene here. See the documentation
at ISceneManager::loadScene and ISceneManager::saveScene for more information.
So to load and display a complicated huge scene, we only need a single call
to loadScene().
*/
// load the scene
smgr->loadScene("hunt.irr");
/*
That was it already. Now add a camera and draw the scene
*/
// add a user controlled camera
scene::ITriangleSelector* selector = 0;
scene::ICameraSceneNode* camera =
camera = smgr->addCameraSceneNodeFPS(0,100.0f,300.0f);
camera->setPosition(core::vector3df(-100,50,-150));
scene::ISceneNodeAnimator* anim =
smgr->createCollisionResponseAnimator(
selector, camera, core::vector3df(30,50,30),
core::vector3df(0,-3,0),
core::vector3df(0,50,0));
//selector->drop();
camera->addAnimator(anim);
anim->drop();
scene::ISceneNode* selectedSceneNode = 0;
scene::ISceneNode* lastSelectedSceneNode = 0;
int lastFPS = -1;
while(device->run())
if (device->isWindowActive())
{
driver->beginScene(true, true, 0);
smgr->drawAll();
core::line3d<f32> line;
line.start = camera->getPosition();
line.end = line.start +
(camera->getTarget() - line.start).normalize() * 1000.0f;
core::vector3df intersection;
core::triangle3df tri;
if (smgr->getSceneCollisionManager()->getCollisionPoint(
line, selector, intersection, tri))
{
driver->setTransform(video::ETS_WORLD, core::matrix4());
driver->draw3DTriangle(tri, video::SColor(0,255,0,0));
}
selectedSceneNode = smgr->getSceneCollisionManager()->
getSceneNodeFromCameraBB(camera);
if (lastSelectedSceneNode)
lastSelectedSceneNode->setMaterialFlag(
video::EMF_LIGHTING, true);
// if (selectedSceneNode == q3node ||
// selectedSceneNode == bill)
// selectedSceneNode = 0;
if (selectedSceneNode)
selectedSceneNode->setMaterialFlag(
video::EMF_LIGHTING, false);
lastSelectedSceneNode = selectedSceneNode;
driver->endScene();
int fps = driver->getFPS();
if (lastFPS != fps)
{
core::stringw str = L"Collision detection example - Irrlicht Engine [";
str += driver->getName();
str += "] FPS:";
str += fps;
device->setWindowCaption(str.c_str());
lastFPS = fps;
}
}
device->drop();
return 0;
}
Well obviously... you've not passed a valid triangle selector to the animator, you've created a pointer to one and then set it to NULL and then passed it to the animator... How do you expect that to do collision?
You need to create the triangle selector using a method from the scene manager.
Presumably you just ignored the solution i gave you in my previous post? Or is there something about it you didn't understand?
You need to create the triangle selector using a method from the scene manager.
Presumably you just ignored the solution i gave you in my previous post? Or is there something about it you didn't understand?
ic
you mean i have done this
scene::ITriangleSelector* selector = 0;
do i need to call this function
ISceneNodeAnimatorCollisionResponse* CSceneManager::createCollisionResponseAnimator(
ITriangleSelector* world, ISceneNode* sceneNode, const core::vector3df& ellipsoidRadius,
const core::vector3df& gravityPerSecond,
const core::vector3df& ellipsoidTranslation, f32 slidingValue)
you mean i have done this
scene::ITriangleSelector* selector = 0;
do i need to call this function
ISceneNodeAnimatorCollisionResponse* CSceneManager::createCollisionResponseAnimator(
ITriangleSelector* world, ISceneNode* sceneNode, const core::vector3df& ellipsoidRadius,
const core::vector3df& gravityPerSecond,
const core::vector3df& ellipsoidTranslation, f32 slidingValue)
-
rogerborg
- Admin
- Posts: 3590
- Joined: Mon Oct 09, 2006 9:36 am
- Location: Scotland - gonnae no slag aff mah Engleesh
- Contact:
Again, read the tutorials. From example 07.Collision main.cpp:
You have to actually create a triangle selector from an IMesh *. At the moment you're not creating one.
To create appropriate triangle selectors, then after loading the .irr file, you will have to retrieve appropriate nodes from the scene. There are several ways of doing this. For example:
Code: Select all
scene::ITriangleSelector* selector = 0;
if (q3node)
{
q3node->setPosition(core::vector3df(-1350,-130,-1400));
selector = smgr->createOctTreeTriangleSelector(q3levelmesh->getMesh(0), q3node, 128);
q3node->setTriangleSelector(selector);
}
To create appropriate triangle selectors, then after loading the .irr file, you will have to retrieve appropriate nodes from the scene. There are several ways of doing this. For example:
- Call ISceneManager::getSceneNodesFromType() to retrieve all scene::ESNT_MESH nodes.
- Give collidable nodes a special ID in IrrEdit, then call getSceneNodeFromId() to find them.
- Name your collidable nodes in IrrEdit then call getSceneNodeFromName() to find them.
Please upload candidate patches to the tracker.
Need help now? IRC to #irrlicht on irc.freenode.net
How To Ask Questions The Smart Way
Need help now? IRC to #irrlicht on irc.freenode.net
How To Ask Questions The Smart Way
When you load a model directly like the tutorials load .3ds or .md2 or whatever then you get a pointer to the mesh and the node.
When you load a .irr file you're loading (possibly) multiple .3ds or .md2 or whatever files with one function call and so it won't return the mesh or node pointers to you.
Hence you have to do what i said and recurse through the scene from the root scene node to find all the nodes that have been loaded in order to create triangle selectors for them.
Now please tell us what part of that you don't understand so we can actually help you with it!
When you load a .irr file you're loading (possibly) multiple .3ds or .md2 or whatever files with one function call and so it won't return the mesh or node pointers to you.
Hence you have to do what i said and recurse through the scene from the root scene node to find all the nodes that have been loaded in order to create triangle selectors for them.
Now please tell us what part of that you don't understand so we can actually help you with it!
-
rogerborg
- Admin
- Posts: 3590
- Joined: Mon Oct 09, 2006 9:36 am
- Location: Scotland - gonnae no slag aff mah Engleesh
- Contact:
OK, a code example. This can be finagled into example 15.LoadIrrFile so that you can see what's going on.
Code: Select all
smgr->loadScene("../../media/example.irr");
scene::ICameraSceneNode * camera = smgr->addCameraSceneNodeFPS();
// Now we will find all mesh scene nodes in the scene and create a collision
// response animator from them. Other ways of retrieving nodes would be to
// give them names or distinctive IDs in IrrEdit and then use getSceneNodeFromName()
// or getSceneNodeFromId().
core::array<scene::ISceneNode *> nodes;
smgr->getSceneNodesFromType(scene::ESNT_MESH, nodes);
// Create a meta triangle selector to hold all the triangle selectors
// (there may only be 1, but it's harmless to wrap it in a meta selector)
scene::IMetaTriangleSelector * meta = smgr->createMetaTriangleSelector();
for(u32 i = 0; i < nodes.size(); ++i)
{
// It should be safe to assume that each node is an IMeshSceneNode
// but let's belt and braces check it:
scene::IMeshSceneNode * node = (scene::IMeshSceneNode*)nodes[i];
if(scene::ESNT_MESH == node->getType())
{
// Create an oct tree selector
scene::ITriangleSelector * selector
= smgr->createOctTreeTriangleSelector(node->getMesh(), node, 128);
// Add it to the meta selector, which will take a reference to it
meta->addTriangleSelector(selector);
// And drop my reference to it, so that the meta selector owns it.
selector->drop();
}
}
// Now that all mesh scene nodes have had triangle selectors created and added
// to the meta selector, create a collision response animator from that meta
// selector.
scene::ISceneNodeAnimator* anim = smgr->createCollisionResponseAnimator(
meta, camera, core::vector3df(5,5,5),
core::vector3df(0,0,0));
meta->drop(); // I'm done with the meta selector now
camera->addAnimator(anim);
anim->drop(); // I'm done with the animator selector now
// And set the camera position so that it doesn't start off stuck in the geometry
camera->setPosition(core::vector3df(0.f, 20.f, 0.f));
// And look at the cube
scene::ISceneNode * cube = smgr->getSceneNodeFromType(scene::ESNT_CUBE);
if(cube)
camera->setTarget(cube->getAbsolutePosition()); Please upload candidate patches to the tracker.
Need help now? IRC to #irrlicht on irc.freenode.net
How To Ask Questions The Smart Way
Need help now? IRC to #irrlicht on irc.freenode.net
How To Ask Questions The Smart Way
